Why does this code using Math.pow print “HELLO WORLD”?
我发现了以下代码。我知道,它看起来不像这个使用看似随机数的数字那么奇怪/令人兴奋,但它似乎比这个使用大量位移位的数字更复杂:
1 2 3 4 5 6 7 8 9 10 |
Ideone代码
输出:
HELLO WORLD
它是如何工作的?它是某种形式的加密还是有人疯狂地构造它?
让我们来研究一下数学:
解出下面的方程,你就能得到答案。这些方程有一个唯一的解,因为方程的数目等于未知变量的数目。
让
为了清楚起见:我用
1 2 3 4 5 6 7 8 9 10 | 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 |
注意,未知数是
现在我们把所有的数字乘以1814400,除以相同的答案,所以它不会改变任何东西,或者通过解方程得到的答案可能不是整数,所以乘以1814400得到整数。
你可以用这个代码解任意阶的联立方程来解这些方程。
在用户9823668的回答的启发下,我找到了另一种方法来逆转计算。代码的内环(包括输出行的除法)基本上表示以下多项式:
此多项式是为代码外循环中的值0到10计算的,并生成结果的ASCII字符。所以问题是:如何通过给定的连续数据点拟合多项式?
我的一个搜索结果指向术语牛顿多项式。这是一组给定数据点的所谓插值多项式。由于多项式是为0到10的值计算的,这里我们有特殊的情形Xi=I。因此,为了构造上述多项式,我们必须计算一些二项式系数。
首先,我们必须计算数据点(即ASCII编码函数输出)上的分差:
1 2 3 4 5 6 7 8 9 10 11 | 0: H = 72 1: E = 69 -3 2: L = 76 7 10 3: L = 76 0 -7 -17 4: O = 79 3 3 10 27 5: = 32 -47 -50 -53 -63 -90 6: W = 87 55 102 152 205 268 358 7: O = 79 -8 -63 -165 -317 -522 -790 -1148 8: R = 82 3 11 74 239 556 1078 1868 3016 9: L = 76 -6 -9 -20 -94 -333 -889 -1967 -3835 -6851 10: D = 68 -8 -2 7 27 121 454 1343 3310 7145 13996 |
然后,每列中最上面的项是我们需要构造插值多项式的系数:
1 2 3 4 5 6 7 8 9 10 11 | 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),可以得到上面所示的多项式。如果有人想知道,多项式如下: