diff --git a/elisp/day-5/solution.el b/elisp/day-5/solution.el index a56080f..9b97586 100755 --- a/elisp/day-5/solution.el +++ b/elisp/day-5/solution.el @@ -27,9 +27,14 @@ (defmacro -make-crates (&rest exprs) `(make-advent-of-code-day-5-crates ,@exprs)) +(defmacro -make-crates-multimove (&rest exprs) + `(make-advent-of-code-day-5-crates-multimove ,@exprs)) + (cl-defstruct -crates stacks) +(cl-defstruct (-crates-multimove (:include -crates))) + (defun -crates-pop (crates n) (with-slots (stacks) crates (when-let ((stack (assoc n stacks))) @@ -47,14 +52,28 @@ (setf (cdr stack) (append (cdr stack) (list crate))) (push (cons n (list crate)) stacks)))) -(defun -crates-process-move (crates move) +(cl-defgeneric -crates-process-move (crates move) (with-slots (n from to) move (cl-loop repeat n do (-crates-push crates (-crates-pop crates (- from 1)) (- to 1))))) -(defun -crates-from-list (input) +(cl-defmethod -crates-process-move ((crates -crates-multimove) move) + (if (= 1 (-move-n move)) + (cl-call-next-method) + (with-slots (stacks) crates + (let ((n (-move-n move)) + (from (- (-move-from move) 1)) + (to (- (-move-to move) 1))) + (setf (alist-get to stacks) (append (seq-take (alist-get from stacks) n) + (alist-get to stacks))) + (setf (alist-get from stacks) (seq-drop (alist-get from stacks) n)))))) + +(defun -crates-process-moves (crates moves) + (cl-loop for move in moves + do (-crates-process-move crates move))) + +(defun -crates-init (crates input) (cl-loop for (crate . n) in input - with crates = (-make-crates :stacks nil) do (-crates-append crates crate n) finally (return crates))) @@ -70,7 +89,7 @@ (moves (seq-subseq input (+ delimiter 1)))) (list crates moves))) -(defun -parse-crates-from-line (line) +(defun -parse-crates-into-conses-from-line (line) (cl-loop for i from 0 to (- (length line) 3) by 4 for n from 0 for crate = (substring line i (+ i 3)) @@ -79,7 +98,7 @@ if (not empty?) collect (cons crate-id n))) -(defun -parse-move-from-line (line) +(defun -parse-move-into-parts-from-line (line) (save-match-data (string-match (rx "move" space (group (one-or-more digit)) space "from" space (group (one-or-more digit)) space @@ -89,28 +108,47 @@ (string-to-number (match-string 2 line)) (string-to-number (match-string 3 line))))) -(defun -part-1 (input) - (pcase-let* ((`(,input-crates ,input-moves) (-parse-input-into-parts input)) - (parsed-crates-list (cl-loop for line in input-crates - append (-parse-crates-from-line line))) - (crates (-crates-from-list parsed-crates-list)) - (moves (cl-loop for line in input-moves - for move = (pcase-let ((`(,n ,from ,to) (-parse-move-from-line line))) - (-make-move :n n :from from :to to)) - collect move))) - (seq-do (lambda (move) - (-crates-process-move crates move)) - moves) +(defun -make-list-of-move-structs-from-input (input-moves) + (cl-loop for line in input-moves + for move = (pcase-let ((`(n from to) (-parse-move-into-parts-from-line line))) + (-make-move :n n :from from :to to)) + collect move)) + +(defun -solution (crates input) + (pcase-let ((`(,input-crates ,input-moves) (-parse-input-into-parts input))) + (-crates-init crates + (cl-loop for line in input-crates + append (-parse-crates-into-conses-from-line line))) + (-crates-process-moves crates + (cl-loop for line in input-moves + for move = (seq-let (n from to) (-parse-move-into-parts-from-line line) + (-make-move :n n :from from :to to)) + collect move)) (cl-loop for n from 0 to (length (-crates-stacks crates)) - for top-crate = (cadr (assoc n (-crates-stacks crates))) - for top-crates = top-crate then (concat top-crates top-crate) - finally (return top-crates)))) + for top = (car (alist-get n (-crates-stacks crates))) + for result = top then (seq-concatenate 'string result top) + finally (return result)))) + (ert-deftest -test-part-1-example () - (should (equal (-part-1 (aoc-read-file-lines "example.txt")) "CMZ"))) + (should (equal (-solution (-make-crates) + (aoc-read-file-lines "example.txt")) + "CMZ"))) (ert-deftest -test-part-1 () - (should (equal (-part-1 (aoc-read-file-lines "input.txt")) "CFFHVVHNC"))) + (should (equal (-solution (-make-crates) + (aoc-read-file-lines "input.txt")) + "CFFHVVHNC"))) + +(ert-deftest -test-part-2-example () + (should (equal (-solution (-make-crates-multimove) + (aoc-read-file-lines "example.txt")) + "MCD"))) + +(ert-deftest -test-part-2 () + (should (equal (-solution (-make-crates-multimove) + (aoc-read-file-lines "input.txt")) + "FSZWBPTBG"))) (when noninteractive (ert-run-tests-batch)) diff --git a/input/day-5-example.txt b/input/day-5-example.txt new file mode 100644 index 0000000..e98aba4 --- /dev/null +++ b/input/day-5-example.txt @@ -0,0 +1,9 @@ + [D] +[N] [C] +[Z] [M] [P] + 1 2 3 + +move 1 from 2 to 1 +move 3 from 1 to 3 +move 2 from 2 to 1 +move 1 from 1 to 2 \ No newline at end of file diff --git a/input/day-5.txt b/input/day-5.txt new file mode 100644 index 0000000..aef7951 --- /dev/null +++ b/input/day-5.txt @@ -0,0 +1,511 @@ + [G] [P] [M] + [V] [M] [W] [S] [Q] + [N] [N] [G] [H] [T] [F] + [J] [W] [V] [Q] [W] [F] [P] +[C] [H] [T] [T] [G] [B] [Z] [B] +[S] [W] [S] [L] [F] [B] [P] [C] [H] +[G] [M] [Q] [S] [Z] [T] [J] [D] [S] +[B] [T] [M] [B] [J] [C] [T] [G] [N] + 1 2 3 4 5 6 7 8 9 + +move 2 from 4 to 2 +move 6 from 9 to 7 +move 4 from 7 to 2 +move 2 from 4 to 1 +move 2 from 6 to 7 +move 1 from 3 to 8 +move 4 from 7 to 1 +move 2 from 3 to 2 +move 3 from 8 to 5 +move 3 from 1 to 4 +move 12 from 2 to 5 +move 2 from 6 to 8 +move 12 from 5 to 8 +move 3 from 7 to 9 +move 18 from 8 to 9 +move 2 from 8 to 6 +move 3 from 2 to 3 +move 14 from 9 to 4 +move 1 from 1 to 3 +move 7 from 9 to 3 +move 1 from 2 to 1 +move 8 from 4 to 5 +move 5 from 6 to 3 +move 2 from 7 to 9 +move 3 from 4 to 9 +move 4 from 9 to 6 +move 4 from 6 to 1 +move 8 from 4 to 6 +move 10 from 1 to 2 +move 13 from 3 to 2 +move 17 from 5 to 9 +move 2 from 5 to 1 +move 9 from 9 to 7 +move 1 from 3 to 6 +move 2 from 1 to 8 +move 11 from 2 to 4 +move 5 from 6 to 8 +move 1 from 6 to 3 +move 1 from 1 to 4 +move 3 from 8 to 6 +move 3 from 2 to 8 +move 9 from 7 to 9 +move 4 from 4 to 7 +move 1 from 9 to 5 +move 15 from 9 to 7 +move 7 from 8 to 3 +move 1 from 5 to 6 +move 2 from 6 to 9 +move 8 from 2 to 6 +move 3 from 4 to 3 +move 1 from 2 to 5 +move 4 from 9 to 3 +move 1 from 3 to 4 +move 13 from 6 to 2 +move 1 from 5 to 1 +move 4 from 4 to 9 +move 6 from 3 to 2 +move 11 from 2 to 7 +move 6 from 3 to 4 +move 3 from 3 to 2 +move 1 from 3 to 4 +move 1 from 1 to 3 +move 3 from 9 to 2 +move 1 from 3 to 1 +move 4 from 7 to 1 +move 1 from 9 to 5 +move 5 from 1 to 4 +move 11 from 2 to 4 +move 1 from 5 to 3 +move 1 from 2 to 3 +move 12 from 4 to 2 +move 2 from 7 to 2 +move 7 from 4 to 3 +move 5 from 4 to 1 +move 7 from 7 to 6 +move 4 from 1 to 8 +move 1 from 8 to 5 +move 8 from 3 to 2 +move 4 from 7 to 4 +move 13 from 7 to 1 +move 2 from 8 to 6 +move 5 from 4 to 9 +move 1 from 3 to 6 +move 1 from 5 to 8 +move 1 from 2 to 9 +move 4 from 2 to 6 +move 2 from 8 to 6 +move 10 from 1 to 3 +move 4 from 9 to 4 +move 2 from 1 to 3 +move 5 from 2 to 9 +move 4 from 9 to 2 +move 1 from 1 to 2 +move 13 from 2 to 4 +move 15 from 4 to 5 +move 3 from 6 to 8 +move 8 from 3 to 8 +move 1 from 4 to 2 +move 14 from 5 to 1 +move 1 from 5 to 4 +move 1 from 4 to 2 +move 8 from 6 to 7 +move 3 from 6 to 2 +move 2 from 9 to 1 +move 8 from 8 to 7 +move 9 from 1 to 5 +move 7 from 5 to 3 +move 14 from 7 to 9 +move 2 from 2 to 3 +move 7 from 2 to 1 +move 1 from 6 to 1 +move 4 from 9 to 2 +move 8 from 3 to 6 +move 2 from 4 to 3 +move 4 from 3 to 5 +move 5 from 5 to 7 +move 2 from 6 to 9 +move 6 from 6 to 2 +move 4 from 2 to 3 +move 1 from 6 to 2 +move 2 from 7 to 8 +move 13 from 9 to 5 +move 2 from 7 to 1 +move 14 from 1 to 5 +move 15 from 5 to 7 +move 3 from 8 to 7 +move 5 from 3 to 5 +move 6 from 5 to 7 +move 4 from 1 to 7 +move 1 from 2 to 5 +move 3 from 2 to 8 +move 11 from 5 to 2 +move 10 from 7 to 1 +move 1 from 3 to 4 +move 10 from 2 to 9 +move 1 from 5 to 8 +move 6 from 7 to 3 +move 1 from 4 to 6 +move 2 from 3 to 8 +move 1 from 2 to 1 +move 4 from 3 to 9 +move 3 from 1 to 6 +move 2 from 7 to 1 +move 1 from 5 to 6 +move 1 from 3 to 8 +move 4 from 1 to 4 +move 5 from 2 to 9 +move 3 from 1 to 4 +move 18 from 9 to 7 +move 4 from 8 to 4 +move 3 from 1 to 2 +move 1 from 9 to 7 +move 1 from 4 to 7 +move 1 from 6 to 2 +move 1 from 2 to 5 +move 25 from 7 to 3 +move 7 from 4 to 2 +move 8 from 7 to 9 +move 4 from 8 to 6 +move 1 from 8 to 5 +move 4 from 6 to 5 +move 2 from 9 to 5 +move 3 from 5 to 8 +move 4 from 6 to 4 +move 12 from 3 to 5 +move 11 from 3 to 2 +move 13 from 5 to 8 +move 4 from 9 to 6 +move 7 from 4 to 9 +move 2 from 6 to 2 +move 12 from 2 to 7 +move 1 from 6 to 3 +move 1 from 5 to 6 +move 2 from 5 to 3 +move 15 from 8 to 6 +move 4 from 6 to 7 +move 1 from 5 to 1 +move 10 from 2 to 8 +move 8 from 8 to 3 +move 8 from 6 to 8 +move 2 from 7 to 6 +move 9 from 9 to 7 +move 8 from 8 to 9 +move 1 from 1 to 3 +move 1 from 2 to 7 +move 7 from 3 to 1 +move 3 from 8 to 5 +move 3 from 1 to 6 +move 7 from 9 to 2 +move 2 from 3 to 7 +move 5 from 7 to 9 +move 17 from 7 to 5 +move 2 from 7 to 6 +move 10 from 6 to 3 +move 1 from 1 to 3 +move 6 from 9 to 3 +move 1 from 2 to 9 +move 2 from 7 to 9 +move 2 from 9 to 7 +move 1 from 5 to 8 +move 1 from 8 to 5 +move 6 from 2 to 5 +move 1 from 6 to 1 +move 5 from 3 to 5 +move 1 from 6 to 8 +move 1 from 7 to 9 +move 2 from 9 to 3 +move 15 from 5 to 2 +move 2 from 1 to 8 +move 2 from 3 to 7 +move 2 from 8 to 3 +move 3 from 5 to 9 +move 1 from 8 to 6 +move 1 from 9 to 6 +move 3 from 7 to 6 +move 17 from 3 to 4 +move 1 from 1 to 2 +move 6 from 2 to 9 +move 16 from 4 to 1 +move 4 from 6 to 8 +move 9 from 5 to 6 +move 8 from 6 to 2 +move 2 from 9 to 5 +move 2 from 3 to 5 +move 1 from 6 to 2 +move 1 from 4 to 8 +move 14 from 1 to 3 +move 8 from 5 to 3 +move 20 from 3 to 1 +move 1 from 8 to 2 +move 1 from 9 to 6 +move 1 from 6 to 7 +move 1 from 7 to 3 +move 22 from 1 to 2 +move 3 from 3 to 6 +move 27 from 2 to 8 +move 2 from 2 to 8 +move 2 from 6 to 9 +move 2 from 9 to 4 +move 2 from 4 to 8 +move 1 from 1 to 3 +move 14 from 8 to 5 +move 1 from 3 to 9 +move 3 from 9 to 2 +move 5 from 2 to 8 +move 10 from 2 to 9 +move 1 from 6 to 7 +move 1 from 7 to 5 +move 7 from 5 to 2 +move 2 from 9 to 2 +move 1 from 6 to 2 +move 2 from 9 to 5 +move 3 from 5 to 6 +move 6 from 5 to 3 +move 1 from 5 to 6 +move 4 from 3 to 9 +move 2 from 9 to 8 +move 3 from 9 to 5 +move 23 from 8 to 1 +move 2 from 6 to 1 +move 1 from 5 to 7 +move 2 from 3 to 5 +move 2 from 9 to 5 +move 4 from 9 to 7 +move 2 from 9 to 4 +move 1 from 5 to 4 +move 5 from 8 to 5 +move 2 from 6 to 2 +move 3 from 7 to 3 +move 1 from 3 to 4 +move 3 from 2 to 8 +move 4 from 1 to 6 +move 2 from 6 to 3 +move 4 from 1 to 2 +move 3 from 8 to 1 +move 13 from 2 to 5 +move 4 from 3 to 2 +move 14 from 5 to 7 +move 5 from 2 to 7 +move 18 from 7 to 9 +move 4 from 4 to 7 +move 2 from 5 to 4 +move 17 from 9 to 5 +move 1 from 9 to 1 +move 1 from 7 to 2 +move 5 from 7 to 2 +move 18 from 1 to 4 +move 1 from 7 to 3 +move 1 from 3 to 6 +move 2 from 1 to 3 +move 1 from 6 to 5 +move 2 from 6 to 8 +move 1 from 8 to 9 +move 1 from 8 to 3 +move 13 from 4 to 5 +move 1 from 1 to 6 +move 3 from 2 to 4 +move 1 from 6 to 1 +move 3 from 2 to 9 +move 3 from 3 to 1 +move 5 from 4 to 5 +move 30 from 5 to 3 +move 1 from 4 to 6 +move 1 from 9 to 8 +move 1 from 9 to 6 +move 21 from 3 to 7 +move 3 from 1 to 6 +move 1 from 1 to 4 +move 1 from 9 to 6 +move 1 from 8 to 2 +move 1 from 3 to 6 +move 1 from 9 to 3 +move 5 from 4 to 8 +move 1 from 2 to 4 +move 9 from 5 to 7 +move 2 from 5 to 9 +move 2 from 8 to 2 +move 2 from 6 to 3 +move 1 from 4 to 1 +move 4 from 3 to 8 +move 2 from 9 to 2 +move 4 from 2 to 6 +move 1 from 1 to 4 +move 2 from 6 to 9 +move 2 from 5 to 4 +move 1 from 3 to 1 +move 1 from 1 to 3 +move 2 from 9 to 1 +move 5 from 3 to 5 +move 1 from 1 to 8 +move 4 from 6 to 4 +move 5 from 5 to 6 +move 18 from 7 to 5 +move 1 from 3 to 4 +move 12 from 7 to 5 +move 15 from 5 to 6 +move 1 from 5 to 8 +move 1 from 3 to 7 +move 1 from 1 to 2 +move 1 from 2 to 4 +move 1 from 7 to 9 +move 2 from 8 to 2 +move 1 from 2 to 4 +move 4 from 4 to 2 +move 1 from 2 to 1 +move 1 from 9 to 8 +move 4 from 6 to 4 +move 3 from 2 to 6 +move 1 from 2 to 6 +move 8 from 4 to 3 +move 1 from 1 to 3 +move 6 from 6 to 1 +move 1 from 3 to 6 +move 5 from 1 to 7 +move 10 from 5 to 9 +move 3 from 9 to 8 +move 7 from 6 to 2 +move 1 from 7 to 8 +move 3 from 5 to 8 +move 3 from 6 to 2 +move 6 from 8 to 9 +move 1 from 5 to 3 +move 2 from 3 to 1 +move 2 from 4 to 8 +move 6 from 6 to 9 +move 1 from 1 to 4 +move 17 from 9 to 2 +move 1 from 4 to 1 +move 2 from 7 to 8 +move 1 from 9 to 8 +move 3 from 8 to 4 +move 3 from 1 to 4 +move 9 from 8 to 2 +move 1 from 8 to 4 +move 12 from 2 to 7 +move 4 from 7 to 4 +move 1 from 8 to 1 +move 10 from 4 to 2 +move 3 from 3 to 2 +move 1 from 9 to 7 +move 11 from 7 to 3 +move 1 from 3 to 1 +move 2 from 3 to 9 +move 1 from 3 to 7 +move 2 from 1 to 9 +move 1 from 6 to 5 +move 7 from 3 to 6 +move 1 from 7 to 3 +move 3 from 3 to 4 +move 1 from 5 to 7 +move 2 from 4 to 3 +move 2 from 4 to 8 +move 1 from 7 to 6 +move 2 from 6 to 8 +move 1 from 9 to 2 +move 1 from 9 to 5 +move 1 from 5 to 1 +move 1 from 8 to 6 +move 1 from 3 to 2 +move 4 from 6 to 1 +move 5 from 1 to 4 +move 11 from 2 to 4 +move 2 from 8 to 2 +move 1 from 8 to 9 +move 27 from 2 to 5 +move 4 from 6 to 3 +move 3 from 2 to 4 +move 2 from 5 to 9 +move 1 from 5 to 7 +move 2 from 9 to 5 +move 14 from 4 to 7 +move 2 from 4 to 7 +move 3 from 4 to 8 +move 4 from 3 to 1 +move 4 from 1 to 8 +move 2 from 3 to 9 +move 2 from 9 to 3 +move 7 from 8 to 9 +move 1 from 3 to 8 +move 2 from 3 to 2 +move 25 from 5 to 9 +move 1 from 5 to 8 +move 1 from 8 to 7 +move 26 from 9 to 1 +move 23 from 1 to 5 +move 7 from 9 to 7 +move 1 from 9 to 8 +move 1 from 9 to 2 +move 5 from 7 to 1 +move 20 from 5 to 6 +move 1 from 7 to 6 +move 2 from 5 to 3 +move 1 from 8 to 6 +move 21 from 6 to 8 +move 1 from 6 to 4 +move 1 from 1 to 7 +move 2 from 1 to 6 +move 1 from 1 to 3 +move 1 from 2 to 5 +move 1 from 2 to 6 +move 2 from 7 to 6 +move 6 from 7 to 9 +move 3 from 1 to 2 +move 17 from 8 to 1 +move 1 from 4 to 1 +move 2 from 6 to 9 +move 3 from 8 to 9 +move 2 from 3 to 7 +move 2 from 9 to 8 +move 4 from 7 to 3 +move 4 from 3 to 4 +move 2 from 5 to 8 +move 4 from 8 to 4 +move 3 from 6 to 8 +move 18 from 1 to 5 +move 1 from 3 to 4 +move 3 from 2 to 4 +move 5 from 9 to 1 +move 10 from 7 to 5 +move 5 from 1 to 3 +move 5 from 3 to 5 +move 5 from 4 to 3 +move 2 from 4 to 2 +move 5 from 8 to 3 +move 25 from 5 to 2 +move 3 from 3 to 6 +move 1 from 1 to 3 +move 3 from 6 to 7 +move 1 from 4 to 2 +move 1 from 5 to 8 +move 2 from 4 to 9 +move 1 from 8 to 1 +move 20 from 2 to 7 +move 10 from 7 to 1 +move 1 from 1 to 7 +move 4 from 7 to 8 +move 5 from 5 to 4 +move 4 from 8 to 6 +move 1 from 1 to 3 +move 5 from 7 to 4 +move 2 from 1 to 5 +move 4 from 9 to 1 +move 3 from 2 to 5 +move 5 from 5 to 1 +move 1 from 9 to 1 +move 11 from 1 to 3 +move 1 from 6 to 2 +move 7 from 3 to 5 +move 11 from 3 to 7 +move 1 from 2 to 6 +move 7 from 7 to 8 +move 1 from 9 to 1 +move 2 from 3 to 1 +move 1 from 5 to 3 +move 4 from 1 to 6 +move 4 from 6 to 3 +move 9 from 4 to 5 +move 2 from 8 to 2 +move 4 from 6 to 9 +move 3 from 2 to 4 +move 1 from 8 to 6