次のような再帰シーケンスを含む(プログラミング競技の練習から)挑戦的な問題に出くわしました
与えられた 3 つの数値mnk検索要素 a[k] ここで
a[0] = m
a[1] = n
a[i] = a[i-1] + a[i-2] ; if floor(i/2) mod 2 = 1
a[i] = a[i-1] - a[i-4] ; if floor(i/2) mod 2 = 0
例: m=2 n=3 k=6 の場合、答えは 9 になります
a[0] = 2
a[1] = 3
a[2] = 3 + 2 = 5
a[3] = 5 + 3 = 8
a[4] = 8 - 2 = 6
a[5] = 6 - 3 = 3
a[6] = 3 + 6 = 9
...
これは私がシーケンスを生成する方法です(明らかに最初の100要素でも大量のスタックと超低速を消費します)
1 fbm :: Int → Int → Int → Int
2 fbm m n 0 = m
3 fbm m n 1 = n
4 fbm m n x = let a = fbm m n (x-1)
5 b = fbm m n (x-2)
6 c = fbm m n (x-4)
7 in case (x `div` 2) `mod` 2 of
8 1 → a + b
9 0 → a - c
10
11 fbs m n = map (λx→fbm m n x) [0..]
大きな(〜1000 +)インデックスで要素を見つける必要があるため、問題が発生しました。4つの入力を持つ関数のみに計算を制限し、 4つの要素ウィンドウを持つ関数をリストに再帰的に適用することで、別のアプローチを試みますが、それらの実装に成功することはできません(方法がわからないことを意味しますやれ)
fs1 = map fst $ iterate next (a,b)
where next (a,b) = something
fs2 = m:n:scanl (gen) 2 fs2
where gen [a,b,c,d] = something
fs3 = scanl (genx m n 0 0) (repeat 0)
where genx a b c d = something
質問 1:この問題を解決するための良い方法はありますか? (+それを行う方法の例を見せてください)
質問 2:私のやり方が間違っていたら、この種の問題をどのように解決しますか?