# HG changeset patch # User Steve Losh # Date 1507858194 14400 # Node ID 393d1f8dd75487c1b3d7d0c4f296fff33e0b7606 # Parent 15e8fe451b4aa04441dfda771ddde04945663aeb Clean up diff -r 15e8fe451b4a -r 393d1f8dd754 src/problems.lisp --- a/src/problems.lisp Tue Oct 10 21:09:53 2017 -0400 +++ b/src/problems.lisp Thu Oct 12 21:29:54 2017 -0400 @@ -8,7 +8,7 @@ (iterate (for i :from 1 :below 1000) (when (or (dividesp i 3) (dividesp i 5)) - (sum i)))) + (summing i)))) (defun problem-2 () ;; Each new term in the Fibonacci sequence is generated by adding the previous @@ -21,7 +21,7 @@ (iterate (for n :in-fibonacci t) (while (<= n 4000000)) (when (evenp n) - (sum n)))) + (summing n)))) (defun problem-3 () ;; The prime factors of 13195 are 5, 7, 13 and 29. @@ -664,7 +664,7 @@ (flet ((maximum-sum-for-digits (n) (* (expt 9 5) n)) (digit-power-sum (n) - (sum (mapcar (rcurry #'expt 5) (digits n))))) + (sum (digits n) :key (rcurry #'expt 5)))) (iterate ;; We want to find a limit N that's bigger than the maximum possible sum ;; for its number of digits. @@ -814,7 +814,7 @@ (iterate (for i :from 1 :below 1000000) (when (and (palindromep i 10) (palindromep i 2)) - (sum i)))) + (summing i)))) (defun problem-37 () ;; The number 3797 has an interesting property. Being prime itself, it is @@ -836,7 +836,7 @@ (with count = 0) (for i :from 11 :by 2) (when (truncatablep i) - (sum i) + (summing i) (incf count)) (while (< count 11))))) @@ -1371,7 +1371,7 @@ (iterate (for size :from 3 :by 2) (for count :from 5 :by 4) - (sum (primes-in-layer size) :into primes) + (summing (primes-in-layer size) :into primes) (for ratio = (/ primes count)) (finding size :such-that (< ratio 1/10))))) @@ -1602,7 +1602,7 @@ (while (>= maximum-possible-digits power)) (finally (return power))))) (iterate (for n :from 1 :below (find-bound)) - (sum (score n))))) + (summing (score n))))) (defun problem-69 () ;; Euler's Totient function, φ(n) [sometimes called the phi function], is @@ -1699,7 +1699,7 @@ ;; How many chains, with a starting number below one million, contain exactly ;; sixty non-repeating terms? (labels ((digit-factorial (n) - (sum (mapcar #'factorial (digits n)))) + (sum (digits n) :key #'factorial)) (term-count (n) (iterate (for i :initially n :then (digit-factorial i)) (until (member i prev)) diff -r 15e8fe451b4a -r 393d1f8dd754 src/utils.lisp --- a/src/utils.lisp Tue Oct 10 21:09:53 2017 -0400 +++ b/src/utils.lisp Thu Oct 12 21:29:54 2017 -0400 @@ -340,10 +340,25 @@ i)))) -(defun factorial (n) +(defun factorial% (n) (iterate (for i :from 1 :to n) (multiplying i))) +(defun precompute-factorials (size) + (iterate + (with cache = (make-array size :element-type 'integer)) + (for i :from 0 :below size) + (setf (aref cache i) (factorial% i)) + (finally (return cache)))) + +(defparameter *factorial-cache-size* 2000) +(defparameter *factorial-cache* (precompute-factorials *factorial-cache-size*)) + +(defun factorial (n) + (if (< n *factorial-cache-size*) + (aref *factorial-cache* n) + (factorial% n))) + (defun perfectp (n) (= n (sum (proper-divisors n))))