Life Goes On

まあまあだけど楽しんでる方です

60問目

http://projecteuler.net/index.php?section=problems&id=60
7 と 109 をつなげた数は 7109 も 1097 も素数となる。素数 3, 7, 109, 673 はどの2つをつなげても素数となる。同様にどの2つをつなげても素数となるような素数5つの組合せについて、その和の最小値を求める。
最初は小さい素数から順に組み合わせて求めようとしたのですが、そうすると探索の範囲が決まらないので、一番大きい素数を決めて、それより小さい素数の中から他の素数を探すようにしました。

main = print $ sum $ euler060 5

euler060 :: Integer -> [Integer]
euler060 n = head $ cons n primes

cons :: Integer -> [Integer] -> [[Integer]]
cons 0 _ = [[]]
cons n xs = [ x : con | x <- xs,
    let xs' = filter (canConcat x) $ takeWhile (< x) xs,
    con <- cons (n - 1) xs' ]

canConcat :: Integer -> Integer -> Bool
canConcat p1 p2 = (isPrime $ read $ (show p1) ++ (show p2)) &&
    (isPrime $ read $ (show p2) ++ (show p1))

primes :: [Integer]
primes = 2 : filter isPrime [3..]

isPrime :: Integer -> Bool
isPrime x = all ((/= 0) . mod x) $
    takeWhile (<= (floor $ sqrt $ fromIntegral x)) primes