Abundant, deficient and perfect number classifications: Difference between revisions

Content added Content deleted
(Added Bracmat solution)
(→‎{{header|Racket}}: Much shorter code)
Line 568: Line 568:


=={{header|Racket}}==
=={{header|Racket}}==

We use use '''fold-divisors''' from [[Proper_divisors#Racket]].



<lang racket>#lang racket
<lang racket>#lang racket
(require "proper-divisors.rkt")
(require math)
(define (proper-divisors n) (drop-right (divisors n) 1))
(define SCOPE 20000)
(define classes '(deficient perfect abundant))
(define (classify n)
(list-ref classes (add1 (sgn (- (apply + (proper-divisors n)) n)))))


(let ([N 20000])
(define P
(let ((P-v (vector)))
(define t (make-hasheq))
(λ (n)
(for ([i (in-range 1 (add1 N))])
(set! P-v (fold-divisors P-v n 0 +))
(define c (classify i))
(vector-ref P-v n))))
(hash-set! t c (add1 (hash-ref t c 0))))
(printf "The range between 1 and ~a has:\n" N)

(for ([c classes]) (printf " ~a ~a numbers\n" (hash-ref t c 0) c)))</lang>
(define-values
(a d p)
(for/fold ((a 0) (d 0) (p 0))
((n (in-range SCOPE 0 -1))) ; doing this backwards initialises the memo
(match (- (P n) n)
[0 (values a d (add1 p))] ; perfect
[(? negative?) (values a (add1 d) p)] ; deficient
[(? positive?) (values (add1 a) d p)]))) ; abundant

(printf #<<EOS
Between 1 and ~s:
~a abundant numbers
~a deficient numbers
~a perfect numbers
EOS
SCOPE a d p)</lang>


{{out}}
{{out}}
<pre>
<pre>
Between 1 and 20000:
The range between 1 and 20000 has:
4953 abundant numbers
15043 deficient numbers
15043 deficient numbers
4 perfect numbers
4 perfect numbers
4953 abundant numbers
</pre>
</pre>