adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

commit 5523e6dd2ef81bc0c640df1bc6089e6ac3d1d2ea
parent ff82f9bb3da918f3fae83a156fcc4dca41c399d0
Author: Lukas Henkel <lh@entf.net>
Date:   Mon, 12 Dec 2022 21:01:46 +0100

Day 12

Diffstat:
Madventofcode2022.asd | 8+++++---
Ainput/day12.txt | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/day12.lisp | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
At/day12.lisp | 19+++++++++++++++++++
4 files changed, 155 insertions(+), 3 deletions(-)

diff --git a/adventofcode2022.asd b/adventofcode2022.asd @@ -5,7 +5,7 @@ :licence "AGPLv3" :serial t :pathname "src" - :depends-on ("trivia" "str") + :depends-on ("trivia" "str" "queues" "queues.simple-queue") :components ((:file "main") (:file "day01") (:file "day02") @@ -17,7 +17,8 @@ (:file "day08") (:file "day09") (:file "day10") - (:file "day11"))) + (:file "day11") + (:file "day12"))) (defsystem "adventofcode2022/test" :description "My solutions to the advent of code 2022" @@ -38,4 +39,5 @@ (:file "day08") (:file "day09") (:file "day10") - (:file "day11"))) + (:file "day11") + (:file "day12"))) diff --git a/input/day12.txt b/input/day12.txt @@ -0,0 +1,41 @@ +abccccccccccccccccaaccccccccccccccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa +abcccccccccccccaaaaaccccccccccccccccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaa +abccccccccccccccaaaaaccccccccccccccaaaaacccaaaaaacccccaaccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaa +abccccccccccccccaaaaacccccccccaacccaaaaacccaaaaaaaccccaaaacaacaaccccccccccccccccccccccccaaaccccaaaccccccccccccaaaa +abcccccccccccccaaaaacccccccaaaaaccaaaaaacccaaaaaaaacaaaaaacaaaaaccccccccccccccccccccccccaaacccaaaaccccccccccccaaac +abccccccaacaaaccccaaccccccccaaaaacaaaaaaccaaaacaaaacaaaaaccaaaaaaccccccccccccccccccccccccaaaaaaaacccccccccccccaacc +abccccccaaaaaaccccccccccccccaaaaacaaaaaaccaaaaccaaaacaaaaacaaaaaacccccccccccccccccccccccaaaaaaaaaccccccccccccccccc +abccccccaaaaaacccccccccccccaaaaaccccaaccccaacccccaaccaacaacaaaaaccccccccccccccccccccccccccaaakkkkllllcccaaaccccccc +abccccccaaaaaaacccccccccccccccaaccccaacccccccccccccccccccccccaaaccccccaaaacccccccccjjjjkkkkkkkkkkllllccccaacaccccc +abcccccaaaaaaaacccccaaccccccccccccccaaaaaaccccccccccccccccccaaccccccccaaaaccccccccjjjjjkkkkkkkkkppllllcccaaaaacccc +abcccccaaaaaaaaccaaaacccccccccccccccaaaaaccccccccccccccccaacaaccccccccaaaacccccccjjjjjjjkkkkkppppppplllccaaaaacccc +abccccccccaaaccccaaaaaacccccccccccaaaaaaaccccccccccccccccaaaaacccccccccaacccccccjjjjoooooooppppppppplllcccaaaccccc +abccccccccaaccccccaaaaaccccaacccccaaaaaaaaccccaaacccccccccaaaaaaacccccccccccccccjjjooooooooppppuuppppllcccaaaccccc +abccccccaacccccccaaaaacccccaaaccaaaaaaaaaaccaaaaaaccccccaaaaaaaaaacaaaccccccccccjjjoooouuuoopuuuuupppllcccaaaccccc +abacccccaaccccccccccaacccccaaaaaaaccaaaaaaccaaaaaaccccccaaaaaccaaaaaaaccccaaccccjjoootuuuuuuuuuuuuvpqlllcccccccccc +abaccaaaaaaaacccccccccccccccaaaaaaccaacccccccaaaaacccccccacaaaccaaaaaaccaaaacaccjjooottuuuuuuuxyuvvqqljjccddcccccc +abcccaaaaaaaaccccccccccccaaaaaaaaacaacaaccccaaaaaccccccccccaaaaaaaaaacccaaaaaacciijootttxxxuuxyyyvvqqjjjjdddcccccc +abcccccaaaaccccaaacccccccaaaaaaaaacaaaaaccccaaaaaccccccccccccaaaaaaaaacccaaaaccciiinntttxxxxxxyyvvqqqqjjjddddccccc +abccccaaaaaccccaaaaacccccaaaaaaaaaaaaaaaaccccccccccccccccccccaaaaaaaaaaccaaaaccciiinntttxxxxxxyyvvvqqqqjjjdddccccc +abccccaaaaaaccaaaaaccccccccaaaaaaaaaaaaaacccccccccccccccccccccccaaacaaacaacaaccciiinnnttxxxxxyyyvvvvqqqqjjjdddcccc +SbccccaaccaaccaaaaacccccccccaaaaaaaaaaaaacccccccccccccccccccccccaaacccccccccccciiinnntttxxxEzzyyyyvvvqqqjjjdddcccc +abcccccccccccccaaaaacccccccaaaaaaaaacaaaccccccccccccccccccccccccaaccccccccccccciiinnnttxxxxyyyyyyyyvvvqqqjjjdddccc +abcccccccccccccaaccccccccccaaaaaaaaccccccccccccccccccccccccccccccccccccccccccciiinnntttxxyyyyyyyyyvvvvqqqjjjdddccc +abccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccciiinntttxxxwwwyyywwvvvvrqqjjjjdddccc +abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccciinnntttxwwwwwyyywwvvvrrrqkkkeddcccc +abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccchhnnntttsswwswwyywwrrrrrrkkkkeeecccc +abcccccccccccccccccccccccccccaaaaaacccccccccccccccccccaccccccccccccaaacccccccchhhnmmssssssswwwwwwrrrkkkkkeeeeecccc +abcccccccccccccccccccccccccccccaaacccccccccccccccccccaaccccccccccaaaaaacccccaahhhmmmmmsssssswwwwrrrkkkkkeeeeeccccc +abaacccccccccccccaccccccccccccccccccccccccccccccccaaaaacaacccccccaaaaaacaaaaaahhhhmmmmmmmmssswwwrrkkkkeeeeeacccccc +abacccccccccccccaaaaaaaaccccccccaaacccccccaaccccccaaaaaaaacccccccaaaaaacaaaaaaahhhhmmmmmmmmsssrrrrkkkeeeeeaacccccc +abaaaccccaaccccccaaaaaacccccccccaaacccaacaaaccccccccaaaacccccccccaaaaacccaaaaaaahhhhhhhmmmmlsssrrllkfeeeeaaaaacccc +abaaaccaaaaccccccaaaaaacccccccccaaaaaaaaaaaaaacccccaaaaacccccccccaaaaacccaaaaaaachhhhhgggmllsssrrllkffeaaaaaaacccc +abaacccaaaaaacccaaaaaaaacccccaaaaaaaaaaaaaaaaacccccaacaaacccccccccccccccaaaaaacccccchggggglllllllllfffaaaaaaaacccc +abaaccccaaaacccaaaaaaaaaaccccaaaaaaaaacaaaaaaaccaccaccaaacccccccccccccccaaaaaacccccccccgggglllllllffffaaaaaacccccc +abcccccaaaaacccaaaaaaaaaacccccaaaaaaaccaaaaacccaaaccccccccccccccccccccccccccaacccccccccagggglllllffffccccaaacccccc +abcccccaacaaccccccaaaaacaccaacccaaaaaaaaaaaaaccaaacccccccccccccccccccccccccccccccccccccaagggggffffffcccccccccccccc +abcccccccccccaaaaaaaaacccccaaccaaaaaaaccaaaaacaaaaccccccccccccccccccccccccccccccccccccaaaacgggfffffccccccccccccccc +abcccccccccccaaaaacaacccaaaaaaaaaaccaacccaaaaaaaacccaaccccccccccccccccccccccccccccccccccccccggfffccccccccccccaaaca +abccccccccccaaaaaaccccccaaaaaaaaacccccccccaaaaaaaaaaaacccccccccccccaaaccccccccccccccccccccccaaaccccccccccccccaaaaa +abccccccccccaaaaaaccccccccaaaacccccccccccccaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccaaaccccccccccccccaaaa +abcccccccccccaaaaacccccccaaaaaaccccccccccaaaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccccccccccccccccccaaaaa diff --git a/src/day12.lisp b/src/day12.lisp @@ -0,0 +1,90 @@ +(defpackage #:adventofcode2022/day12 + (:use #:cl #:adventofcode2022) + (:import-from #:queues + #:qpush + #:qpop + #:qsize + #:make-queue)) +(in-package #:adventofcode2022/day12) + +(defun get-passable-neighbors (map pos) + (loop with width = (array-dimension map 0) + with height = (array-dimension map 1) + with pos-height = (aref map (first pos) (second pos)) + for dir in '((-1 0) + (1 0) + (0 -1) + (0 1)) + for x = (+ (first pos) (first dir)) + for y = (+ (second pos) (second dir)) + unless (or (< x 0) (< y 0) + (>= x width) (>= y height) + (< (1+ pos-height) (aref map x y))) + collect (list x y))) + +(defun find-shortest-route (map start-pos end-pos) + (loop with queue = (make-queue :simple-queue) + with steps = (make-hash-table :test 'equal) + initially (setf (gethash start-pos steps) 0) + (qpush queue start-pos) + while (> (qsize queue) 0) + for pos = (qpop queue) + for current-steps = (gethash pos steps) + when (equal pos end-pos) + return current-steps + do (loop for next in (get-passable-neighbors map pos) + unless (gethash next steps) + do (setf (gethash next steps) (1+ current-steps)) + and do (qpush queue next)))) + +(defun find-position (map char) + (loop named outer + for y from 0 below (length map) + for row = (aref map y) + do (loop for x from 0 below (length row) + when (char= (aref row x) char) + do (return-from outer (list x y))))) + +(defun convert-map (map) + (loop with height = (length map) + with width = (length (aref map 0)) + with new-map = (make-array (list width height)) + for y from 0 below height + for row = (aref map y) + do (loop for x from 0 below width + for cell = (aref row x) + do (setf (aref new-map x y) + (cond + ((char= cell #\S) 0) + ((char= cell #\E) 25) + (t (- (char-code cell) 97))))) + finally (return new-map))) + +(defun task1 (inputs) + (let* ((map (coerce inputs 'vector)) + (start-pos (find-position map #\S)) + (end-pos (find-position map #\E)) + (map (convert-map map))) + (find-shortest-route map start-pos end-pos))) + +(defun task2 (inputs) + (loop with map = (coerce inputs 'vector) + with end-pos = (find-position map #\E) + with shortest-distance = nil + with current-distance = nil + initially (setf map (convert-map map)) + for x from 0 below (array-dimension map 0) + do (loop for y from 0 below (array-dimension map 1) + when (= 0 (aref map x y)) + do (setf current-distance + (find-shortest-route map (list x y) end-pos)) + and when (or (null shortest-distance) + (and (not (null current-distance)) + (< current-distance shortest-distance))) + do (setf shortest-distance current-distance)) + finally (return shortest-distance))) + +(define-day 12 + () + #'task1 + #'task2) diff --git a/t/day12.lisp b/t/day12.lisp @@ -0,0 +1,19 @@ +(in-package #:adventofcode2022/test) + +(defconstant +testdata-day12+ "Sabqponm +abcryxxl +accszExk +acctuvwj +abdefghi") + +(def-test day12-task1 () + (is-true + (= 31 + (run-task 12 1 + (make-string-input-stream +testdata-day12+))))) + +(def-test day12-task2 () + (is-true + (= 29 + (run-task 12 2 + (make-string-input-stream +testdata-day12+)))))