算額あれこれ

算額問題をコンピュータで解きます

大きな数の先頭と末尾(3)

大きな数の先頭と末尾(2)」を awk で書いてみると,「大きな数の先頭と末尾(2)」が R の特殊な機能を使っているのではないことが理解できるだろう。

# file name : func.awk
BEGIN {
    print fun(3863080011, 2613515386) # 254361
    print fun(21321331, 1234653876) # 81
    print fun(521340345, 1396720193) # 84765625
    print fun(1843165372, 2835135645) # 79967232
    print fun(417934669, 3961963772) # 11298161
    print fun(7564929, 1434531250) # 1
    print fun(3713420107, 616334320) # 57768001
    print fun(57564748, 243756997) # 3328
    print fun(2249407224, 3483719867) # 32397824
    print fun(444893257, 3572472608) # 25452801
}

function mul(m, n,   km, kn, am, an, i, j, carry, num, ans) { # 8 桁以下の,m, n の掛け算を行い,下 8 桁を返す
    km = m
    kn = n
    for (i = 1; i <= 8; i++) {
        am[i] = km % 10
        km = int(km / 10)
        an[i] = kn % 10
        kn = int(kn / 10)
    }
    for (i = 1; i <= 8; i++) {
        for (j = 1; j <= 8; j++) {
            ans[i+j-1] += am[i]*an[j]
        }
    }
    carry = 0 # 繰り上がり
    num = 0
    for (i = 1; i <= 8; i++) { # 繰り上がり処理
        ans[i] += carry
        carry = int(ans[i]  / 10)
        num += (ans[i] % 10) * 10^(i-1)
    }
    return num # 答の下 8 桁を返す
}

function fun(m, n,   ans) {
    m = m % 1e8
    ans = 1
    for (;;) {
        if (n % 2 == 1) {
            ans = mul(ans, m) # もとの n の ビットが立っているところを掛け算
        }
        n = int(n / 2) # もとの n のビットが立っているところを探すため半分ずつにしていく
        if (n == 0) return ans
        m = mul(m, m) # 被巾数は倍々にしていく
    }
    return ans
}

$ gawk -f func.awk
254361
81
84765625
79967232
11298161
1
57768001
3328
32397824
25452801