2017年10月30日月曜日

フィボナッチ数

--fibo: 定義そのままの素朴な再帰。
fibo 0 = 0
fibo 1 = 1
fibo n = fibo (n - 1) + fibo (n - 2)
f0 = 0:1:(zipWith (+) f0 (tail f0))
--f1: f0をリスト内包表記に置き換えたもの。-XParallelListComp オプションが必要
f1 = 0:1:[x+y|x<-f1|y<-tail f1]
--f2: mainは f2 (0,1)
f2 (a,b) = do
print a
f2 (b,a+b)
--以下はState Monadを利用したLoop。 Control.Monad.State のインポートが必要。
--f3: mainは runStateT f3 (0,1)
f3 :: StateT (Integer, Integer) IO b
f3 = do
(a,b) <- get
liftIO $ print a
put (b,a+b)
f3
--f4: mainは runStateT f4 [1:0]
f4 :: StateT [Integer] IO b
f4 = do
l@(a:b:c) <- get
liftIO $ print l
put $ (a+b):a:b:c
f4
--f5: mainは runStateT f5 ([0,1], 0)
f5 :: StateT ([Integer], Int) IO b
f5 = do
(l,i) <- get
liftIO $ print l
put (l ++ [(l!!i + l!!(i+1))],i+1)
f5
f6 :: [[Integer]]
f6 = scanl (\x@(a:b:_) _ -> (a+b):x) [1,0] [0..]
--f7 main = print "put 0" >> f7 1
f7 :: Integer ->IO ()
f7 b = do
l <- getLine
let a = read l
putStr "put "
print b
f7 $ a + b
view raw fibo.hs hosted with ❤ by GitHub


f6 の実行例

*Main> last $ take 10 f6
[55,34,21,13,8,5,3,2,1,1,0]

これは

foldl (\x@(a:b:_) _ -> (a+b):x) [1,0] [0..8]

と同じです。

フィボナッチ数列の隣り合う 2 項の比は黄金比に収束Wします。

f2 (a,b) = do
print (a,b)
f2 (b,a+b)
main = f2 (1,2)
view raw fibo2.hs hosted with ❤ by GitHub
import Data.Ratio
go = do
c <- getLine
let (a,b) = read c :: (Integer, Integer)
print $ fromRational $ b % a
go
main = go
view raw gr.hs hosted with ❤ by GitHub
$ runghc fibo2.hs | runghc gr.hs

~
~
~
1.618033988749895
1.618033988749895
1.618033988749895
~
~
~
Ctrl-Cを押して終了。

0 件のコメント:

コメントを投稿

Haskell Process

Haskellの System.Processは便利ですが、問題もあります。 単一スレッドでの逐次処理を保証していない。(想像です。) 次のようなスクリプトを書いてみた。 --a.hs main = print [1..10] --t.hs import Sy...