# 1ac3a8d6e4b2

`Use `losh:summation``
author Steve Losh Sat, 02 Dec 2017 13:10:23 -0500 acbb1860ce62 89b641f412c6 (none) 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))
;; (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```