# multiply perfect numbers

Find multiply perfect numbers.

``` \$ cat mpn.scm
(use-modules (srfi srfi-1))

(define (divides? a b)

; Return true iff a divides b

(= 0 (remainder b a)))

(define (factors n)

; Return a list of factors of n including n.

(let loop ((i 2) (max n) (factors (list 1 n)))
(if (<= max i)
factors
(if (divides? i n)
(let* ((j (quotient n i))
(new-factors (cons j factors)))
(loop (+ i 1) j
(if (= i j) new-factors (cons i new-factors))))
(loop (+ i 1) max factors)))))

(define (mpn n)

; Return a list of all the multiply perfect numbers at most n

(let loop ((i 6) (mp-nums '()))
(if (< n i)
mp-nums
(let ((m (fold-right + 0 (factors i))))
(loop (+ i 1)
(if (divides? i m) (cons i mp-nums) mp-nums))))))

\$ i=1 ; n=10 ; \
while (( i < 6 )) ; do
time guile -c "(load \"mpn.scm\") (write (mpn \$n))"
(( ++i ))
(( n *= 10 ))
done
(6)
real    0m0.037s
user    0m0.036s
sys     0m0.004s
(28 6)
real    0m0.032s
user    0m0.024s
sys     0m0.004s
(672 496 120 28 6)
real    0m0.072s
user    0m0.068s
sys     0m0.000s
(8128 672 496 120 28 6)
real    0m2.491s
user    0m2.488s
sys     0m0.000s
(32760 30240 8128 672 496 120 28 6)
real    3m28.512s
user    3m28.248s
sys     0m0.012s

\$
```