| 1 | {-# LANGUAGE RankNTypes #-} |
|---|
| 2 | {-# OPTIONS_GHC -O -fno-full-laziness #-} |
|---|
| 3 | |
|---|
| 4 | import Control.Parallel ( par ) |
|---|
| 5 | import Control.Parallel.Strategies ( using, seqList, r0 ) |
|---|
| 6 | |
|---|
| 7 | newtype Search a = S { search :: forall b . (a -> Int -> [b]) -> Int -> [b] } |
|---|
| 8 | |
|---|
| 9 | idfs :: Int -> Search a -> [a] |
|---|
| 10 | idfs n a = parconcat [ search a result d | d <- [0,n..] ] |
|---|
| 11 | where result x d = if d<n then [x] else [] |
|---|
| 12 | |
|---|
| 13 | parconcat :: [[a]] -> [a] |
|---|
| 14 | parconcat [] = [] |
|---|
| 15 | parconcat (x:xs) = ys `par` ((x `using` seqList r0) ++ ys) |
|---|
| 16 | where ys = parconcat xs |
|---|
| 17 | |
|---|
| 18 | ret :: a -> Search a |
|---|
| 19 | ret x = S ($x) |
|---|
| 20 | |
|---|
| 21 | bind :: Search a -> (a -> Search b) -> Search b |
|---|
| 22 | bind (S a) k = S (\c -> a (\x -> search (k x) c)) |
|---|
| 23 | |
|---|
| 24 | zero :: Search a |
|---|
| 25 | zero = S (\_ _ -> []) |
|---|
| 26 | |
|---|
| 27 | plus :: Search a -> Search a -> Search a |
|---|
| 28 | plus (S a) (S b) = S (\c d -> if d==0 then [] else a c (d-1) ++ b c (d-1)) |
|---|
| 29 | |
|---|
| 30 | anyof :: [a] -> Search a |
|---|
| 31 | anyof = foldr plus zero . map ret |
|---|
| 32 | |
|---|
| 33 | pytriple :: Search (Int,Int,Int) |
|---|
| 34 | pytriple = anyof [1..] `bind` \a -> |
|---|
| 35 | anyof [a+1..] `bind` \b -> |
|---|
| 36 | anyof [b+1..] `bind` \c -> |
|---|
| 37 | if a*a + b*b == c*c then ret (a,b,c) else zero |
|---|
| 38 | |
|---|
| 39 | main = print . length . take 500 . idfs 100 $ pytriple |
|---|