こちらのアドバイスを元に、斜めに連続する4つの数値の積を求める関数を見直してみる。
-- 行列 grid から斜めの行列 diagonals を作成する
diagonals = (map catMaybes . transpose . zipWith (++) (iterate (Nothing:) []) . map (map Just)) grid
うーむ…これも詳しく読み解いていかないと理解が追いつかない。
まず、map (map Just) gridで、全ての要素に Just をつける。
[[8, 2, 22, 97, 38~[[Just 8, Just 2, Just 22, Just 97, Just 38~になる。

次に、(iterate (Nothing:) [])だが、初期値 [] と 関数 (Nothing:) を与えて無限リストを作る。
[[],[Nothing],[Nothing,Nothing],[Nothing,Nothing,Nothing]~ができる。

これらを zipWith (++) で連結していくと、各行の先頭に Nothing が一つずつ増加して追加された行列が出来上がる。
一行目が[Just 8,Just 2,Just 22,Just 97,Just 38,Just 15,Just 0,Just 40~
二行目が[Nothing,Just 49,Just 49,Just 99,Just 40,Just 17,Just 81,Just 18~
三行目が[Nothing,Nothing,Just 81,Just 49,Just 31,Just 73,Just 55,Just 79~となる。

これを transpose すると、
一行目が[Just 8,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing~
二行目が[Just 2,Just 49,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing~
三行目が[Just 22,Just 49,Just 81,Nothing,Nothing,Nothing,Nothing,Nothing~となる。
お、もうすでに斜めの行列が出来上がりつつある。

これらの各要素に catMaybes することで、Maybe が剥がれる。
catMaybes は Data.Maybe モジュールに定義されていて、Scala の flatten と同じような効果がある。
一行目が[8]
二行目が[2,49]
三行目が[22,49,81]となる。
これで斜めの連続するリストを作ることができた。
あとはリストの要素数が4以上であれば積を計算していって、最大値を求めればいい。

完成形はこんな感じになった。

Copyright© 2011-2021 Shunsuke Otani All Right Reserved .