49問目
http://projecteuler.net/index.php?section=problems&id=49
1487, 4817, 8147のように、(i)どれも素数で、(ii)それぞれの数が他の数の並べ替えとなっている、4桁の等差数列を見つけ、それを繋げた12桁の数を求める。
手順は↓の通り。間違ってはいませんが、もう少し端折ってもよかったみたいです。(各グループで3つの数の組合せを律儀に求めず、小さい順に並べて等差数列になるものを抽出しても、答えは求まる)
- まず4桁の素数を抽出
- 構成する数字でグループ化
- 各グループで3つの数の組合せを全て求め
- 等差数列となる組合せを抽出
import Data.List import Data.Ord main = print $ euler049 euler049 :: [String] euler049 = map concat $ filter arithmetic $ concatMap (comb 3) $ groupBy (\ a b -> sort a == sort b) $ sortBy (comparing sort) $ map show $ takeWhile (< 10000) $ dropWhile (< 1000) primes arithmetic :: [String] -> Bool arithmetic [] = False arithmetic [a, b, c] = read c - read b == read b - read a comb :: Eq a => Int -> [a] -> [[a]] comb n s | (n > length s) = [[]] | (n == 0) = [[]] | otherwise = [x : xs | x <- take ((length s) - n + 1) s, xs <- comb (n - 1) (tail $ dropWhile (/= x) s)] primes :: [Int] primes = 2 : filter isPrime [3..] isPrime :: Int -> Bool isPrime x = all ((/= 0) . mod x) $ takeWhile (<= (floor $ sqrt $ fromIntegral x)) primes