[Haskell-cafe] Re: Function to detect duplicates
Ketil Malde
ketil at malde.org
Fri Feb 26 10:50:42 EST 2010
| Am Freitag 26 Februar 2010 00:57:48 schrieb Rafael Gustavo da Cunha Pereira
| Pinto:
|
|> 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
Since Ishaaq Chandy just posted about how to generalize nested list
comprehensions, I thought this was an interesting way to approach this.
First a couple of simple helper functions:
> val = foldl (\x y -> x*10+y) 0
> divides d n = n `mod` d == 0
So you could solve it using a set of list comprehensions:
> solutions = [[x1,x2,x3,x4,x5,x6,x7,x8,x9,x10]
> | x1 <- [0..9]
> , x2 <- [0..9], divides 2 $ val [x1,x2]
> , x3 <- [0..9], divides 3 $ val [x1,x2,x3]
> , x4 <- [0..9], divides 4 $ val [x1,x2,x3,x4]
> , x5 <- [0..9], divides 5 $ val [x1,x2,x3,x4,x5]
> , x6 <- [0..9], divides 6 $ val [x1,x2,x3,x4,x5,x6]
> , x7 <- [0..9], divides 7 $ val [x1,x2,x3,x4,x5,x6,x7]
> , x8 <- [0..9], divides 8 $ val [x1,x2,x3,x4,x5,x6,x7,x8]
> , x9 <- [0..9], divides 9 $ val [x1,x2,x3,x4,x5,x6,x7,x8,x9]
> , x10 <- [0]
> , length (nub [x1,x2,x3,x4,x5,x6,x7,x8,x9,x10]) == 10
> ]
This is a nicely declarative way to do it, and a pretty clear way to
formulate the original problem statement. But it's a bit tedious with
all the repetitions, so you would rather recurse to make it more
general. Since list comprehensions are just a different way to work in
the list monad (where | becomes 'guard'), I managed to come up with this:
> solve :: [Int] -> [[Int]]
> solve prefix = do
> let l = length prefix
> if l == 10
> then return prefix
> else do
> x <- [0..9]
> let r = prefix++[x]
> guard (divides (l+1) (val r) && nub r == r)
> solve r
-k
(PS: I'm happy to hear any comments regarding style or other issues)
--
If I haven't seen further, it is by standing in the footprints of giants
More information about the Haskell-Cafe
mailing list