Life Goes On

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

58問目

http://projecteuler.net/index.php?section=problems&id=58
1から始まる数を時計回りにらせん状に配置していく。四隅の数のうち素数の占める割合が最初に10%未満になるのは、一辺の長さがいくつのときか求める。
若干遅いので、もう少し上手いやり方があるのかもしれません。

main = print euler058

euler058 :: Int
euler058 = (head $ dropWhile over10 [1..]) * 2 + 1
    where over10 n = (primesOnCorner !! n) * 100 >= (4 * n + 1) * 10

primesOnCorner :: [Int]
primesOnCorner = scanl1 (+) $ map (length . filter isPrime) corners

corners :: [[Integer]]
corners = [ [ 2*m*n+(2*n-1)^2 | m <- [1..4] ] | n <- [0..] ]

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

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