# HG changeset patch # User Steve Losh # Date 1512238223 18000 # Node ID 1ac3a8d6e4b2a129614d1989b888a9564c657612 # Parent acbb1860ce620e0cc214fb48bf13f6e4d5f0db61 Use `losh:summation` diff -r acbb1860ce62 -r 1ac3a8d6e4b2 package.lisp --- 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 diff -r acbb1860ce62 -r 1ac3a8d6e4b2 src/problems.lisp --- 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) diff -r acbb1860ce62 -r 1ac3a8d6e4b2 src/utils.lisp --- 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