summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2021-12-22 18:34:27 +0100
committerYann Herklotz <git@yannherklotz.com>2021-12-22 18:34:27 +0100
commit310d8d21bfc8a024c9a469a1f39a2370008fd9ea (patch)
tree3a74bb424c2ffd1be2b8c59cf0dc36316e560760
parent8572c23e969af73092fe99a0e89b4f94159cb032 (diff)
downloadaoc21-310d8d21bfc8a024c9a469a1f39a2370008fd9ea.tar.gz
aoc21-310d8d21bfc8a024c9a469a1f39a2370008fd9ea.zip
Add day 5 to aoc
-rw-r--r--src/04.lisp3
-rw-r--r--src/05.lisp83
-rw-r--r--src/common.lisp5
-rw-r--r--test/05.lisp6
-rw-r--r--top.lisp3
5 files changed, 95 insertions, 5 deletions
diff --git a/src/04.lisp b/src/04.lisp
index 33436c2..4bbdd60 100644
--- a/src/04.lisp
+++ b/src/04.lisp
@@ -1,5 +1,4 @@
(use-package 'cl-ppcre)
-(use-package 'cl-utilities)
(use-package 'trivia)
(defun 04/parse-input-direct (input)
@@ -7,7 +6,7 @@
(boards (mapcar (lambda (x) (mapcar (lambda (y)
(mapcar (lambda (z)
(list (parse-integer z) nil)) (split " +" (trim y)))) x))
- (split-sequence-if (lambda (x) (equalp x "")) (cddr input)))))
+ (cl-utilities:split-sequence-if (lambda (x) (equalp x "")) (cddr input)))))
(list in-list boards)))
(defun 04/parse-input (input-file)
diff --git a/src/05.lisp b/src/05.lisp
new file mode 100644
index 0000000..607b290
--- /dev/null
+++ b/src/05.lisp
@@ -0,0 +1,83 @@
+(use-package 'cl-ppcre)
+(use-package 'trivia)
+
+(defun 05/parse-input-direct (input)
+ (mapcar (lambda (i)
+ (map 'list #'parse-integer
+ (multiple-value-bind (a b)
+ (scan-to-strings "(.*),(.*) -> (.*),(.*)" i) b)))
+ input))
+
+(defun max-coord (c1 c2)
+ (match (list c1 c2)
+ ((list (list x1 y1) (list x2 y2))
+ (list (max x1 x2) (max y1 y2)))))
+
+(defun find-max (l)
+ (fold-left #'max-coord '(0 0)
+ (mapcar
+ (lambda (x)
+ (match x
+ ((list x1 y1 x2 y2)
+ (list (max x1 x2) (max y1 y2))))) l)))
+
+(defun 05/parse-input (input-file)
+ (05/parse-input-direct (get-file-lines input-file)))
+
+(defun draw-line-x (arr y x1 x2)
+ (let ((nx1 (min x1 x2))
+ (nx2 (max x1 x2)))
+ (loop :for x :from nx1 :to nx2
+ :do (incf (aref arr y x)))))
+
+(defun draw-line-y (arr x y1 y2)
+ (let ((ny1 (min y1 y2))
+ (ny2 (max y1 y2)))
+ (loop :for y :from ny1 :to ny2
+ :do (incf (aref arr y x)))))
+
+(defun draw-line-diag (arr x1 y1 x2 y2)
+ (if (< x1 x2)
+ (if (< y1 y2)
+ (loop for y from y1 upto y2
+ for x from x1 upto x2
+ do (incf (aref arr y x)))
+ (loop for y from y1 downto y2
+ for x from x1 upto x2
+ do (incf (aref arr y x))))
+ (if (< y1 y2)
+ (loop for y from y1 upto y2
+ for x from x1 downto x2
+ do (incf (aref arr y x)))
+ (loop for y from y1 downto y2
+ for x from x1 downto x2
+ do (incf (aref arr y x))))))
+
+(defun draw-line (b arr coords)
+ (match coords
+ ((list x1 y1 x2 y2)
+ (if (equalp x1 x2)
+ (draw-line-y arr x1 y1 y2)
+ (if (equalp y1 y2) (draw-line-x arr y1 x1 x2)
+ (when b (draw-line-diag arr x1 y1 x2 y2)))))))
+
+(defun 2d-array-to-list (array)
+ (loop for i below (array-dimension array 0)
+ collect (loop for j below (array-dimension array 1)
+ collect (aref array i j))))
+
+(defun 05/part-a (parsed-input)
+ (let ((lines (make-array (match (mapcar #'1+ (find-max parsed-input)) ((list a b) (list b a)))))
+ (overlapping 0))
+ (loop for x in parsed-input do (draw-line nil lines x))
+ (mapcar (lambda (x) (mapcar (lambda (y) (when (> y 1) (incf overlapping))) x))
+ (2d-array-to-list lines))
+ overlapping))
+
+(defun 05/part-b (parsed-input)
+ (let ((lines (make-array (match (mapcar #'1+ (find-max parsed-input)) ((list a b) (list b a)))))
+ (overlapping 0))
+ (loop for x in parsed-input do (draw-line t lines x))
+ (mapcar (lambda (x) (mapcar (lambda (y) (when (> y 1) (incf overlapping))) x))
+ (2d-array-to-list lines))
+ overlapping))
diff --git a/src/common.lisp b/src/common.lisp
index 2c56184..c9e6e8b 100644
--- a/src/common.lisp
+++ b/src/common.lisp
@@ -15,3 +15,8 @@
(defun trim (input)
(string-trim '(#\Space #\Newline #\Backspace #\Tab
#\Linefeed #\Page #\Return #\Rubout) input))
+
+(defun fold-left (reducer initial list)
+ (loop for fold = initial then (funcall reducer fold element)
+ for element in list
+ finally (return fold)))
diff --git a/test/05.lisp b/test/05.lisp
index 8a717d0..4aa8883 100644
--- a/test/05.lisp
+++ b/test/05.lisp
@@ -20,14 +20,14 @@
(deftest 05/test-ex-b (05/aoc)
(let ((result (05/part-b (05/parse-input-direct 05/default-input))))
- (assert-equalp 0 result)))
+ (assert-equalp 12 result)))
(deftest 05/test-a (05/aoc)
(let ((result (05/part-a (05/parse-input "inputs/05.txt"))))
- (assert-equalp 0 result)))
+ (assert-equalp 7380 result)))
(deftest 05/test-b (05/aoc)
(let ((result (05/part-b (05/parse-input "inputs/05.txt"))))
- (assert-equalp 0 result)))
+ (assert-equalp 21373 result)))
(defun 05/run-tests () (run-suite '05/aoc))
diff --git a/top.lisp b/top.lisp
index 8a6ff40..73b1825 100644
--- a/top.lisp
+++ b/top.lisp
@@ -27,4 +27,7 @@
(load "src/04.lisp")
(load "test/04.lisp")
+(load "src/05.lisp")
+(load "test/05.lisp")
+
(defun run-all () (clunit:run-suite 'aoc))