(define small-odd-swing (vector 1 1 1 3 3 15 5 35 35 315 63 693 231 3003 429 6435 6435 109395 12155 230945 46189 969969 88179 2028117 676039 16900975 1300075 35102025 5014575 145422675 9694845 300540195 300540195)) (define (swing n) (if (< n 33) (vector-ref small-odd-swing n) (let* ((primes (sieve (range 3 n #:by 2))) (rootn (integer-sqrt n)) (primesa (take-while (curryr <= rootn) primes)) (primesb (filter (λ (x) (odd? (quotient n x))) (take-while (curryr <= (quotient n 3)) (drop-while (curryr <= rootn) primes))))) (apply * (append (map (λ (prime) (do ((q (quotient n prime) (quotient q prime)) (p 1 (if (odd? q) (* p prime) p))) ((zero? q) p))) primesa) (take-while (curryr <= n) (drop-while (curryr <= (quotient n 2)) primes)) primesb))))) (define (rec-fact n) (if (< n 2) 1 (* (expt (rec-fact (quotient n 2)) 2) (swing n)))) (define (fact n) (if (< n 20) (Π values 1 n) (arithmetic-shift (rec-fact n) (- n (bitwise-bit-count n)))))