Почему этот код с помощью Math.pow печатает "HELLO WORLD"? - PullRequest
0 голосов
/ 21 мая 2018

Я обнаружил следующий код.Я знаю, это выглядит менее странно / захватывающе, чем этот , использующий, казалось бы, случайные числа, но он кажется более сложным, чем этот , использующий битовые сдвиги для большого числа:

long[] c = {130636800L, -5080148640L, 13802573088L, -14974335980L, 8683908340L,
           -3006955245L, 651448014L, -89047770L, 7457160L, -349165L, 6998L};

for (int x = 0; x < 11; x++) {
    long s = 0;
    for (int i = 0; i < 11; i++)
        s += c[i] * Math.pow(x, i);

    System.out.print((char)(s / 1814400));
}

Код на Ideone

Вывод:

HELLO WORLD

Как это работает?Это какая-то форма шифрования или кто-то разозлился, создавая ее?

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Вдохновленный ответом от пользователя9823668 , я нашел другой способ обратного вычисления.Внутренний цикл кода (включая деление от выходной строки) в основном представляет следующий полином:

Polynomial of the inner loop

Этот полином рассчитывается для значений 0до 10 во внешнем цикле кода и возвращает результирующие символы ASCII.Поэтому возникает вопрос: как вписать полином в заданные последовательные точки данных ?

Один из результатов моего поиска указывает на термин полином Ньютона .Это так называемый интерполяционный полином для заданного набора точек данных.Поскольку многочлен рассчитывается для значений от 0 до 10, у нас есть особый случай из xi = i здесь.Таким образом, чтобы построить вышеупомянутый многочлен, мы должны вычислить некоторые биномиальные коэффициенты.

Сначала мы должны вычислить разделенные различия для точек данных (то есть ASCII-кодированная функцияoutput):

 0: H = <b>72</b>
 1: E = 69  <b>-3</b>
 2: L = 76   7  <b>10</b>
 3: L = 76   0  -7  <b>-17</b>
 4: O = 79   3   3   10   <b>27</b>
 5:   = 32 -47 -50  -53  -63  <b>-90</b>
 6: W = 87  55 102  152  205  268   <b>358</b>
 7: O = 79  -8 -63 -165 -317 -522  -790 <b>-1148</b>
 8: R = 82   3  11   74  239  556  1078  1868  <b>3016</b>
 9: L = 76  -6  -9  -20  -94 -333  -889 -1967 -3835 <b>-6851</b>
10: D = 68  -8  -2   7    27  121   454  1343  3310  7145 <b>13996</b>

Тогда самыми верхними записями в каждом столбце являются коэффициенты, которые нам нужны для построения интерполяционного полинома:

72
-     3 /       1 x
+    10 /       2 x(x-1)
-    17 /       6 x(x-1)(x-2)
+    27 /      24 x(x-1)(x-2)(x-3)
-    90 /     120 x(x-1)(x-2)(x-3)(x-4)
+   358 /     720 x(x-1)(x-2)(x-3)(x-4)(x-5)
-  1148 /    5040 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)
+  3016 /   40320 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)
-  6851 /  362880 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)
+ 13996 / 3628800 x(x-1)(x-2)(x-3)(x-4)(x-5)(x-6)(x-7)(x-8)(x-9)

Здесь знаменатели представляют n! (см. специальный случай ).Расширяя эту формулу (например, используя WolframAlpha ), вы получаете полином, показанный выше.Если кто-то задается вопросом, полином выглядит следующим образом:

Plot of the polynomial

0 голосов
/ 21 мая 2018

Давайте углубимся в математику:

Решите приведенные ниже уравнения, и вы получите ответы.Эти уравнения имеют одно уникальное решение, так как число уравнений равно числу неизвестных переменных.

Позвольте c[0] = 72, что является значением ASCII 'H'.

Для ясности: I 'мы использовали ^ для повышения до соглашения.Теперь решите:

1^0 * c[0] + 1^1 * c[1] + 1^2 * c[2] + 1^3 * c[3] + 1^4 * c[4] + 1^5 * c[5] + 1^6 * c[6] + 1^7 * c[7] + 1^8 * c[8] + 1^9 * c[9] + 1^10 * c[10] = 69
2^0 * c[0] + 2^1 * c[1] + 2^2 * c[2] + 2^3 * c[3] + 2^4 * c[4] + 2^5 * c[5] + 2^6 * c[6] + 2^7 * c[7] + 2^8 * c[8] + 2^9 * c[9] + 2^10 * c[10] = 76
3^0 * c[0] + 3^1 * c[1] + 3^2 * c[2] + 3^3 * c[3] + 3^4 * c[4] + 3^5 * c[5] + 3^6 * c[6] + 3^7 * c[7] + 3^8 * c[8] + 3^9 * c[9] + 3^10 * c[10] = 76
4^0 * c[0] + 4^1 * c[1] + 4^2 * c[2] + 4^3 * c[3] + 4^4 * c[4] + 4^5 * c[5] + 4^6 * c[6] + 4^7 * c[7] + 4^8 * c[8] + 4^9 * c[9] + 4^10 * c[10] = 79
5^0 * c[0] + 5^1 * c[1] + 5^2 * c[2] + 5^3 * c[3] + 5^4 * c[4] + 5^5 * c[5] + 5^6 * c[6] + 5^7 * c[7] + 5^8 * c[8] + 5^9 * c[9] + 5^10 * c[10] = 32
6^0 * c[0] + 6^1 * c[1] + 6^2 * c[2] + 6^3 * c[3] + 6^4 * c[4] + 6^5 * c[5] + 6^6 * c[6] + 6^7 * c[7] + 6^8 * c[8] + 6^9 * c[9] + 6^10 * c[10] = 87  
7^0 * c[0] + 7^1 * c[1] + 7^2 * c[2] + 7^3 * c[3] + 7^4 * c[4] + 7^5 * c[5] + 7^6 * c[6] + 7^7 * c[7] + 7^8 * c[8] + 7^9 * c[9] + 7^10 * c[10] = 79  
8^0 * c[0] + 8^1 * c[1] + 8^2 * c[2] + 8^3 * c[3] + 8^4 * c[4] + 8^5 * c[5] + 8^6 * c[6] + 8^7 * c[7] + 8^8 * c[8] + 8^9 * c[9] + 8^10 * c[10] = 82  
9^0 * c[0] + 9^1 * c[1] + 9^2 * c[2] + 9^3 * c[3] + 9^4 * c[4] + 9^5 * c[5] + 9^6 * c[6] + 9^7 * c[7] + 9^8 * c[8] + 9^9 * c[9] + 9^10 * c[10] = 76
10^0 * c[0] + 10^1 * c[1] + 10^2 * c[2] + 10^3 * c[3] + 10^4 * c[4] + 10^5 * c[5] + 10^6 * c[6] + 10^7 * c[7] + 10^8 * c[8] + 10^9 * c[9] + 10^10 * c[10] = 68

Обратите внимание, что число неизвестных составляет от c[1] до c[10], поэтому 10. Мы знаем, что c[0] = 72, так что это не неизвестно, и число уравнений равно 10.

Теперь мы просто умножим все числа на 1814400, разделим их в ответе на одно и то же, чтобы это ничего не изменило, или, вероятно, ответ, найденный при решении уравнений, не будет целыми числами, поэтому умножим на 1814400чтобы получить целые числа.

Вы можете решить эти уравнения, используя этот код для решения одновременных уравнений любого порядка .

...