为什么使用Math.pow的代码打印“HELLO WORLD”?

时间:2018-05-21 15:00:05

标签: java string pow

我发现了以下代码。我知道,它使用看似随机的数字看起来不像this one那么奇怪/令人兴奋,但它似乎比使用大数字位移的this one更复杂:

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));
}

Code on Ideone

输出:

  

你好世界

它是如何工作的?它是某种形式的加密还是有人疯狂构建它?

2 个答案:

答案 0 :(得分:5)

让我们进入一些数学:

解决以下方程式,得到答案。这些方程有一个唯一的解决方案,因为方程的数量等于未知变量的数量。

c[0] = 72,即'H'的ASCII值。

为清楚起见:我已将^用于提升惯例。现在解决:

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得到整数

您可以使用this code for solving simultaneous equations of any order来解决这些方程式。

答案 1 :(得分:2)

受到answer from user9823668的启发,我发现了另一种如何扭转计算的方法。代码的内部循环(包括输出行的除法)基本上代表以下多项式:

Polynomial of the inner loop

对于代码外部循环中的值0到10计算此多项式,并生成结果ASCII字符。所以问题是:如何适应polynomial through given consecutive data points

其中一个my search results指向术语Newton polynomial。这是给定数据点集的所谓插值多项式。由于多项式是针对0到10的值计算的,所以我们在这里得到{em> xi = i 的special case。因此,为了构造上述多项式,我们必须计算一些二项式系数。

首先,我们必须计算数据点上的divided differences(即ASCII编码的函数输出):

$ cat tst.awk
BEGIN { OFS="," }
$2 != 0 {
    printf "%s%s", (NR>1 ? $1 : "Name"), OFS
    for (i=2; i<=NF; i+=2) {
        gsub(/^.*\/|\..*$/,"",$i)
        printf "%s%s", $i, (i<NF ? OFS : ORS)
    }
}

$ paste Sample1.txt Sample2.txt | awk -f tst.awk > output.csv

然后,每列中最顶层的条目是我们构造插值多项式所需的系数:

 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

此处,分母代表n!(请参阅special case)。 通过扩展此公式(例如,通过使用WolframAlpha),您将获得上面显示的多项式。如果有人想知道,多项式看起来如下:

Plot of the polynomial