import Data.List (unfoldr) import Data.List (find) import Data.Maybe (listToMaybe) minus (x:xs) (y:ys) = case (compare x y) of LT -> x : minus xs (y:ys) EQ -> minus xs ys GT -> minus (x:xs) ys minus xs _ = xs union (x:xs) (y:ys) = case (compare x y) of LT -> x : union xs (y:ys) EQ -> x : union xs ys GT -> y : union (x:xs) ys union xs [] = xs union [] ys = ys primesToQ m = eratos [2..m] where eratos [] = [] eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m]) combinations 0 _ = [[]] combinations n xs = [ xs !! i : x | i <- [0..(length xs)-1] , x <- combinations (n-1) (drop (i+1) xs) ] pfactors prs n = unfoldr (\(ds,n) -> listToMaybe [(x, (dropWhile (< x) ds, div n x)) | x <- takeWhile ((<=n).(^2)) ds ++ [n|n>1], mod n x==0]) (prs,n) primes = 2 : 3 : [x | x <- [5,7..], head (pfactors (tail primes) x) == x] isPrime n = n > 1 && foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r)) True primes is_concatenatable_pair list = isPrime (read(show(list!!0) ++ show(list!!1))) && isPrime (read(show(list!!1) ++ show(list!!0))) is_concatenatable_set list = and (map is_concatenatable_pair (combinations 2 list)) solution = find is_concatenatable_set (combinations 4 (primesToQ 30000))