
in the original GitHub fork: https://github.com/ntoronto/racket Some things about this are known to be broken (most egregious is that the array tests DO NOT RUN because of a problem in typed/rackunit), about half has no coverage in the tests, and half has no documentation. Fixes and docs are coming. This is committed now to allow others to find errors and inconsistency in the things that appear to be working, and to give the author a (rather incomplete) sense of closure.
270 lines
9.9 KiB
Racket
270 lines
9.9 KiB
Racket
#lang typed/racket
|
|
(require math/number-theory)
|
|
(require typed/rackunit)
|
|
|
|
; "quadratic.rkt"
|
|
(check-equal? (quadratic-solutions 1 0 -4) '(-2 2))
|
|
(check-equal? (quadratic-solutions 1 0 +4) '())
|
|
(check-equal? (quadratic-solutions 1 0 0) '(0))
|
|
(check-equal? (quadratic-integer-solutions 1 0 -4) '(-2 2))
|
|
(check-equal? (quadratic-integer-solutions 1 0 +4) '())
|
|
(check-equal? (quadratic-integer-solutions 1 0 0) '(0))
|
|
(check-equal? (quadratic-natural-solutions 1 0 -4) '(2))
|
|
(check-equal? (quadratic-natural-solutions 1 0 +4) '())
|
|
(check-equal? (quadratic-natural-solutions 1 0 0) '(0))
|
|
|
|
; "eulerian-number.rkt"
|
|
(check-equal? (map (λ: ([x : Natural]) (eulerian-number 5 x)) '(0 1 2 3 4))
|
|
'(1 26 66 26 1))
|
|
|
|
; "primitive-roots.rkt"
|
|
(check-equal? (unit-group 20) '(1 3 7 9 11 13 17 19)) ; 19 !!!!
|
|
(check-equal? (order 19 20) 2)
|
|
(check-equal? (order 3 20) 4)
|
|
(check-equal? (orders 20) '(1 4 4 2 2 4 4 2)) ; (order 3 20)=4, ...
|
|
(check-true (andmap exists-primitive-root? '(1 2 4 3 9 6 18)))
|
|
(check-false (ormap exists-primitive-root? '(8 16 12)))
|
|
(check-equal? (primitive-root 20) #f)
|
|
(check-equal? (primitive-root 10) 7) ; (length (unit-group 10)) = (order 7 10)
|
|
(check-true (primitive-root? 7 10))
|
|
(check-false (primitive-root? 7 20))
|
|
(check-equal? (primitive-roots 10) '(3 7))
|
|
(: find-and-check-root : Positive-Integer -> Boolean)
|
|
(define (find-and-check-root n)
|
|
(define r (primitive-root n))
|
|
(cond [(not r) #t]
|
|
[else (= (length (unit-group n)) (order r n))]))
|
|
(check-true (andmap find-and-check-root '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 78125)))
|
|
|
|
;"polygonal.rkt"
|
|
(check-equal? (map triangle '(0 1 2 3 4 5)) '(0 1 3 6 10 15))
|
|
(check-equal? (map pentagonal '(0 1 2 3 4 5)) '(0 1 5 12 22 35))
|
|
(check-equal? (map hexagonal '(0 1 2 3 4 5)) '(0 1 6 15 28 45))
|
|
(check-equal? (map heptagonal '(0 1 2 3 4 5)) '(0 1 7 18 34 55))
|
|
(check-equal? (map octagonal '(0 1 2 3 4 5)) '(0 1 8 21 40 65))
|
|
(check-true (andmap triangle? '(0 1 3 6 10 15)))
|
|
(check-true (andmap square? '(0 1 4 9 16 25)))
|
|
(check-true (andmap pentagonal? '(0 1 5 12 22 35)))
|
|
(check-true (andmap hexagonal? '(0 1 6 15 28 45)))
|
|
(check-true (andmap heptagonal? '(0 1 7 18 34 55)))
|
|
(check-true (andmap octagonal? '(0 1 8 21 40 65)))
|
|
|
|
; "farey.rkt"
|
|
(check-equal? (farey 5) '(0 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1))
|
|
(check-equal? (mediant 1/1 1/2) 2/3)
|
|
|
|
; "fibonacci.rkt"
|
|
(check-equal? (build-list 8 fibonacci) '(0 1 1 2 3 5 8 13))
|
|
(check-equal? (build-list 8 (make-fibonacci 2 1)) '(2 1 3 4 7 11 18 29))
|
|
(for*: ([a (in-range -5 6)]
|
|
[b (in-range -5 6)]
|
|
[mod (in-range 1 8)])
|
|
(check-equal? (build-list 20 (λ: ([n : Integer]) ((make-fibonacci/mod a b) n mod)))
|
|
(build-list 20 (λ: ([n : Integer]) (modulo ((make-fibonacci a b) n) mod)))))
|
|
|
|
; "partitions.rkt"
|
|
(check-equal? (map partition-count '(0 1 2 3 4 5 6 7 8 9 10))
|
|
'(1 1 2 3 5 7 11 15 22 30 42))
|
|
|
|
|
|
; "bernoulli.rkt"
|
|
(check-equal? (map bernoulli '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18))
|
|
'(1 -1/2 1/6 0 -1/30 0 1/42 0 -1/30 0 5/66 0 -691/2730 0 7/6 0 -3617/510 0 43867/798))
|
|
|
|
; "tangent-number.rkt"
|
|
(require typed/rackunit)
|
|
(check-equal? (map tangent-number '(1 3 5 7 9 11 13)) '(1 2 16 272 7936 353792 22368256))
|
|
(check-equal? (map tangent-number '(0 2 4 6 8 10)) '(0 0 0 0 0 0))
|
|
|
|
; "factorial.rkt"
|
|
(define fact-table-size 171)
|
|
(define simple-cutoff 244)
|
|
|
|
(: test-factorial : Integer -> Integer)
|
|
(define (test-factorial n)
|
|
(if (= n 0) 1 (* n (test-factorial (- n 1)))))
|
|
|
|
(check-equal? (map factorial (list 0 1 2 3 4 5)) '(1 1 2 6 24 120))
|
|
(check-equal? (factorial (+ fact-table-size 1)) (test-factorial (+ fact-table-size 1)))
|
|
(check-equal? (factorial (+ simple-cutoff 1)) (test-factorial (+ simple-cutoff 1)))
|
|
|
|
(check-equal? (binomial 10 3) 120)
|
|
(check-equal? (binomial 10 11) 0)
|
|
(check-equal? (binomial 10 0) 1)
|
|
(check-equal? (binomial 10 10) 1)
|
|
(check-equal? (binomial 10 1) 10)
|
|
(check-equal? (binomial 10 9) 10)
|
|
|
|
(check-equal? (permutations 10 3) 720)
|
|
(check-equal? (permutations 10 0) 1)
|
|
(check-equal? (permutations 10 10) 3628800)
|
|
(check-equal? (permutations 0 0) 1)
|
|
|
|
(check-equal? (multinomial 20 3 4 5 8) 3491888400)
|
|
|
|
; "binomial.rkt"
|
|
(check-equal? (binomial 10 3) 120)
|
|
(check-equal? (binomial 10 11) 0)
|
|
(check-equal? (binomial 10 0) 1)
|
|
(check-equal? (binomial 10 10) 1)
|
|
(check-equal? (binomial 10 1) 10)
|
|
(check-equal? (binomial 10 9) 10)
|
|
|
|
|
|
; "number-theory.rkt"
|
|
(check-true (divides? 2 12))
|
|
(check-false (divides? 2 13))
|
|
(check-true (divides? 2 0))
|
|
; (check-exn (divides? 0 2)) ?
|
|
|
|
(check-equal? (max-dividing-power 3 27) 3)
|
|
(check-equal? (max-dividing-power 3 (* 27 2)) 3)
|
|
|
|
(: list-dot : (Listof Integer) (Listof Integer) -> Integer)
|
|
(define (list-dot as bs)
|
|
(if (empty? as)
|
|
0
|
|
(+ (* (car as) (car bs)) (list-dot (cdr as) (cdr bs)))))
|
|
|
|
(: member? : (All (a) (a (Listof a) -> Boolean)))
|
|
(define (member? x xs)
|
|
(not (not (member x xs))))
|
|
|
|
(check-equal? ; 2*12-1*20 = 4 = gcd(12,20)
|
|
(list-dot '(12 20) (bezout 12 20)) (gcd 12 20))
|
|
(check-equal? (list-dot '(12 20) (bezout 12 20)) (gcd 12 20))
|
|
(check-equal? (list-dot '(20 16) (bezout 20 16)) (gcd 20 16))
|
|
(check-equal? (list-dot '(12 20 16) (bezout 12 20 16)) (gcd 12 20 16))
|
|
|
|
(check-true (coprime? (* 3 7) (* 5 19)))
|
|
(check-false (coprime? (* 3 7 5) (* 5 19 2)))
|
|
|
|
(check-true (pairwise-coprime? 10 7 33 13))
|
|
(check-false (pairwise-coprime? 10 7 33 14))
|
|
(check-false (pairwise-coprime? 6 10 15))
|
|
(check-true (coprime? 6 10 15))
|
|
(: check-inverse : Natural -> Boolean)
|
|
(define (check-inverse n)
|
|
(define m (and (coprime? n 20) (modular-inverse n 20)))
|
|
(cond [m (= (remainder (* n m) 20) 1)]
|
|
[else #t]))
|
|
(check-true (andmap check-inverse (build-list 20 (λ: ([x : Natural]) (+ x 1)))))
|
|
|
|
(check-equal? (solve-chinese '(2 3 2) '(3 5 7)) 23)
|
|
|
|
|
|
(check-equal? (divisors 12) '(1 2 3 4 6 12))
|
|
(check-equal? (divisors -12) '(1 2 3 4 6 12))
|
|
(check-equal? (divisors 0) '())
|
|
|
|
(check-equal? (next-primes -5 10) '(-3 -2 2 3 5 7 11 13 17 19))
|
|
(check-equal? (prev-primes 5 10) '(3 2 -2 -3 -5 -7 -11 -13 -17 -19))
|
|
(check-equal? (next-prime 0) 2)
|
|
(check-equal? (next-prime 1) 2)
|
|
(check-equal? (prev-prime 10) 7)
|
|
(check-equal? (prev-prime 8) 7)
|
|
(check-equal? (prev-prime 17) 13)
|
|
(check-equal? (nth-prime 0) 2)
|
|
(check-equal? (nth-prime 1) 3)
|
|
(check-equal? (nth-prime 2) 5)
|
|
|
|
|
|
(let ()
|
|
(: prime-sum : Integer Integer -> Integer)
|
|
(define (prime-sum start delta)
|
|
(define: s : Integer 0)
|
|
(for: ([i (in-range start (+ start delta 1))])
|
|
(set! s (+ s (next-prime i))))
|
|
s)
|
|
(check-equal? (prime-sum (expt 10 6) 1000) 1001511919) ; Sum[NextPrime[n], {n, 10^6, 10^6 + 1000}]
|
|
(check-equal? (prime-sum (expt 10 7) 1000) 10010514423) ; Sum[NextPrime[n], {n, 10^7, 10^7 + 1000}]
|
|
(check-equal? (prime-sum (expt 10 8) 1000) 100100519271) ; Sum[NextPrime[n], {n, 10^8, 10^8 + 1000}]
|
|
(check-equal? (prime-sum (expt 10 9) 1000) 1001000516807) ; Sum[NextPrime[n], {n, 10^9, 10^9 + 1000}]
|
|
)
|
|
|
|
#;(check-equal? 7472966967499
|
|
(let ()
|
|
; sum of the first million primes
|
|
(define: s : Integer 0)
|
|
(define: p : Integer 1)
|
|
(for: ([i (in-range 0 (expt 10 6))])
|
|
(when (zero? (remainder i 10000))
|
|
(newline)
|
|
(display i))
|
|
(when (zero? (remainder i 1000))
|
|
(display "."))
|
|
(set! p (next-prime p))
|
|
(set! s (+ s p)))
|
|
s))
|
|
|
|
(check-equal? (next-prime (expt 10 7)) 10000019)
|
|
(check-equal? (next-prime (expt 10 8)) 100000007)
|
|
(check-equal? (factorize (* 10000019 100000007)) '((10000019 1) (100000007 1)))
|
|
(: check-factorize : Natural -> Boolean)
|
|
(define (check-factorize n)
|
|
(= (defactorize (factorize n)) n))
|
|
(check-true (for/and: : Boolean ([n : Natural (in-range (expt 10 9) (+ (expt 10 9) 10000))])
|
|
(check-factorize n)))
|
|
|
|
(: check-as-power : Positive-Integer Natural Natural -> Boolean)
|
|
(define (check-as-power a r n)
|
|
(define-values (b e) (as-power a))
|
|
(and (= b r) (= e n)))
|
|
(check-true (check-as-power 27 3 3))
|
|
(check-true (check-as-power 28 28 1))
|
|
(check-true (check-as-power (* 5 5 7 7 7) (* 5 5 7 7 7) 1))
|
|
(check-true (check-as-power (* 5 5 7 7 7 7) 245 2))
|
|
|
|
(check-true (prime-power? (expt 3 7)))
|
|
(check-false (prime-power? (expt 12 7)))
|
|
|
|
(check-false (perfect-power? 3))
|
|
(check-true (perfect-power? 9))
|
|
(check-true (perfect-power? (expt 12 7)))
|
|
(check-false (perfect-power? (- (expt 12 7) 1)))
|
|
|
|
|
|
(check-equal? (moebius-mu (* 3 5 7 11)) 1)
|
|
(check-equal? (moebius-mu (* 3 5 7)) -1)
|
|
(check-equal? (moebius-mu (* 3 5 5 7)) 0)
|
|
|
|
(check-equal? (divisor-sum 1000) 2340)
|
|
(check-equal? (divisor-sum 1000 0) 16)
|
|
(check-equal? (divisor-sum 1000 1) 2340)
|
|
(check-equal? (divisor-sum 1000 2) 1383460)
|
|
|
|
(: check-integer-root : Natural Natural -> Boolean)
|
|
(define (check-integer-root a n)
|
|
(define r (integer-root a n))
|
|
(unless (and (<= (expt r n) a) (> (expt (+ r 1) n) a))
|
|
(displayln (list 'check-integer-root 'a a 'n n)))
|
|
(and (<= (expt r n) a) (> (expt (+ r 1) n) a)))
|
|
|
|
(for:([a : Natural (in-range (expt 10 9) (+ (expt 10 9) 10000))]
|
|
[n : Natural (in-range 2 5)])
|
|
(check-true (check-integer-root a n)))
|
|
|
|
; "quadratic-residues.rkt"
|
|
(check-equal? (quadratic-character 2 5) -1)
|
|
(check-equal? (quadratic-character 3 5) -1)
|
|
(check-equal? (quadratic-character 5 5) 0)
|
|
(check-equal? (quadratic-character 7 5) -1)
|
|
(check-equal? (quadratic-character 11 5) 1)
|
|
|
|
(check-true (quadratic-residue? 1 17))
|
|
(check-true (quadratic-residue? 2 17))
|
|
(check-true (quadratic-residue? 4 17))
|
|
(check-true (quadratic-residue? 8 17))
|
|
(check-true (quadratic-residue? 9 17))
|
|
(check-true (quadratic-residue? 13 17))
|
|
(check-true (quadratic-residue? 15 17))
|
|
(check-true (quadratic-residue? 16 17))
|
|
(check-false (quadratic-residue? 3 17))
|
|
(check-false (quadratic-residue? 5 17))
|
|
(check-false (quadratic-residue? 6 17))
|
|
(check-false (quadratic-residue? 7 17))
|
|
(check-false (quadratic-residue? 10 17))
|
|
(check-false (quadratic-residue? 11 17))
|
|
(check-false (quadratic-residue? 12 17))
|
|
(check-false (quadratic-residue? 14 17))
|