I am wondering how to write a function calculating the sum of proper divisors of a integer greater than 1.
(define (sum-of-proper-divisors n)
(cond
[(= n 1) 1]
[(= 0 (remainder n (sub1 n)))
(+ (remainder n (sub1 n)) (sum-of-proper-divisors (sub1 (sub1 n))))]
[else (sum-of-proper-divisors (sub1 n))]))
This is the code that I wrote, however, it does not work. It will never stop evaluating because it will always do n-1. And I don't know how to fix this. Also, there might be other problems. How to put the restriction that makes the function stop evaluating when the divisor becomes 1?
You're confusing the number n
whose divisors you want to find, with said divisors. Notice that n
never changes, what must be modified at each step is the current integer being tested (a possible divisor). For that you'll need to pass around two parameters:
(define (sum-of-proper-divisors n i)
(cond
[(= i 1) 1]
[(= (remainder n i) 0)
(+ i (sum-of-proper-divisors n (sub1 i)))]
[else (sum-of-proper-divisors n (sub1 i))]))
Call it like this, at the beginning i
must be one unit less than n
:
(sum-of-proper-divisors 10 9)
=> 8
If having two parameters bothers you there are several ways to pass a single parameter, for instance using a named let
:
(define (sum-of-proper-divisors n)
(let loop ((i (sub1 n)))
(cond
[(= i 1) 1]
[(= (remainder n i) 0)
(+ i (loop (sub1 i)))]
[else (loop (sub1 i))])))