2008年5月1日木曜日

とりあえず、「ふつうのHaskell」は読み終わった。

サンプルも書いた。
でも、ぶっちゃけよくわからんよ、Haskell。

とりあえず、fizzbuzz問題でも解いてみる。れんしゅう。


** 1から100までの数字を列挙。ただし、3の倍数の時はfizz、5の倍数の時はbuzz、15の倍数の時はfizzbuzz。

普通の言語で組むなら100まで回したループの内部で条件分岐、って考えるのがシンプルだが。
haskellループないし。
1から100までのリストを用意して各要素に対してfizzbuzzな関数を適用して出力。かなぁ。

とりあえず1から100までのリストを出してみる。
>|haskell|
main = putStr [1..100]
||< 怒られた。putStrにリストは渡せないか。じゃあ、リストを展開して出すか。 >|haskell|
main = putStr unlines [1..100]
||< 怒られた。unlinesは文字列のリストじゃないとダメか。 >|haskell|
main = print [1..100]
||< でた。んー。最終的な出力形式をどうするかって問題がありそげだけど、とりあえずこれでいいか。 ふむ。入力はIntのリストだけど、出力にはfizzやらbuzzやらが入るんだから、Stringのリストになるのか。 つーことは、fizzbuzz関数の型は [Int] -> [String] か。
とりあえず、fizzbuzz関数を組み込んでみる。

>|haskell|
main = print $ fizzbuzz [1..100]

fizzbuzz :: [Int] -> [String]
fizzbuzz cs = map show cs
||< 問答無用でshow関数使ってIntをStringに変えちゃってるけど、ここに条件入れればおけかな。 >|haskell|
main = print $ fuzzbizz [1..100]

fuzzbizz :: [Int] -> [String]
fuzzbizz cs = map test cs
where
test c = if c `mod` 15 == 0 then "fizzbuzz" else
if c `mod` 5 == 0 then "buzz" else
if c `mod` 3 == 0 then "fizz" else show c
||< でけた。次。 ** 素数を出す。 Haskellとかすごい得意そうな問題だな。 んー。考え方としては、2以上の数のリストを用意して (1が入ると面倒なので) そのリストから先頭一つをとって、その数で割れるかどうかのフィルタリングをして、ってかんじかなー。 こんな感じ? 2, [ 3, 4, 5, 6, ...] →のリストに対して2で割れないモノだけ抽出するフィルタをかけると 2, [ 3, 5, 7, 9, ...] そしたら、→のリストに同じことを繰り返してく。 2, 3, [ 5, 7, 11, ... ] →のリストがなくなるまで続けて、最後に連結して終わり。 調べればもっと効率的な解法がありそうだけど、とりあえずこれで組んでみる。 >|haskell|
main = print $ prime [2..100]

prime :: [Int] -> [Int]
prime [] = []
prime (x:xs) = x : ( prime $ filter check xs )
where
check c = if c `mod` x /= 0 then True else False
||<>|haskell|
main = print $ prime [2..100]

prime :: [Int] -> [Int]
prime [] = []
prime (x:xs) = x : prime [ c | c <- xs, c `mod` x /= 0 ]
||<

こんなもんかな。

http://d.hatena.ne.jp/masato_spica/20080609

0 件のコメント: