1

The following works fine:

sdb n = sum [n,n*2..999]
main = print $ sdb 3 + sdb 5 - sdb 15

But it's not that efficient since it has to sum 999/n times each time sdb is called. when I rewrote sdb:

sdb n = 
    let x = quot 999 n
    in n*x*(x+1)/2

and runhaskell the whole code, I got an entire page of error. Summing it up:

... No instance for (Show a0) arising from a use of `print'
... No instance for (Integral a0) arising from a use of `sdb'
... No instance for (Num a0) arising from a use of `-'

I added type declaration for sdb:

sdb :: Integer -> Integer

but I got another error:

No instance for (Fractional Integer) arising from a use of `/'
    Possible fix: add an instance declaration for (Fractional Integer)
    In the expression: n * x * (x + 1) / 2
    In the expression: let x = quot 999 n in n * x * (x + 1) / 2
    In an equation for `sdb':
        sdb n = let x = quot 999 n in n * x * (x + 1) / 2

I don't get it.

  1. What should I correct? Can you also explain why I got those errors? SOLVED: I changed / with div.

  2. Is there a more idiomatic and/or concise way to write the same algorithm?

Pigna
  • 2,792
  • 5
  • 29
  • 51

1 Answers1

0

How about this:

sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]

Edit

For a small upper bound like 999 this would be a more idiomatic and concise way, but if a more general solution is required, above would be too slow. Here is a better approach, which similarly to the questions itself, uses "Gauss's trick" to sum numbers divisible by n:

sumOfMults :: Integral a => a -> a -> a -> a
sumOfMults n1 n2 m = sdb n1 + sdb n2 - sdb (lcm n1 n2) where
  sdb n = let x = m `div` n
          in n * x * (x + 1) `div` 2
lehins
  • 9,642
  • 2
  • 35
  • 49
  • 1
    shorter, of course, but slower :/ and it's a different algorithm from mine. I asked for a more idiomatic and/or concise way of writing the same algorithm because I'm new to Haskell and I want to learn the best syntax – Pigna Apr 02 '16 at 16:30
  • 1
    It is more idiomatic and concise. Looking at this code it is extremely easy to see what is actually going on, it's almost like a specification of the problem itself (Sum all numbers from 1 to 999 that are divisible by 3 or 5). I do agree that it is slower, but that would only matter if you where working with upper bounds of much higher than `999`. – lehins Apr 02 '16 at 17:00
  • oh sure, but I put 999 just as an example. Sorry for not being clear! – Pigna Apr 02 '16 at 17:30
  • @Pigna, in that case your solution was good. I added a little more general one, see the edit. – lehins Apr 03 '16 at 16:03