1 から 2000 までの数字が何通りの立方数の和で表せるか (その 2)

AWK Users JP :: 1 から 2000 までの数字が何通りの立方数の和で表せるかはうまくいったように見えて別の整数化でハマっていたため、AWK Users JP :: 整数化の問題 (オレオレ int を作る)で作成したオレオレ int 関数を使った版を書いておきます。 1729がつまらない数字だって?そんなことはないよ - みずぴー日記に近く、解析解を求めるような方法を使っています。 ですから、for 文は 2 重になっています。

#! /usr/local/bin/nawk -f
# 1729_4.awk

BEGIN {
    num = ARGV[1] ? ARGV[1] : 2000;

    for (i = 1; i <= num; i++) {
        for (j = 0; j <= cube_root(i); j++) {
            if (j ^ 3 + ore_int(cube_root(i - j ^ 3)) ^ 3 == i &&
                j <= ore_int(cube_root(i - j ^ 3))) {
                print i " = " j " ^ 3 + " ore_int(cube_root(i - j ^ 3)) " ^ 3";
            }
        }
    }
}

# 1/3 乗 (立方根) を返す
#   in:     数値 num
#   out:    数値 num の 1/3 乗 (立方根)
function cube_root(num) {
    return num ^ (1 / 3);
}

# 2 進数表記できない場合にある程度丸めた整数化を行います (オレオレ int)
#   in:     数値 num
#   out:    num の整数化されたもの
function ore_int(num,       str, period) {
    str = sprintf("%100.99f\n", num) "";
    ##print str;
    if (abs(sprintf("%100.99f", str - int(num) - get_e())) < 0.000000000001) {
        return int(num) + 1;
    } else {
        return int(num);
    }
}

# 絶対値を返す
#   in:     数値 num
#   out:    数値 num の絶対値
function abs(num) {
    if (num >= 0) {
        return num;
    } else {
        return -num;
    }
}

function get_e() {
    return 0.999999999999999;
}

実行してみると以下のようになります。

$ time nawk -f 1729_4.awk
1 = 0 ^ 3 + 1 ^ 3
2 = 1 ^ 3 + 1 ^ 3
8 = 0 ^ 3 + 2 ^ 3
9 = 1 ^ 3 + 2 ^ 3
16 = 2 ^ 3 + 2 ^ 3
27 = 0 ^ 3 + 3 ^ 3
28 = 1 ^ 3 + 3 ^ 3
35 = 2 ^ 3 + 3 ^ 3
54 = 3 ^ 3 + 3 ^ 3
64 = 0 ^ 3 + 4 ^ 3
65 = 1 ^ 3 + 4 ^ 3
72 = 2 ^ 3 + 4 ^ 3
91 = 3 ^ 3 + 4 ^ 3
125 = 0 ^ 3 + 5 ^ 3
126 = 1 ^ 3 + 5 ^ 3
128 = 4 ^ 3 + 4 ^ 3
133 = 2 ^ 3 + 5 ^ 3
152 = 3 ^ 3 + 5 ^ 3
189 = 4 ^ 3 + 5 ^ 3
216 = 0 ^ 3 + 6 ^ 3
217 = 1 ^ 3 + 6 ^ 3
224 = 2 ^ 3 + 6 ^ 3
243 = 3 ^ 3 + 6 ^ 3
250 = 5 ^ 3 + 5 ^ 3
280 = 4 ^ 3 + 6 ^ 3
341 = 5 ^ 3 + 6 ^ 3
343 = 0 ^ 3 + 7 ^ 3
344 = 1 ^ 3 + 7 ^ 3
351 = 2 ^ 3 + 7 ^ 3
370 = 3 ^ 3 + 7 ^ 3
407 = 4 ^ 3 + 7 ^ 3
432 = 6 ^ 3 + 6 ^ 3
468 = 5 ^ 3 + 7 ^ 3
512 = 0 ^ 3 + 8 ^ 3
513 = 1 ^ 3 + 8 ^ 3
520 = 2 ^ 3 + 8 ^ 3
539 = 3 ^ 3 + 8 ^ 3
559 = 6 ^ 3 + 7 ^ 3
576 = 4 ^ 3 + 8 ^ 3
637 = 5 ^ 3 + 8 ^ 3
686 = 7 ^ 3 + 7 ^ 3
728 = 6 ^ 3 + 8 ^ 3
729 = 0 ^ 3 + 9 ^ 3
730 = 1 ^ 3 + 9 ^ 3
737 = 2 ^ 3 + 9 ^ 3
756 = 3 ^ 3 + 9 ^ 3
793 = 4 ^ 3 + 9 ^ 3
854 = 5 ^ 3 + 9 ^ 3
855 = 7 ^ 3 + 8 ^ 3
945 = 6 ^ 3 + 9 ^ 3
1000 = 0 ^ 3 + 10 ^ 3
1001 = 1 ^ 3 + 10 ^ 3
1008 = 2 ^ 3 + 10 ^ 3
1024 = 8 ^ 3 + 8 ^ 3
1027 = 3 ^ 3 + 10 ^ 3
1064 = 4 ^ 3 + 10 ^ 3
1072 = 7 ^ 3 + 9 ^ 3
1125 = 5 ^ 3 + 10 ^ 3
1216 = 6 ^ 3 + 10 ^ 3
1241 = 8 ^ 3 + 9 ^ 3
1331 = 0 ^ 3 + 11 ^ 3
1332 = 1 ^ 3 + 11 ^ 3
1339 = 2 ^ 3 + 11 ^ 3
1343 = 7 ^ 3 + 10 ^ 3
1358 = 3 ^ 3 + 11 ^ 3
1395 = 4 ^ 3 + 11 ^ 3
1456 = 5 ^ 3 + 11 ^ 3
1458 = 9 ^ 3 + 9 ^ 3
1512 = 8 ^ 3 + 10 ^ 3
1547 = 6 ^ 3 + 11 ^ 3
1674 = 7 ^ 3 + 11 ^ 3
1728 = 0 ^ 3 + 12 ^ 3
1729 = 1 ^ 3 + 12 ^ 3
1729 = 9 ^ 3 + 10 ^ 3
1736 = 2 ^ 3 + 12 ^ 3
1755 = 3 ^ 3 + 12 ^ 3
1792 = 4 ^ 3 + 12 ^ 3
1843 = 8 ^ 3 + 11 ^ 3
1853 = 5 ^ 3 + 12 ^ 3
1944 = 6 ^ 3 + 12 ^ 3
2000 = 10 ^ 3 + 10 ^ 3
nawk -f 1729_4.awk  0.31s user 0.01s system 95% cpu 0.330 total

AWK Users JP :: 1 から 2000 までの数字が何通りの立方数の和で表せるか (1729_2.awk) と答え合わせを行います。 zsh を使っている場合には以下のようにして差を見ることができます。

$ diff -u <(nawk -f 1729_2.awk) <(nawk -f 1729_4.awk)

差がないため何も表示されません。

整数化の罠はどこに潜んでいるか分かりにくいので注意したいです。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png