1ac3a8d6e4b2

Use `losh:summation`
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 02 Dec 2017 13:10:23 -0500
parents acbb1860ce62
children 89b641f412c6
branches/tags (none)
files package.lisp src/problems.lisp src/utils.lisp

Changes

--- a/package.lisp	Tue Nov 28 18:19:38 2017 -0500
+++ b/package.lisp	Sat Dec 02 13:10:23 2017 -0500
@@ -5,7 +5,8 @@
     :losh
     :euler.quickutils)
   (:import-from :1am :is)
-  (:shadowing-import-from :1am :test))
+  (:shadowing-import-from :1am :test)
+  (:export :run-tests))
 
 (defpackage :euler.poker
   (:use
--- a/src/problems.lisp	Tue Nov 28 18:19:38 2017 -0500
+++ b/src/problems.lisp	Sat Dec 02 13:10:23 2017 -0500
@@ -76,9 +76,9 @@
   ;; Find the difference between the sum of the squares of the first one hundred
   ;; natural numbers and the square of the sum.
   (flet ((sum-of-squares (to)
-           (sum (irange 1 to :key #'square)))
+           (summation (irange 1 to :key #'square)))
          (square-of-sum (to)
-           (square (sum (irange 1 to)))))
+           (square (summation (irange 1 to)))))
     (abs (- (sum-of-squares 100) ; apparently it wants the absolute value
             (square-of-sum 100)))))
 
@@ -115,7 +115,7 @@
 (defun problem-10 ()
   ;; The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
   ;; Find the sum of all the primes below two million.
-  (sum (sieve 2000000)))
+  (summation (sieve 2000000)))
 
 (defun problem-11 ()
   ;; In the 20×20 grid below, four numbers along a diagonal line have been marked
@@ -366,8 +366,8 @@
            (silly-british-letters (n)
              (+ (letters n)
                 (if (has-british-and n) 0 3))))
-    (sum (irange 1 1000)
-         :key #'silly-british-letters)))
+    (summation (irange 1 1000)
+               :key #'silly-british-letters)))
 
 (defun problem-18 ()
   ;; By starting at the top of the triangle below and moving to adjacent numbers
@@ -452,7 +452,7 @@
   ;; 71 and 142; so d(284) = 220.
   ;;
   ;; Evaluate the sum of all the amicable numbers under 10000.
-  (sum (remove-if-not #'amicablep (range 1 10000))))
+  (summation (remove-if-not #'amicablep (range 1 10000))))
 
 (defun problem-22 ()
   ;; Using names.txt, a 46K text file containing over five-thousand first names,
@@ -470,10 +470,10 @@
                parse-strings-file
                (sort <> #'string<)))
            (name-score (name)
-             (sum name :key #'letter-number)))
+             (summation name :key #'letter-number)))
     (iterate (for (position . name) :in
                   (enumerate (read-names) :start 1))
-             (sum (* position (name-score name))))))
+             (summing (* position (name-score name))))))
 
 (defun problem-23 ()
   ;; A perfect number is a number for which the sum of its proper divisors is
@@ -502,7 +502,7 @@
              (iterate (for a :in-hashset abundant-numbers)
                       (when (hset-contains-p abundant-numbers (- n a))
                         (return t)))))
-      (sum (remove-if #'abundant-sum-p (irange 1 limit))))))
+      (summation (remove-if #'abundant-sum-p (irange 1 limit))))))
 
 (defun problem-24 ()
   ;; A permutation is an ordered arrangement of objects. For example, 3124 is
@@ -659,7 +659,7 @@
   (flet ((maximum-sum-for-digits (n)
            (* (expt 9 5) n))
          (digit-power-sum (n)
-           (sum (digits n) :key (rcurry #'expt 5))))
+           (summation (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.
@@ -723,7 +723,7 @@
                              #(1 2 3 4 5 6 7 8 9)
                              :copy nil))
       remove-duplicates
-      sum)))
+      summation)))
 
 (defun problem-33 ()
   ;; The fraction 49/98 is a curious fraction, as an inexperienced mathematician
@@ -773,8 +773,7 @@
   ;; Note: as 1! = 1 and 2! = 2 are not sums they are not included.
   (iterate
     (for n :from 3 :to 1000000)
-    ;; have to use funcall here because `sum` is an iterate keyword.  kill me.
-    (when (= n (funcall #'sum (digits n) :key #'factorial))
+    (when (= n (summation (digits n) :key #'factorial))
       (summing n))))
 
 (defun problem-35 ()
@@ -933,7 +932,7 @@
   ;; containing nearly two-thousand common English words, how many are triangle
   ;; words?
   (labels ((word-value (word)
-             (sum word :key #'letter-number))
+             (summation word :key #'letter-number))
            (triangle-word-p (word)
              (trianglep (word-value word))))
     (count-if #'triangle-word-p (parse-strings-file "data/042-words.txt"))))
@@ -967,7 +966,7 @@
                     (dividesp (extract3 digits 5) 11)
                     (dividesp (extract3 digits 6) 13)
                     (dividesp (extract3 digits 7) 17)))))
-    (sum (remove-if-not #'interestingp (pandigitals 0 9)))))
+    (summation (remove-if-not #'interestingp (pandigitals 0 9)))))
 
 (defun problem-44 ()
   ;; Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first
@@ -1075,7 +1074,7 @@
   ;; Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000.
   (-<> (irange 1 1000)
     (mapcar #'expt <> <>)
-    sum
+    summation
     (mod <> (expt 10 10))))
 
 (defun problem-49 ()
@@ -1361,7 +1360,7 @@
   (labels ((score (value)
              (if (primep value) 1 0))
            (primes-in-layer (size)
-             (sum (number-spiral-corners size) :key #'score)))
+             (summation (number-spiral-corners size) :key #'score)))
     (iterate
       (for size :from 3 :by 2)
       (for count :from 5 :by 4)
@@ -1421,7 +1420,7 @@
              length))
          (answer (keyword)
            ;; (pr (stringify keyword)) ; keyword is "god", lol
-           (sum (apply-cipher keyword))))
+           (summation (apply-cipher keyword))))
       (iterate (for-nested ((a :from (char-code #\a) :to (char-code #\z))
                             (b :from (char-code #\a) :to (char-code #\z))
                             (c :from (char-code #\a) :to (char-code #\z))))
@@ -1531,7 +1530,7 @@
                         (prev (car path))
                         (final (choose set path (suffix prev) (prefix init))))
                      (return-from problem-61
-                       (sum (reverse (cons (first final) path))))))))))
+                       (summation (reverse (cons (first final) path))))))))))
     (map-permutations #'search-sets
                       (list (numbers #'triangle)
                             (numbers #'square)
@@ -1693,7 +1692,7 @@
   ;; How many chains, with a starting number below one million, contain exactly
   ;; sixty non-repeating terms?
   (labels ((digit-factorial (n)
-             (sum (digits n) :key #'factorial))
+             (summation (digits n) :key #'factorial))
            (term-count (n)
              (iterate (for i :initially n :then (digit-factorial i))
                       (until (member i prev))
@@ -1884,7 +1883,7 @@
         (for (values reversible j) = (reversiblep i))
         (setf (aref done j) 1)
         (when reversible
-          (sum (if (= i j) 1 2)))))))
+          (summing (if (= i j) 1 2)))))))
 
 (defun problem-206 ()
   (declare (optimize speed))
@@ -1950,8 +1949,8 @@
                (logcount (logxor p c))))
            (transition (transition-function previous-digits current-digits)
              ;; The new digits will probably be shorter than the old digits.
-             (sum (mapcar-long transition-function nil
-                               previous-digits current-digits)))
+             (summation (mapcar-long transition-function nil
+                                     previous-digits current-digits)))
            (run-clock (seed)
              (iterate
                (for current :in-list (mapcar (rcurry #'digits :from-end t)
--- a/src/utils.lisp	Tue Nov 28 18:19:38 2017 -0500
+++ b/src/utils.lisp	Sat Dec 02 13:10:23 2017 -0500
@@ -239,19 +239,6 @@
     (string= s (reverse s))))
 
 
-(defun-inlineable sum (sequence &key key)
-  (iterate (for n :in-whatever sequence)
-           (sum (if key
-                  (funcall key n)
-                  n))))
-
-(defun-inlineable product (sequence &key key)
-  (iterate (for n :in-whatever sequence)
-           (multiplying (if key
-                          (funcall key n)
-                          n))))
-
-
 (defun-inlineable mutate (function list)
   "Destructively mutate each element of `list` in-place with `function`.
 
@@ -312,7 +299,7 @@
   If `proper` is given, only include the proper divisors (i.e. not `n` itself).
 
   "
-  (sum (unsorted-divisors n :proper proper)))
+  (summation (unsorted-divisors n :proper proper)))
 
 (defun product-of-divisors (n &key proper)
   ;; From *Recreations in the Theory of Numbers: The Queen of Mathematics