I’m currently in the process of solving euler problems to improve in Haskell. Though, my attempt at solving problem n° 43 produces no output.
Just to be clear, I’m not asking for help on the “problem algorithmic” part, even if I’m wrong. I’m specifically asking for help on the Haskell part.
So, I divided my attempt into simple functions. First I build a list holding all 0-9pandigital numbers, then I define functions to cut those numbers into the interesting part and finally I filter only the correct ones:
import Data.List
main = print $ foldl1 (+) goodOnes
pands = [read x :: Integer | x <- permutations "0123456789", head x /= '0']
cut3from :: Integer -> Integer -> Integer
cut3from x n = mod (div x nd) 1000
where
l = fromIntegral $ length $ show x :: Integer
nd = 10 ^ (l - 3 - n)
cut :: Integer -> [Integer]
cut x = map (cut3from x) [1..7]
testDiv :: Integral a => [a] -> Bool
testDiv l = and zipped
where
zipped = zipWith mult l [2, 3, 5, 7, 11, 13, 17]
mult :: Integral a => a -> a -> Bool
mult a b = mod a b == 0
goodOnes = filter (testDiv.cut) pands
Though, when compiling it (with -O2) and executing it, it outputs nothing. Even with +RTS -s.
I’d like advice on two points mainly:
- why is this code wrong, how to improve it
- how could I have debugged it myself
- as a side point, if you have advice on how to handle Integer and Ints easily, please post them. I find it troublesome to use both together.
But any other remark is welcome!
EDIT: it seems that GHCi slowly builds the result list goodOnes and is able to answer after a long time (only in GHCi, when compiled it’s still as reported). That’s certainly not a behaviour I can wish to observ in my programs. How could I fix that ?
EDIT2: it now works when compiled too (code unchanged). I’m puzzled about all those inconsistencies and would welcome any explanation!
EDIT3: semihappy ending: after a reboot, all went back to normal ~~
To answer “how could I have debugged it myself”:
Check out ghci.
It’s an interactive interpreter that allows you to:
load files and play with the contents
type in definitions and use them
evaluate expressions and see the results
inspect types and kinds
Make sure you test each of the little pieces before you test the whole shebang — it’s easier to find problems in small things than in big ones. Check out QuickCheck if you’re into unit tests.
For the
Ints vs.Integers issue, you could sidestep the issue by only usingIntegers (of course, they may be less efficient: YMMV).Data.Listhas functions prefixed withgeneric, i.e.genericLengthwhich are quite useful.Here’s how I compiled and ran it: