----------------------------------------------------------------------------
【関連】
【F#】Seq.unfoldは理解するのは難しいが・・・分かると簡単??
http://pro.art55.jp/?eid=1303926
【F#】Seq.unfoldは理解するのは難しいが・・・分かると簡単??その2
http://pro.art55.jp/?eid=1303927
【C#】F#のSeq.unfold関数をC#で実装してみた。
http://pro.art55.jp/?eid=1303928
【C#】F#のSeq.unfold関数をC#で実装してみた。その2
http://pro.art55.jp/?eid=1303929
-----------------------------------------------------------------------------
【F#】Seq.unfoldは理解するのは難しいが・・・分かると簡単??そ(http://pro.art55.jp/?eid=1303926)の続きです。
背伸びしてフィボナッチ数のシーケンスを求めたいと思います。
フィボナッチ数列は下記のように定義できるそうです(参照Wik)
式1: F_0 = 0
式2: F_1 = 1
式3: F_n2 = F_n + F_n1 (n>=0)
※_n1は下付のn+1、_n2は下付のn+2
(雑記)一般項の証明は高校でならったような気がしますが、完全に忘れていました。なんでルートが出てくるん??って、昔ならったとすれば、同じ事に2度驚いたことになります。
で、Seq.unfoldの第一引数の関数に当てはめてみたいと思います。
カレントの値がF_nならネクストの値はF_n1です。
式3はつまり二つ連続するフィボナッチ数を組とする引数をとると、そのFn1の次のフィボナッチ数が求められるということなので
F_n2 (F_n, F_n1) = F_n + F_n1
なので
カレントの状態(F_n, F_n1)を渡すとカレントの値がFnになり
カレントの状態(F_n, F_n1)を渡すとネクストの状態は(Fn1, Fn2)
(Fn1, Fn2)は(Fn1, Fn + Fn1)と書き換えることができます。
なのでフィボナッチ数列をシーケンスで表現すると
let fibonacciSequence = Seq.unfold (fun (f_n, f_n1) -> Some(f_n, (f_n1, f_n + f_n1))) (0, 1)
となります。
コンソール出力させるコードも記述すると
let fibonacciSequence = Seq.unfold (fun (f_n, f_n1) -> Some(f_n, (f_n1, f_n + f_n1))) (0, 1)
fibonacciSequence
|> Seq.takeWhile (fun number -> number <= 1000)
|> Seq.iter (printfn "%d")
で出力結果は
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
オライリーに書かれてるコードと差異がありますが、なんとか自分で記述することができました。