--- a/.lispwords Sun Dec 01 11:39:22 2019 -0500
+++ b/.lispwords Sun Dec 01 12:07:01 2019 -0500
@@ -1,1 +1,2 @@
(1 let-complex)
+(3 define-problem)
--- a/package.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/package.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -2,7 +2,6 @@
(:use :cl :losh :iterate :advent.quickutils)
(:export
:define-problem
- :define-problem-tests
:read-all
:read-lines
--- a/src/2017/day-01.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2017/day-01.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -2,7 +2,7 @@
(in-package :advent/2017/01)
-(define-problem (2017 1) (data read-line)
+(define-problem (2017 1) (data read-line) (1049 1508)
(iterate
(with digits = (map 'vector #'digit-char-p data))
(for digit :in-vector digits)
@@ -13,7 +13,3 @@
(when (= digit next) (sum digit :into part2))
(finally (return (values part1 part2)))))
-(1am:test test-2017/01
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 1049 part1))
- (1am:is (= 1508 part2))))
--- a/src/2017/day-02.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2017/day-02.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -14,14 +14,10 @@
(multiple-value-bind (lo hi) (extrema #'< row)
(- hi lo)))
-(define-problem (2017 2) (data read-lines-of-numbers-and-garbage)
+(define-problem (2017 2) (data read-lines-of-numbers-and-garbage) (53460 282)
(iterate
(for row :in data)
(summing (checksum row) :into part1)
(summing (find-quotient row) :into part2)
(finally (return (values part1 part2)))))
-(1am:test test-2017/02
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 53460 part1))
- (1am:is (= 282 part2))))
--- a/src/2017/day-03.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2017/day-03.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -19,7 +19,7 @@
(iterate (for (dx dy) :within-radius 1 :skip-origin t)
(collect (+ coord (complex dx dy)))))
-(define-problem (2017 3) (data read)
+(define-problem (2017 3) (data read) (552 330785)
(values
(manhattan-distance #c(0 0) (advent/spiral:number-coordinates data))
(iterate
@@ -31,7 +31,4 @@
(finding value :such-that (> value data))
(setf (gethash coord memory) value))))
-(1am:test test-2017/03
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 552 part1))
- (1am:is (= 330785 part2))))
+
--- a/src/2017/day-04.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2017/day-04.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -29,7 +29,7 @@
(string= (sort (copy-seq string1) #'char<)
(sort (copy-seq string2) #'char<)))
-(define-problem (2017 4) (data read-lines-of-words)
+(define-problem (2017 4) (data read-lines-of-words) (337 231)
(values (count-if (lambda (phrase)
(not (contains-duplicates-p phrase :test #'equal)))
data)
@@ -38,8 +38,3 @@
data)))
-(1am:test test-2017/04
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 337 part1))
- (1am:is (= 231 part2))))
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/2017/day-05.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -0,0 +1,25 @@
+(defpackage :advent/2017/05 #.cl-user::*advent-use*)
+(in-package :advent/2017/05)
+
+(defun fresh-simple-vector (sequence)
+ (if (typep sequence 'simple-vector)
+ (copy-seq sequence)
+ (coerce sequence 'simple-vector)))
+
+(defun compute (data modification-function)
+ (iterate
+ (with maze = (fresh-simple-vector data))
+ (with bound = (1- (length maze)))
+ (with address = 0)
+ (while (<= 0 address bound))
+ (counting t)
+ (for offset = (aref maze address))
+ (callf (aref maze address) modification-function)
+ (incf address offset)))
+
+(define-problem (2017 5) (data read-all) (342669 25136209)
+ (values
+ (compute data #'1+)
+ (compute data (lambda (value) (+ value (if (>= value 3) -1 1))))))
+
+
--- a/src/2018/day-01.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-01.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -2,7 +2,7 @@
(in-package :advent/2018/01)
-(define-problem (2018 1) (data read-all)
+(define-problem (2018 1) (data read-all) (522 73364)
(values
(summation data)
(progn
@@ -14,8 +14,3 @@
(if (hset-contains-p seen frequency)
(return frequency)
(hset-insert! seen frequency))))))
-
-(1am:test test-2018/01
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 522 part1))
- (1am:is (= 73364 part2))))
--- a/src/2018/day-02.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-02.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -2,7 +2,7 @@
(in-package :advent/2018/02)
-(define-problem (2018 2) (data read-lines)
+(define-problem (2018 2) (data read-lines) (8296 "pazvmqbftrbeosiecxlghkwud")
(values
(let* ((freqs (mapcar #'frequencies data))
(counts (mapcar #'hash-table-values freqs)))
@@ -18,8 +18,3 @@
(let ((i (mismatch a b)))
(str:concat (subseq a 0 i)
(subseq a (1+ i)))))))
-
-(1am:test test-2018/02
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 8296 part1))
- (1am:is (string= "pazvmqbftrbeosiecxlghkwud" part2))))
--- a/src/2018/day-03.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-03.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -34,7 +34,7 @@
fabric))
-(define-problem (2018 3) (data read-lines)
+(define-problem (2018 3) (data read-lines) (107663 1166)
(let* ((claims (mapcar #'parse-claim data))
(fabric (make-fabric claims)))
(values
@@ -42,8 +42,3 @@
(counting (> uses 1)))
(claim-id (first (unique claims :test #'claims-intersect-p))))))
-(1am:test test-2018/03
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 107663 part1))
- (1am:is (= 1166 part2))))
-
--- a/src/2018/day-04.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-04.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -41,7 +41,7 @@
(finally (return result))))
-(define-problem (2018 4) (data read-lines)
+(define-problem (2018 4) (data read-lines) (143415 49944)
(let ((guard-histograms (-<> data
(sort <> #'string<)
(mapcar #'parse-line <>)
@@ -65,8 +65,3 @@
sleepy-guard-preferred-minute)
(* predictable-guard
predictable-guard-time)))))
-
-(1am:test test-2018/04
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 143415 part1))
- (1am:is (= 49944 part2))))
--- a/src/2018/day-05.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-05.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -13,6 +13,7 @@
(coerce (nreverse result) 'string))
(define-problem (2018 5) (data alexandria:read-stream-content-into-string)
+ (10708 5330)
(deletef data #\newline)
(values
(length (react data))
@@ -20,9 +21,3 @@
(for unit :in-vector (remove-duplicates data :test #'char-equal))
(for candidate = (react (remove unit data :test #'char-equal)))
(minimizing (length candidate)))))
-
-
-(1am:test test-2018/05
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 10708 part1))
- (1am:is (= 5330 part2))))
--- a/src/2018/day-06.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-06.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -12,7 +12,7 @@
(1 (car results))
(t nil))))
-(define-problem (2018 6) (data read-lines)
+(define-problem (2018 6) (data read-lines) (3420 46667)
(let* ((coordinates (mapcar #'parse-line data))
(xs (mapcar #'realpart coordinates))
(ys (mapcar #'imagpart coordinates))
@@ -42,9 +42,3 @@
(for point = (complex x y))
(for total-distance = (summation coordinates :key (curry #'manhattan-distance point)))
(counting (< total-distance 10000))))))
-
-
-(1am:test test-2018/06
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 3420 part1))
- (1am:is (= 46667 part2))))
--- a/src/2018/day-07.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-07.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -31,7 +31,7 @@
(setf worker nil))))))
-(define-problem (2018 7) (data read-lines)
+(define-problem (2018 7) (data read-lines) ("BFGKNRTWXIHPUMLQVZOYJACDSE" 1163)
(values
(let ((graph (make-graph (mapcar #'parse-line data))))
;; (digraph.dot:draw graph)
@@ -59,9 +59,3 @@
(setf worker (cons task (task-length task))))))
(when (and (emptyp graph) (every #'null workers))
(return elapsed)))))
-
-
-(1am:test test-2018/07
- (multiple-value-bind (part1 part2) (run)
- (1am:is (string= "BFGKNRTWXIHPUMLQVZOYJACDSE" part1))
- (1am:is (= 1163 part2))))
--- a/src/2018/day-08.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-08.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -24,16 +24,10 @@
(when (array-in-bounds-p children index)
(summing (node-value (aref children index)))))))
-(define-problem (2018 8) (data)
+(define-problem (2018 8) (data) (37905 33891)
(let ((root (read-node data)))
(values
(recursively ((node root))
(+ (summation (metadata node))
(summation (children node) :key #'recur)))
(node-value root))))
-
-
-(1am:test test-2018/08
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 37905 part1))
- (1am:is (= 33891 part2))))
--- a/src/2018/day-09.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-09.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -27,13 +27,8 @@
(define-problem (2018 9) (data alexandria:read-stream-content-into-string)
+ (398730 3349635509)
(multiple-value-bind (players marbles) (parse-input data)
#+sbcl (sb-ext:gc :full t)
(values (play players marbles)
(play players (* marbles 100)))))
-
-
-(1am:test test-2018/09
- (multiple-value-bind (part1 part2) (run)
- (1am:is (= 398730 part1))
- (1am:is (= 3349635509 part2))))
--- a/src/2018/day-10.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-10.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -41,6 +41,7 @@
(map nil #'write-line field))))
(define-problem (2018 10) (data read-lines-of-numbers-and-garbage)
+ () ;; This can't really be tested automatically :(
(iterate
(with stars = (mapcar #'parse-line data))
(with ticks = 0)
@@ -52,7 +53,3 @@
(draw stars)
(until (string= "q" (read-line)))
(tick stars)))
-
-(1am:test test-2018/10
- ;; This can't really be tested automatically :(
- (values))
--- a/src/2018/day-11.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-11.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -21,7 +21,7 @@
(nth-digit 2 <>)
(- <> 5)))
-(define-problem (2018 11) (serial-number read)
+(define-problem (2018 11) (serial-number read) ("245,14" "235,206,13")
(let ((totals (make-array (list 300 300))))
(flet ((gref (x y)
(let ((x (1- x))
@@ -56,9 +56,3 @@
(for (x y power) = (largest-square n))
(finding (format nil "~D,~D,~D" x y n)
:maximizing power)))))))
-
-
-(1am:test test-2018/11
- (multiple-value-bind (part1 part2) (run)
- (1am:is (string= "245,14" part1))
- (1am:is (string= "235,206,13" part2))))
--- a/src/2018/day-12.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-12.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -107,6 +107,7 @@
pots))))
(define-problem (2018 12) (data)
+ () ;; can't really test noninteractively :(
(multiple-value-bind (pots rules) (read-problem data)
(values
(progn
@@ -127,11 +128,3 @@
(starting-value 7508)
(ticks (- 50000000000 starting-tick)))
(+ starting-value (* score-per-tick ticks))))
-
-
-;;;; Test ---------------------------------------------------------------------
-(1am:test test-2018/12
- ;; can't really test noninteractively :(
- ;; (multiple-value-bind (part1) (run)
- ;; (1am:is (= 1733 part1)))
- (values))
--- a/src/2018/day-13.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-13.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -202,11 +202,6 @@
(-<> carts hash-table-values first cart-position format-position)
:such-that (= 1 carts-remaining))))))
-(define-problem (2018 13) (data read-lines)
+(define-problem (2018 13) (data read-lines) ("83,49" "73,36")
(values (part-1 data)
(part-2 data)))
-
-(1am:test test-2018/13
- (multiple-value-bind (part1 part2) (run)
- (1am:is (string= "83,49" part1))
- (1am:is (string= "73,36" part2))))
--- a/src/2018/day-14.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-14.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -12,7 +12,7 @@
(defun format-output (scores)
(str:join "" (coerce scores 'list)))
-(define-problem (2018 14) (data read)
+(define-problem (2018 14) (data read) ("3610281143" 20211326)
#+sbcl (sb-ext:gc :full t)
(iterate
(with recipes = (make-array 2
@@ -43,8 +43,3 @@
(move-elves recipes elves)
(finally (return (values part-1 part-2)))))
-
-(1am:test test-2018/14
- (multiple-value-bind (part1 part2) (run)
- (1am:is (string= "3610281143" part1))
- (1am:is (= 20211326 part2))))
--- a/src/2018/day-15.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2018/day-15.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -250,11 +250,6 @@
(values))
-(define-problem (2018 15) (data read-lines)
+(define-problem (2018 15) (data read-lines) ()
(generate-world data)
(print-world))
-
-;; (1am:test test-2018/15
-;; (multiple-value-bind (part1 part2) (run)
-;; (1am:is (string= "3610281143" part1))
-;; (1am:is (= 20211326 part2))))
--- a/src/2019/day-01.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/2019/day-01.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -11,8 +11,7 @@
(summing fuel)
(until (zerop fuel))))
-(define-problem (2019 1) (data read-all)
+(define-problem (2019 1) (data read-all) (3464458 5193796)
(values (summation data :key #'fuel-required)
(summation data :key #'complete-fuel-required)))
-(define-problem-tests (2019 1) 3464458 1)
--- a/src/utils.lisp Sun Dec 01 11:39:22 2019 -0500
+++ b/src/utils.lisp Sun Dec 01 12:07:01 2019 -0500
@@ -27,21 +27,35 @@
;;;; Problems -----------------------------------------------------------------
+(defmacro define-problem-tests ((year day) part1 part2)
+ `(1am:test ,(alexandria:symbolicate 'test-
+ (princ-to-string year)
+ '/
+ (princ-to-string day))
+ (multiple-value-bind (part1 part2) (,(alexandria:symbolicate 'run))
+ (1am:is (equal ,part1 part1))
+ (1am:is (equal ,part2 part2)))))
+
(defmacro define-problem ((year day)
(arg &optional (reader 'identity))
+ (&optional answer1 answer2)
&body body)
(multiple-value-bind (body declarations docstring)
(alexandria:parse-body body :documentation t)
(with-gensyms (file)
(let ((run (symb 'run)))
- `(defun ,run (&optional ,arg)
- ,@(when docstring (list docstring))
- ,@declarations
- (let ((,file (unless ,arg (open (problem-data-path ,year ,day)))))
- (unwind-protect
- (progn (setf ,arg (,reader (ensure-stream (or ,arg ,file))))
- ,@body)
- (when ,file (close ,file)))))))))
+ `(progn
+ (defun ,run (&optional ,arg)
+ ,@(when docstring (list docstring))
+ ,@declarations
+ (let ((,file (unless ,arg (open (problem-data-path ,year ,day)))))
+ (unwind-protect
+ (progn (setf ,arg (,reader (ensure-stream (or ,arg ,file))))
+ ,@body)
+ (when ,file (close ,file)))))
+ ,@(when answer1
+ (list `(define-problem-tests (,year ,day) ,answer1 ,answer2)))
+ 'run)))))
(defun problem-data-path (year day)
(make-pathname
@@ -49,14 +63,6 @@
:name (format nil "~2,'0D" day)
:type "txt"))
-(defmacro define-problem-tests ((year day) part1 part2)
- `(1am:test ,(alexandria:symbolicate 'test-
- (princ-to-string year)
- '/
- (princ-to-string day))
- (multiple-value-bind (part1 part2) (,(alexandria:symbolicate 'run))
- (1am:is (= ,part1 part1))
- (1am:is (= ,part2 part2)))))
;;;; Readers ------------------------------------------------------------------