From 475d382b0baaa085910d6066d3a51943e777b147 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 22 Dec 2021 15:02:02 +0100 Subject: Pass the 4th day in AOC --- src/03.lisp | 9 ++------ src/04.lisp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/common.lisp | 15 ++++++++++++++ test/04.lisp | 6 +++--- top.lisp | 7 ++++++- 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 src/04.lisp diff --git a/src/03.lisp b/src/03.lisp index a9cd314..2a4b2fa 100644 --- a/src/03.lisp +++ b/src/03.lisp @@ -10,11 +10,6 @@ (defun 03/parse-input (input-file) (03/parse-input-direct (get-file-lines input-file))) -;; Loops through two item windows on input and counts each time the first is less than the second -(defun 03/partial (func &rest args1) - (lambda (&rest args2) - (apply func (append args1 args2)))) - (defun 03/is-more (h l) (mapcar (lambda (x) (if (< x h) 0 1)) l)) @@ -29,11 +24,11 @@ (defun 03/find-most-common (parsed-input) (let ((half-length (/ (list-length parsed-input) 2))) - (03/is-more half-length (apply (03/partial #'mapcar #'+) parsed-input)))) + (03/is-more half-length (apply (partial #'mapcar #'+) parsed-input)))) (defun 03/find-least-common (parsed-input) (let ((half-length (/ (list-length parsed-input) 2))) - (03/is-less half-length (apply (03/partial #'mapcar #'+) parsed-input)))) + (03/is-less half-length (apply (partial #'mapcar #'+) parsed-input)))) (defun 03/part-a (parsed-input) (let* ((l (03/find-most-common parsed-input)) diff --git a/src/04.lisp b/src/04.lisp new file mode 100644 index 0000000..33436c2 --- /dev/null +++ b/src/04.lisp @@ -0,0 +1,64 @@ +(use-package 'cl-ppcre) +(use-package 'cl-utilities) +(use-package 'trivia) + +(defun 04/parse-input-direct (input) + (let ((in-list (mapcar #'parse-integer (split "," (car input)))) + (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))))) + (list in-list boards))) + +(defun 04/parse-input (input-file) + (04/parse-input-direct (get-file-lines input-file))) + +(defun 04/update-board (num board) + (mapcar (lambda (row) + (mapcar (lambda (val) + (if (equalp num (car val)) (list (car val) t) val)) + row)) + board)) + +(defun rotate (list-of-lists) + (apply #'mapcar #'list list-of-lists)) + +(defun 04/check-rows (row) (every #'cadr row)) + +(defun 04/check-board (board) + (if (or (some #'04/check-rows board) + (some #'04/check-rows (rotate board))) + board nil)) + +;; (04/check-board '(((2 t) (3 nil)) ((2 nil) (3 t)))) +;; ==> nil + +(defun 04/to-val (v) (if (cadr v) 0 (car v))) + +(defun 04/sum-unmarked (board) + (apply #'+ (mapcar (compose + (partial #'apply #'+) + (partial #'mapcar #'04/to-val)) + board))) + +(defun 04/part-a (parsed-input) + (let ((inputs (car parsed-input)) + (boards (cadr parsed-input))) + (match (loop :for i :in inputs + :do (setf boards (mapcar (partial #'04/update-board i) boards)) + :when (some #'04/check-board boards) + :return (list i (some #'04/check-board boards))) + ((list i board) + (* i (04/sum-unmarked board)))))) + +(defun 04/part-b (parsed-input) + (let ((inputs (car parsed-input)) + (boards (cadr parsed-input))) + (match (loop :for i :in inputs + :do (setf boards (mapcar (partial #'04/update-board i) boards)) + :when (not (equalp (list-length boards) 1)) + :do (setf boards (filter (compose #'not #'04/check-board) boards)) + :when (and (equalp (list-length boards) 1) (04/check-board (car boards))) + :return (list i (car boards))) + ((list i board) + (* i (04/sum-unmarked board)))))) diff --git a/src/common.lisp b/src/common.lisp index c59ea79..2c56184 100644 --- a/src/common.lisp +++ b/src/common.lisp @@ -1,2 +1,17 @@ (defun get-file-lines (name) (uiop:read-file-lines name)) + +(defun partial (func &rest args1) + (lambda (&rest args2) + (apply func (append args1 args2)))) + +(defun compose (a b) + (lambda (&rest args) + (funcall a (apply b args)))) + +(defun filter (func l) + (loop :for i :in l :when (funcall func i) :collect i)) + +(defun trim (input) + (string-trim '(#\Space #\Newline #\Backspace #\Tab + #\Linefeed #\Page #\Return #\Rubout) input)) diff --git a/test/04.lisp b/test/04.lisp index cccaf4e..d003649 100644 --- a/test/04.lisp +++ b/test/04.lisp @@ -29,14 +29,14 @@ (deftest 04/test-ex-b (04/aoc) (let ((result (04/part-b (04/parse-input-direct 04/default-input)))) - (assert-equalp 0 result))) + (assert-equalp 1924 result))) (deftest 04/test-a (04/aoc) (let ((result (04/part-a (04/parse-input "inputs/04.txt")))) - (assert-equalp 0 result))) + (assert-equalp 51776 result))) (deftest 04/test-b (04/aoc) (let ((result (04/part-b (04/parse-input "inputs/04.txt")))) - (assert-equalp 0 result))) + (assert-equalp 16830 result))) (defun 04/run-tests () (run-suite '04/aoc)) diff --git a/top.lisp b/top.lisp index 4a69a6a..8a6ff40 100644 --- a/top.lisp +++ b/top.lisp @@ -8,6 +8,8 @@ (ql:quickload 'uiop :silent t) (ql:quickload 'cl-ppcre :silent t) (ql:quickload 'clunit :silent t) +(ql:quickload 'cl-utilities :silent t) +(ql:quickload 'trivia :silent t) (load "src/common.lisp") @@ -22,4 +24,7 @@ (load "src/03.lisp") (load "test/03.lisp") -(defun run-all () (run-suite 'aoc)) +(load "src/04.lisp") +(load "test/04.lisp") + +(defun run-all () (clunit:run-suite 'aoc)) -- cgit