1

I need to write a function that will return the number of ways in which can be n (n is a natural number) written as the sum of natural numbers. For example: 4 can be written as 1+1+1+1, 1+1+2, 2+2, 3+1 and 4. I have written a function that returns the number of all the options, but does not take into account that the possibilities 1 + 1 + 2 and 2 + 1 + 1 (and all similar cases) are equal. So for n=4 it returns 8 instead of 5. Here is my function:

(define (possibilities n)
   (define (loop i)
      (cond [(= i n) 1]
         [(> i n) 0]
         [(+ (possibilities (- n i)) (loop (+ i 1)))]))
     (cond [(< n 1) 0]
        [#t (loop 1)]))

Could you please help me with fixing my function, so it will work the way it should be. Thank you.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
koshy6252
  • 75
  • 1
  • 6
  • Be careful with how you're using `cond`. You should use `else` for the last condition, not `#t` and definitely not an expression without a condition as you did in the 5th line of your function. – Óscar López Jan 18 '15 at 19:21

1 Answers1

1

This is a well-known function, it's called the partition function P, its possible values are referenced as A000041 in the on-line encyclopedia of integer sequences.

One simple solution (not the fastest!) would be to use this helper function, which denotes the number of ways of writing n as a sum of exactly k terms:

(define (p n k)
  (cond ((> k n) 0)
        ((= k 0) 0)
        ((= k n) 1)
        (else 
         (+ (p (sub1 n) (sub1 k))
            (p (- n k) k)))))

Then we just have to add the possible results, being careful with the edge cases:

(define (possibilities n)
  (cond ((negative? n) 0)
        ((zero? n) 1)
        (else
         (for/sum ([i (in-range (add1 n))])
           (p n i)))))

For example:

(map possibilities (range 11))
=> '(1 1 2 3 5 7 11 15 22 30 42)
Óscar López
  • 232,561
  • 37
  • 312
  • 386