
renamed `partition-count' to `partitions' to be consistent with `permutations', and gave better examples in `multinomial' docs * (flulp-error +inf.0 +nan.0) was returning +nan.0 instead of +inf.0 * Type of `multinomial' didn't match its docs or `flmultinomial' * Reworded docs for `diagonal-array' * Reworked/reordered quite a few things in docs for `math/bigfloat' * Fixed first identity given in `gamma-inc' docs * Fixed descrption for `+max.0', etc.
41 lines
1.3 KiB
Racket
41 lines
1.3 KiB
Racket
#lang typed/racket/base
|
|
|
|
(require racket/flonum
|
|
"../../base.rkt"
|
|
"../vector/vector.rkt"
|
|
"types.rkt")
|
|
|
|
(provide partitions)
|
|
|
|
(define num-global-ps 200)
|
|
(: global-ps (Vectorof Natural))
|
|
(define global-ps (make-vector num-global-ps 0))
|
|
(vector-set! global-ps 0 1)
|
|
|
|
(: partitions : Integer -> Natural)
|
|
; http://en.wikipedia.org/wiki/Partition_(number_theory)
|
|
(define (partitions n)
|
|
(define: local-ps : (Vectorof Natural)
|
|
(make-vector (max 0 (- (+ n 1) num-global-ps)) 0))
|
|
|
|
(: ps-ref! (Integer (-> Natural) -> Natural))
|
|
(define (ps-ref! n thnk)
|
|
(cond [(n . < . num-global-ps)
|
|
(vector-ref! global-ps n thnk exact-zero?)]
|
|
[else
|
|
(vector-ref! local-ps (- n num-global-ps) thnk exact-zero?)]))
|
|
|
|
(let: loop : Natural ([n : Integer n])
|
|
(cond [(< n 0) 0]
|
|
[(= n 0) 1]
|
|
[else
|
|
(ps-ref!
|
|
n (λ ()
|
|
(define m (/ (+ 1.0 (flsqrt (+ 1.0 (* 24.0 n)))) 6.0))
|
|
(assert
|
|
(for/fold: ([sum : Integer 0]) ([k (in-range 1 (add1 (exact-floor m)))])
|
|
(+ sum (* (if (odd? k) 1 -1)
|
|
(+ (loop (- n (quotient (* k (- (* 3 k) 1)) 2)))
|
|
(loop (- n (quotient (* k (+ (* 3 k) 1)) 2)))))))
|
|
natural?)))])))
|