Just to clarify the issue, I will propose the puzzle:
There is a single 10 digit number that:
1) uses all ten digits [0..9], with no repetitions
2) the number formed by the first digit (right to left, most significant) is divisible by one
3) the number formed by the first 2 digits (again right to left) is divisible by two
4) the number formed by the first 3 digits is divisible by three
and so on, until:
11) the number formed by the first 10 digits (all!) is by 10
Actually this can be solved by a little logic, but I wanted to give a try on brute force search using haskell.
I am not looking very large lists, but I was expecting a handful of small lists.
My algorithm follow these steps:
1) start with an list of empty list ([[]]), call it ds
2) I cons each member of [0..9] to ds
3) filter using:
a) noneRepeated
b) (listToNum d) `mod` l == 0, where l is the length of each sublist d (not computed, it is an accumulator that is incremented each time I cons)
4) repeat steps 2-3 until l==10
So, I represent each possible number as a reversed list of its digits... It ran REALLY fast (sub-second).
So, bragging about Haskell with a Smalltalk-lover friend, by showing him how clean was the code and how easy was to profile, I figured out that I spent 99% on noneRepeated.
After changing to the merge sort version, I have 30% on noneRepeated, 30% on listToNum and 30% on putStrLn. Pretty good!
Besides, I could brag a little more about Hakell to that specific friend!! ;-)
Best regards to you all!!
Rafael
PS: Here is the original search code, with the bad noneRepeated and still using length
import Data.List
digits=[0..9]
noneRepeated::[Integer]->Bool
noneRepeated=null.(filter
(>1)).(map length).group.sort
listToNum::[Integer]->Integer
listToNum
= (foldl (\a x->10*a+x) 0).reverse
check::[Integer]->Bool
check ds= and [noneRepeated ds,
(listToNum ds) `mod` l==0]
where l=fromIntegral $ length ds
nextlevel::[[Integer]]->[[Integer]]