47問目
http://projecteuler.net/index.php?section=problems&id=47
2つの素因数を持つ数が最初に2つ連続するのは14 = 2 × 7、15 = 3 × 5のときである。4つの素因数を持つ数が最初に4つ連続するとき、その最初の値を求める。
素因数分解を行うのですが、そのときn1/2以下の素数で割っていくことで高速化を図っています。
もともとはこのコメントを参考にしました。
他にも同じように悩んだ人がいたみたいです。
import Data.List main = print $ euler047 4 euler047 :: Int -> Int euler047 n = head $ head $ filter (all ((== n) . len) . take n) $ tails [1..] len :: Int -> Int len n = length $ nub $ factors primes n factors :: [Int] -> Int -> [Int] factors (p:ps) n | q < p = [n] | r == 0 = p : factors (p:ps) q | otherwise = factors ps n where (q, r) = divMod n p primes :: [Int] primes = 2 : filter isPrime [3..] isPrime :: Int -> Bool isPrime x = all ((/= 0) . mod x) $ takeWhile (<= (floor $ sqrt $ fromIntegral x)) primes