「サルベジオン社で宇宙船のデータを救え」とのことで...
問題 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 で,キーが偶数だったら,ちょっと面倒だったはず。