fugafuga.write

日々のログ

すごいH本 part18

map と filter ふたたび

10万以下の数のうち3829で割り切れる最大の数を探す

largestDivisible :: Integer
largestDivisible = head (filter p [100000,99999..])
  where p x = x `mod` 3829 == 0

実行結果

*Main> largestDivisible
99554

10000 より小さい全ての奇数の平方数の和

*Main> sum (takeWhile (<10000) (filter odd (map (^2) [1..])))
166650

内包表記で書く

*Main> sum (takeWhile (<10000) [m | m <- [n^2 | n <- [1..]], odd m])
166650

コラッツ数列を扱う

  • 任意の自然数から開始する
  • 数が1なら、終了
  • 数が偶数なら、2で割る
  • 数が奇数なら、3倍して1足す
  • 新しい値でこのアルゴリズムを繰り返す

1から100までの数のうち、長さ15以上のコラッツ列の開始数になるものはいくつあるか?

まず数列を作る関数を書く

chain :: Integer -> [Integer]
chain 1 = [1]
chain n
  | even n = n : chain (n `div` 2)
  | odd n  = n : chain (n * 3 + 1)

実行結果

*Main> chain 3
[3,10,5,16,8,4,2,1]

chainを使って求める

numLongChains :: Int
numLongChains = length (filter isLong (map chain [1..100]))
  where isLong xs = length xs > 15

実行結果

*Main> numLongChains
66

map に複数の引数を与える

*Main> let listOfFuns = map (*) [0..]
*Main> (listOfFuns !! 4) 5
20

!!はリストの要素を取得する演算子

(4*) 5になってる

所感

関数が長くなってくると読むのに時間がかかるようになってきた。 部分適用のおかげで関数を扱うための柔軟性が上がっていることを実感してきている。

いやー、楽しいな。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

  • 作者: MiranLipovaca
  • 出版社/メーカー: オーム社
  • 発売日: 2017/07/14
  • メディア: Kindle版
  • 購入: 4人 クリック: 9回
  • この商品を含むブログを見る