diff options
Diffstat (limited to '2021/12')
-rw-r--r-- | 2021/12/input | 23 | ||||
-rw-r--r-- | 2021/12/one.tl | 49 | ||||
-rw-r--r-- | 2021/12/testinput | 7 | ||||
-rw-r--r-- | 2021/12/two.tl | 68 |
4 files changed, 147 insertions, 0 deletions
diff --git a/2021/12/input b/2021/12/input new file mode 100644 index 0000000..756681b --- /dev/null +++ b/2021/12/input @@ -0,0 +1,23 @@ +pn-TY +rp-ka +az-aw +al-IV +pn-co +end-rp +aw-TY +rp-pn +al-rp +end-al +IV-co +end-TM +co-TY +TY-ka +aw-pn +aw-IV +pn-IV +IV-ka +TM-rp +aw-PD +start-IV +start-co +start-pn diff --git a/2021/12/one.tl b/2021/12/one.tl new file mode 100644 index 0000000..70e36d5 --- /dev/null +++ b/2021/12/one.tl @@ -0,0 +1,49 @@ +(defvar %cave-hash% (hash)) + +(defstruct cave () + name + neighbors + + (:postinit (cv) + (assert cv.name) + (set [%cave-hash% cv.name] cv))) + +(defstruct small-cave cave + (:method visit (cv path fn) + (unless (member cv path) + (push cv path) + (each ((n cv.neighbors)) + n.(visit path fn))))) + +(defstruct big-cave cave + (:method visit (cv path fn) + (push cv path) + (each ((n cv.neighbors)) + n.(visit path fn)))) + +(defstruct end-cave cave + (:method visit (cv path fn) + (push cv path) + [fn path])) + +(defun ensure-cave (name) + (or [%cave-hash% name] + (set [%cave-hash% name] + (match-case name + ("end" (new end-cave name name)) + (@[all @str chr-islower] (new small-cave name name)) + (@else (new big-cave name name)))))) + +(defun read-caves (: (name "input")) + (with-stream (s (open-file name)) + (whilet ((line (get-line s))) + (match `@a-@b` line + (let ((ca (ensure-cave a)) + (cb (ensure-cave b))) + (pushnew cb ca.neighbors) + (pushnew ca cb.neighbors)))))) + +(defun find-paths (fn) + (let ((start [%cave-hash% "start"])) + (assert start) + start.(visit nil fn))) diff --git a/2021/12/testinput b/2021/12/testinput new file mode 100644 index 0000000..6fd8c41 --- /dev/null +++ b/2021/12/testinput @@ -0,0 +1,7 @@ +start-A +start-b +A-c +A-b +b-d +A-end +b-end diff --git a/2021/12/two.tl b/2021/12/two.tl new file mode 100644 index 0000000..69f179a --- /dev/null +++ b/2021/12/two.tl @@ -0,0 +1,68 @@ +(defvar %cave-hash% (hash)) + +(defstruct cave () + name + neighbors + + (:postinit (cv) + (assert cv.name) + (set [%cave-hash% cv.name] cv))) + +(defstruct end-cave cave + (:method visit (cv path fn) + (push cv path) + [fn (remq t path)])) + +(defstruct start-cave cave + (:method visit (cv path fn) + (unless (member cv path) + (push cv path) + (each ((n cv.neighbors)) + n.(visit path fn))))) + +(defstruct small-cave cave + (:method visit (cv path fn) + (let ((in-path (member cv path))) + (when (or (not in-path) + (not (member t path))) + (push cv path) + (if in-path + (push t path)) + (each ((n cv.neighbors)) + n.(visit path fn)))))) + +(defstruct big-cave cave + (:method visit (cv path fn) + (push cv path) + (each ((n cv.neighbors)) + n.(visit path fn)))) + +(defun ensure-cave (name) + (or [%cave-hash% name] + (set [%cave-hash% name] + (match-case name + ("end" (new end-cave name name)) + ("start" (new start-cave name name)) + (@[all @str chr-islower] (new small-cave name name)) + (@else (new big-cave name name)))))) + +(defun read-caves (: (name "input")) + (with-stream (s (open-file name)) + (whilet ((line (get-line s))) + (match `@a-@b` line + (let ((ca (ensure-cave a)) + (cb (ensure-cave b))) + (pushnew cb ca.neighbors) + (pushnew ca cb.neighbors)))))) + +(defun find-paths (fn) + (let ((start [%cave-hash% "start"])) + (assert start) + start.(visit nil fn))) + +(defun solve (: (name "input")) + (let (paths) + (read-caves name) + (find-paths (opip reverse (mapcar .name) (push @1 paths))) + (mapdo [chain (ap join-with ",") pprinl] paths) + (len paths))) |