-- Haskell reconstruction of http://blog.lorentey.hu/2010/04/21/cpp-template-metaprogramming/ value :: [Int] -> Int value [] = 0 value (first:rest) = 10 * (value rest) + first contains :: Int -> [Int] -> Bool contains elem [] = False contains elem (first:rest) = elem == first || (contains elem rest) divisor_test :: [Int] -> Bool divisor_test (first:rest) = let num = value (first:rest) div = (length rest) + 1 modulus = num `mod` div in modulus == 0 test_candidate :: [Int] -> Bool test_candidate (first:rest) = divisor_test (first:rest) && (not (contains first rest)) search_i :: Int -> Bool -> Bool -> [Int] -> Int search_i len True True (digit:rest) = value (digit:rest) search_i len True False (digit:rest) = search len (1:digit:rest) search_i len good final (digit:rest) = search len (digit+1:rest) search :: Int -> [Int] -> Int search len [] = search len [1] search len [10] = -1 search len (10:next:rest) = search len ((next+1):rest) search len (digit:rest) = let good = test_candidate (digit:rest) final = good && 1 + (length rest) == len in search_i len good final (digit:rest) test = search 9 []