RosettaCodeData/Task/Aliquot-sequence-classifications/Racket/aliquot-sequence-classifications.rkt
2015-02-20 09:02:09 -05:00

53 lines
1.6 KiB
Racket

#lang racket
(require "proper-divisors.rkt" math/number-theory)
(define SCOPE 20000)
(define P
(let ((P-v (vector)))
(λ (n)
(cond
[(> n SCOPE)
(apply + (drop-right (divisors n) 1))]
[else
(set! P-v (fold-divisors P-v n 0 +))
(vector-ref P-v n)]))))
;; initialise P-v
(void (P SCOPE))
(define (aliquot-sequence-class K)
;; note that seq is reversed as a list, since we're consing
(define (inr-asc seq)
(match seq
[(list 0 _ ...)
(values "terminating" seq)]
[(list (== K) (== K) _ ...)
(values "perfect" seq)]
[(list n n _ ...)
(values (format "aspiring to ~a" n) seq)]
[(list (== K) ami (== K) _ ...)
(values (format "amicable with ~a" ami) seq)]
[(list (== K) cycle ... (== K))
(values (format "sociable length ~a" (add1 (length cycle))) seq)]
[(list n cycle ... n _ ...)
(values (format "cyclic on ~a length ~a" n (add1 (length cycle))) seq)]
[(list X _ ...)
#:when (> X 140737488355328)
(values "non-terminating big number" seq)]
[(list seq ...)
#:when (> (length seq) 16)
(values "non-terminating long sequence" seq)]
[(list seq1 seq ...) (inr-asc (list* (P seq1) seq1 seq))]))
(inr-asc (list K)))
(define (report-aliquot-sequence-class n)
(define-values (c s) (aliquot-sequence-class n))
(printf "~a:\t~a\t~a~%" n c (reverse s)))
(for ((i (in-range 1 10)))
(report-aliquot-sequence-class i))
(newline)
(for ((i (in-list '(11 12 28 496 220 1184 12496 1264460 790 909 562 1064 1488 15355717786080))))
(report-aliquot-sequence-class i))