7254は39×186=7254としたときに、かける数・かけられる数・積が1から9までの 数字が1回ずつ使われているという特徴がある。
かける数・かけられる数・積で1から9の数字が1回ずつ使われている全の積の和 を求めよ。
ヒント:いくつかの積は複数の方法で得られるが和には一度しか含めない。
式に使われている数字が順列だと考えて、全ての数の並びの組み合わせについ て、それぞれxと=が全ての組み合わせで考えたとき、掛け算の式として成り立 つかどうかを考える。
まず、数字の順列を生成する部分は問題24で定義した関数permutationを使う。 それにmapを用いてローカル関数checkを適用する。ここでは順列のリストを3つ に分割し、1番目の部分と2番目の部分の積が3番目の部分の値になっているかを チェックし、成り立っている場合はその積を返す。3つに分割する部分は、それ ぞれ少なくとも1つの数字を含んでいる必要があるので、1番目の部分の長さが 1から7、2番目の部分が1から8-1番目の長さとなる。ここでリストを数に変換す る関数listToIntを適用しそのtupleを返す。リストを数に変換する関数は foldl1を用いて定義する。foldl1はfoldlと同様にリストの要素を順番に関数に 適用するが、初期値としてリストの先頭の要素を用いる。
listToInt = foldl1 (\x y -> x * 10 + y)
euler032 = sum $ nub $ concat $ map check $ permutation [1..9]
where check l = [z | (x, y, z) <- split, x * y == z]
where split = [split' i j | i <- [1..7], j <- [1..8 - i]]
where split' i j =
let (x, l2) = splitAt i l
(y, z) = splitAt j l2
in (listToInt x, listToInt y, listToInt z)
