888f5c30c949

Enhance the sum/prod macros

Why not?
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Mon, 20 Jan 2020 14:19:26 -0500
parents 8f6ef53eac55
children 0a5694fe577c
branches/tags (none)
files src/problems/aspc.lisp src/utils.lisp

Changes

--- a/src/problems/aspc.lisp	Mon Jan 20 13:41:09 2020 -0500
+++ b/src/problems/aspc.lisp	Mon Jan 20 14:19:26 2020 -0500
@@ -5,9 +5,8 @@
 (define-problem aspc (data stream) "6 3" "42"
   (let ((n (read data))
         (m (read data)))
-    (iterate
-      (for k :from m :to n)
-      (u:summing* (u:binomial-coefficient n k) :modulo 1000000))))
+    (u:Σ (k m n :modulo 1000000)
+      (u:binomial-coefficient n k))))
 
 
 #; Scratch --------------------------------------------------------------------
--- a/src/utils.lisp	Mon Jan 20 13:41:09 2020 -0500
+++ b/src/utils.lisp	Mon Jan 20 14:19:26 2020 -0500
@@ -178,7 +178,7 @@
            (multiplying i)))
 
 
-(defmacro do-sum ((var from to) &body body)
+(defmacro do-sum ((var from to &key (initial-value 0) modulo) &body body)
   "Sum `body` with `var` iterating over `[from, to]`.
 
   It's just Σ:
@@ -193,13 +193,16 @@
 
   "
   (once-only (to)
-    (with-gensyms (result)
+    (with-gensyms (result mod)
       `(do ((,var ,from (1+ ,var))
-            (,result 0))
+            ,@(when modulo `((,mod ,modulo)))
+            (,result ,initial-value))
          ((> ,var ,to) ,result)
-         (incf ,result (progn ,@body))))))
+         ,(if modulo
+            `(setf ,result (mod (+ ,result (progn ,@body)) ,mod))
+            `(incf ,result (progn ,@body)))))))
 
-(defmacro do-product ((var from to) &body body)
+(defmacro do-product ((var from to &key (initial-value 1) modulo) &body body)
   "Multiply `body` with `var` iterating over `[from, to]`.
 
   It's just Π:
@@ -213,11 +216,15 @@
 
   "
   (once-only (to)
-    (with-gensyms (result)
+    (with-gensyms (result mod)
       `(do ((,var ,from (1+ ,var))
-            (,result 1))
+            ,@(when modulo `((,mod ,modulo)))
+            (,result ,initial-value))
          ((> ,var ,to) ,result)
-         (setf ,result (* ,result (progn ,@body)))))))
+         (setf ,result
+               ,(if modulo
+                  `(mod (* ,result (progn ,@body)) ,mod)
+                  `(* ,result (progn ,@body))))))))
 
 
 (defmacro Σ (bindings &body body) ;; lol