Life Goes On

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

44問目

http://projecteuler.net/index.php?section=problems&id=44
Pj+Pk と Pk-Pj がともに五角数であるような2つの五角数 Pj、Pk について、最小の|Pk - Pj|を求める。
解けたのですが、遅い…。これは何とかしないと。
改善案求む!!

main = print $ euler044

euler044 :: Int
euler044 = head 
    [pk - pj | pj <- pentagonals, pk <- dropWhile (<= pj) pentagonals,
        isPentagonal (pk + pj), isPentagonal (pk - pj)]

isPentagonal :: Int -> Bool
isPentagonal n = n == (head $ dropWhile (< n) pentagonals)

pentagonals :: [Int]
pentagonals = [div (n * (3 * n - 1)) 2 | n <- [1..10000000]]

コメントでヒントを頂きました。
そうか、Pjを固定してPkの上限がないか探していたけど、Pkを先に固定してしまえば、PjはPk未満だから、値域が限定されるんだ。これなら無限リストでも大丈夫。

euler044 :: Int
euler044 = head 
    [pk - pj | pk <- pentagonals, pj <- takeWhile (< pk) pentagonals,
        isPentagonal (pk - pj), isPentagonal (pk + pj)]