393d1f8dd754

Clean up
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 12 Oct 2017 21:29:54 -0400
parents 15e8fe451b4a
children cb34c7bc34fc
branches/tags (none)
files src/problems.lisp src/utils.lisp

Changes

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))))