2

having an issue with my perfect number function. The objective of the code is to determine if the number is a perfect number, meaning it is equal to the sum of its divisors. Ex:6. Im having trouble with my code. Here's my function:

(define (is-perfect x)
  (define (divides a b) (= (modulo b a) 0))
  (define (sum-proper-divisors y)
    (if (= y 1)
        1
        (if (divides y x)
            (+ y (sum-proper-divisors (- y 1)))
        (if (= x 1)
            #f
            (= (sum-proper-divisors (- x 1)
                                    x)))))))
false
  • 10,264
  • 13
  • 101
  • 209

2 Answers2

2

You almost got it! there are a couple of problems, though. First, you're missing a case in sum-proper-divisors: you ask if y is one and if (divides y x), but what happens if y does not divide x?

The second problem, is that the last if expression must be outside of the definition of the two helper procedures, currently it's inside sum-proper-divisors. Properly indenting your code will make easier to find this kind of errors.

This is how a correct solution looks, because this looks like homework I'll let you fill-in the blanks:

(define (is-perfect x)
  (define (divides a b)
    (= (modulo b a) 0))
  (define (sum-proper-divisors y)
    (cond ((<= y 1)
           1)
          ((divides y x)
           (+ y (sum-proper-divisors (- y 1))))
          (else
           <???>))) ; what goes in here?
  (if (= x 1)
      #f
      (= (sum-proper-divisors (- x 1)) x)))
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • It goes to infinite loop at x=0, maybe remove the if and change `((= y 1) 1)` to `((<= y 0) 0)` ? – user1651640 Sep 12 '12 at 18:02
  • I apologize, but I seem to have introduced a bug with my suggestion, I did't notice 0 would "become" a perfect number like this. the if predicate should be `<= x 1` . the cond wasn't a problem. I'm terribly sorry. – user1651640 Sep 13 '12 at 09:48
0
(define (is-perfect x)

  (define (divides a b) (= (modulo b a) 0))

  (define (sum-proper-divisors y)
    (if (< y 1)  
       0                                     ; stop recursion here
       (if (divides y x)
         (+ y (sum-proper-divisors (- y 1))) ; add 'y' to the sum
         (sum-proper-divisors (- y 1))       ; else continue testing and sum divisors below 'y'
       )
    )
  )

  ; now, use the defined functions to obtain and return result
  (if
    (<= x 0)
      #f      ;; by definition, perfect number must be a positive integer, so...
      (= (sum-proper-divisors (- x 1)) x) ; ...else.
  )
  
)

Test 0-999:

(for ([i 1000])
   (cond 
     ((is-perfect i)
        (printf "~a IS PERFECT~n" i)
     )
   )
)

Output:

6 IS PERFECT
28 IS PERFECT
496 IS PERFECT
> 
dariox
  • 303
  • 2
  • 11