Project Euler in R: Problem 25 の中の aatrujilloJan 25, 2012 03:02 PM
なぜ list なんかを使うかなあ。途中の項も不要なんだから,以下のようにすれば,計算時間は半分になる。
a <- as.bigz(1)
b <- as.bigz(1)
i <- 2
repeat {
i <- i+1
c <- a+b
if (nchar(as.character(c)) >= 1000) break
a <- b
b <- c
}
print(i)
ところで,元のプログラムは,
fibon1 = list()
fibon1[[1]] = fibon1[[2]] = as.bigz(1)
digits = 1000
i=3
n=0
while(n < digits){
fibon1[[i]] = fibon1[[i-1]]+fibon1[[i-2]]
n = nchar(as.character(fibon1[[i]]))
i=i+1
}
i-1
のように,答えの表示で i-1 としている。
これは,カウンターの位置が不適切だからそうしないと答えが合わないからだが,以下のようにするのが自然。
fibon1 = list()
fibon1[[1]] = fibon1[[2]] = as.bigz(1)
digits = 1000
i=2
n=0
while(n < digits){
i=i+1
fibon1[[i]] = fibon1[[i-1]]+fibon1[[i-2]]
n = nchar(as.character(fibon1[[i]]))
}
i
プログラム書法の一つ:カウントのしそこないに注意
while ループの前に n=0 などと無駄な設定が必要なのは,while ループを使っているから。新しい項を計算して,その項の桁数を見ればよいのだから,repeat を使えば n=0 という設定は不要。r の repeat は繰り返し終了判定を含まないので repeat ループの中で if を使う。
fibon1 = list()
fibon1[[1]] = fibon1[[2]] = as.bigz(1)
digits = 1000
i=2
repeat {
i=i+1
fibon1[[i]] = fibon1[[i-1]]+fibon1[[i-2]]
if (nchar(as.character(fibon1[[i]])) >= digits) break
}
i
プログラム書法の一つ:適切なところで条件判定をしよう