views:

458

answers:

1

Hi I am doing problem 21 in eulerproject. One part requires finding the list of proper divisors of a number. i.e. where there is remainder of n and some number of less than n. So I made this Haskell, but GHCI gets angry at me.

divisors n =[ n | n <- [1..(n-1)], n `rem` [1..(n-1)] ==0 ]

The problem is that I don't know how to make:

n `rem` [1..(n-1)]

so that it only returns the number less than n that divide evenly into n.

+5  A: 

You just need a separate variable.

Prelude> let divisors n = [x | x <- [1..(n-1)], n `rem` x == 0]
Prelude> divisors 20
[1,2,4,5,10]
Prelude> divisors 30
[1,2,3,5,6,10,15]

Now, if you wanted to make it a bit more efficient, we already know that a divisor won't be more than half of n, and we know 1 is a divisor of everything. And, let's go ahead and make it a bit more Haskell-y to boot, avoiding a list comprehension:

Prelude> let divisors n = 1 : filter ((==0) . rem n) [2 .. n `div` 2]
Prelude> divisors 20
[1,2,4,5,10]
Prelude> divisors 30
[1,2,3,5,6,10,15]
Prelude> divisors 31
[1]
Mark Rushakoff
Why is list comprehension not very Haskell?Also, a small question, is there a way to find the sum of the sum of all the lists in a list?
Jonno_FTW
I'm not a Haskell veteran by any means, but I haven't really seen any list comprehensions used in any Haskell libraries, for instance. Small answer: `sum $ map sum x`, such as `sum $ map sum [ [1,2,3], [4,5,6], [7,8,9] ]` resulting in 45.
Mark Rushakoff