以下の20×20の格子状にならんだ数字のうち、対角線上に並んだ4つの数字が赤 く色がついている。
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48この4つの数の積は26x63x78x14=1788696である。
この20×20の格子状で、縦横斜めのいずれかの方向に並んだ4つの数字の積の最 大値を求めよ。
ここで再びデータの扱いが問題となる。今回も数が少ないのでプログラム中に リテラルとして埋め込むことにする。問題を素直に実装する場合、データへの ランダムアクセスが必要となるが、基本的にはリストというのはランダムアク セスに適していない。そこでHaskellの配列を使うことにする。
まずデータは都合のいい形に書き換えることにする。今回は以下のように問題 のデータにガード用の0を追加したリストとした。そしてlistArray関数を使い 配列を生成する。配列のインデックスは任意の値が指定できる。今回は本来の データが(0,0)-(19,19)の範囲にくるように、(0, -3)から(22, 22)の範囲をイ ンデックスに指定した。
続いて問題を解くプログラムであるが、全ての場所を起点にして縦横斜めの4つ の積をそれぞれ求めてリストにしmaximumで最大値を求めるというものである。 ここでproduct4はある点での縦横斜め4方向の積のリストを求める関数。リスト の内包表記で全ての点の積のリストを求めている。product4は実際には product4’を計算する方向を指定して呼び出し結果をリストにしている。 product4’では配列から方向に従って4つの値を取り出したリストを生成し、 productでその積を求めている。配列の要素にアクセスする演算は!である。
euler011Grid = listArray ((0, -3), (22, 22)) [0,0,0,08,02,22,97,38,15,00,40,00,75,04,05,07,78,52,12,50,77,91,08,0,0,0, 0,0,0,49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,04,56,62,00,0,0,0, 0,0,0,81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,03,49,13,36,65,0,0,0, 0,0,0,52,70,95,23,04,60,11,42,69,24,68,56,01,32,56,71,37,02,36,91,0,0,0, 0,0,0,22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80,0,0,0, 0,0,0,24,47,32,60,99,03,45,02,44,75,33,53,78,36,84,20,35,17,12,50,0,0,0, 0,0,0,32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70,0,0,0, 0,0,0,67,26,20,68,02,62,12,20,95,63,94,39,63,08,40,91,66,49,94,21,0,0,0, 0,0,0,24,55,58,05,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72,0,0,0, 0,0,0,21,36,23,09,75,00,76,44,20,45,35,14,00,61,33,97,34,31,33,95,0,0,0, 0,0,0,78,17,53,28,22,75,31,67,15,94,03,80,04,62,16,14,09,53,56,92,0,0,0, 0,0,0,16,39,05,42,96,35,31,47,55,58,88,24,00,17,54,24,36,29,85,57,0,0,0, 0,0,0,86,56,00,48,35,71,89,07,05,44,44,37,44,60,21,58,51,54,17,58,0,0,0, 0,0,0,19,80,81,68,05,94,47,69,28,73,92,13,86,52,17,77,04,89,55,40,0,0,0, 0,0,0,04,52,08,83,97,35,99,16,07,97,57,32,16,26,26,79,33,27,98,66,0,0,0, 0,0,0,88,36,68,87,57,62,20,72,03,46,33,67,46,55,12,32,63,93,53,69,0,0,0, 0,0,0,04,42,16,73,38,25,39,11,24,94,72,18,08,46,29,32,40,62,76,36,0,0,0, 0,0,0,20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,04,36,16,0,0,0, 0,0,0,20,73,35,29,78,31,90,01,74,31,49,71,48,86,81,16,23,57,05,54,0,0,0, 0,0,0,01,70,54,71,83,51,54,69,16,92,33,48,61,43,52,01,89,19,67,48,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] euler011 = maximum [ maximum $ product4 i j | i
