算額あれこれ

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

サルベジオン社で宇宙船のデータを救え

「サルベジオン社で宇宙船のデータを救え」とのことで...

問題 1. キーは昇順になっているので,二分法で探索する。
    求める値は "V406435859539156181269150751031"

library(gmp)
url = "http://salvageon.textfile.org/?db=1&index=%s"
key = as.bigz("208050656559285601386927895421059705239114932023754")
begin = as.bigz("0")
end   = as.bigz("1267650600228229401496703205375")
for (i in 0:110) {
    cat(i, as.character(end-begin), "\n")
    med = (begin+end) %/% 2
    m = scan(sprintf(url, med), ""); Sys.sleep(1)
    k = as.bigz(substr(m[3], 2, nchar(m[3])))
    if (k > key) {
        end = med
    } else if (key > k) {
        begin = med
    } else {
        print(m)
        break
    }
}

問題 2. 奇数のキーは後ろ半分にまとまって,順序正しく並んでいる。
    求める値は "V1101943557675920722238136981003"

これは,プログラムを組まずに求めた。

まず,レコードの個数が 2^100 なのに気づけば,ちょうど真ん中が何になっているか,気になる。真ん中の次,その次と見てみれば,ははあ~んと気づいた。

2023636070998557444542586045 は 初項 = 1,項差 = 2 の数列の何番目か?
> (as.bigz("2023636070998557444542586045")+1)/2
[1] 1011818035499278722271293023

対応するコードは
> as.bigz("633825300114114700748351602688")+(as.bigz("2023636070998557444542586045")+1)%/%2 - 1
Big Integer ('bigz') :
[1] 634837118149613979470622895710

コードは 634837118149613979470622895710
scan("http://salvageon.textfile.org/?db=2&index=634837118149613979470622895710", "")

問題 2 で,キーが偶数だったら,ちょっと面倒だったはず。