solved day10
This commit is contained in:
parent
756a97495c
commit
fb2f8a321a
3 changed files with 173 additions and 0 deletions
2
aoc.asd
2
aoc.asd
|
@ -34,6 +34,7 @@
|
|||
(:file "2024/day07")
|
||||
(:file "2024/day08")
|
||||
(:file "2024/day09")
|
||||
(:file "2024/day10")
|
||||
)))
|
||||
:description "Advent of Code challenges and solutions."
|
||||
:long-description "Solutions for the AOC challenges."
|
||||
|
@ -59,6 +60,7 @@
|
|||
(:file "2024/day07-test")
|
||||
(:file "2024/day08-test")
|
||||
(:file "2024/day09-test")
|
||||
(:file "2024/day10-test")
|
||||
)))
|
||||
:description "Test system for aoc"
|
||||
:perform (test-op (op c) (symbol-call :parachute :test :aoc/tests)))
|
||||
|
|
155
src/2024/day10.lisp
Normal file
155
src/2024/day10.lisp
Normal file
|
@ -0,0 +1,155 @@
|
|||
(defpackage :aoc/2024/10
|
||||
(:use :cl :aoc :alexandria :trivia :lla)
|
||||
(:export
|
||||
#:sample-data
|
||||
#:sample-data2
|
||||
#:part1
|
||||
#:part2
|
||||
))
|
||||
|
||||
(in-package :aoc/2024/10)
|
||||
|
||||
|
||||
(defun parse-line (line)
|
||||
(map 'vector (lambda (c) (or (digit-char-p c) 0)) (coerce line 'list)))
|
||||
|
||||
|
||||
(defun parse-input (lines)
|
||||
(let ((heights (mapcar #'parse-line lines)))
|
||||
(make-array `(,(length (first heights)) ,(length heights)) :initial-contents heights))
|
||||
)
|
||||
|
||||
(defparameter input-text (test-input 2024 10))
|
||||
(defparameter input-data (parse-input input-text))
|
||||
|
||||
(defparameter sample-text (aoc:split-lines "89010123
|
||||
78121874
|
||||
87430965
|
||||
96549874
|
||||
45678903
|
||||
32019012
|
||||
01329801
|
||||
10456732"))
|
||||
(defparameter sample-data
|
||||
(parse-input sample-text))
|
||||
|
||||
(defparameter sample-data-0 (parse-input (aoc:split-lines "...0...
|
||||
...1...
|
||||
...2...
|
||||
6543456
|
||||
7.....7
|
||||
8.....8
|
||||
9.....9")))
|
||||
|
||||
(defparameter sample-data-1 (parse-input (aoc:split-lines "..90..9
|
||||
...1.98
|
||||
...2..7
|
||||
6543456
|
||||
765.987
|
||||
876....
|
||||
987....")))
|
||||
|
||||
(defun find-heights(h map)
|
||||
(loop
|
||||
for y from 0 below (array-dimension map 1)
|
||||
append
|
||||
(loop
|
||||
for x from 0 below (array-dimension map 1)
|
||||
if (= h (aref map x y))
|
||||
collect (cons x y))))
|
||||
|
||||
(defun find-trailheads (map)
|
||||
(find-heights 1 map))
|
||||
|
||||
(defun find-trailends (map)
|
||||
(find-heights 9 map))
|
||||
|
||||
(defun get-xy (map x y)
|
||||
(if (array-in-bounds-p map x y)
|
||||
(aref map x y)
|
||||
0))
|
||||
|
||||
|
||||
|
||||
|
||||
(defun surrounding-paths (trails x y)
|
||||
(remove-duplicates
|
||||
(append
|
||||
(gethash (cons (1+ x) y) trails)
|
||||
(gethash (cons (1- x) y) trails)
|
||||
(gethash (cons x (1+ y)) trails)
|
||||
(gethash (cons x (1- y)) trails)
|
||||
)))
|
||||
|
||||
(defun trails-update (trails map h)
|
||||
(let ((nt (make-hash-table :test #'equal :size 100)))
|
||||
(loop
|
||||
for pt in (find-heights h map)
|
||||
do (setf
|
||||
(gethash pt nt)
|
||||
(if (= h 9)
|
||||
(list pt)
|
||||
(surrounding-paths trails (car pt) (cdr pt))))
|
||||
)
|
||||
nt))
|
||||
|
||||
(defun map-endpoints (map)
|
||||
(let ((ep-map (make-hash-table :test #'equal)))
|
||||
(loop
|
||||
for h from 9 downto 0
|
||||
do (setf ep-map (trails-update ep-map map h)))
|
||||
ep-map))
|
||||
|
||||
(defun score (map)
|
||||
(loop
|
||||
for v being the hash-values in (map-endpoints map)
|
||||
sum (length v)))
|
||||
|
||||
|
||||
(defun sum-surrounding (map x y)
|
||||
(+
|
||||
(get-xy map (1+ x) y)
|
||||
(get-xy map (1- x) y)
|
||||
(get-xy map x (1+ y))
|
||||
(get-xy map x (1- y))
|
||||
)
|
||||
)
|
||||
|
||||
(defun ratings-update (ratings map h)
|
||||
(let ((nr (make-array (array-dimensions ratings) :initial-element 0)))
|
||||
(loop
|
||||
for pt in (find-heights h map)
|
||||
do
|
||||
(let ((x (car pt))
|
||||
(y (cdr pt)))
|
||||
(setf (aref nr x y) (if (= h 9) 1 (sum-surrounding ratings x y))))
|
||||
|
||||
)
|
||||
nr))
|
||||
|
||||
(defun ratings (map)
|
||||
(let ((ratings (make-array (array-dimensions map) :initial-element 0)))
|
||||
(loop
|
||||
for h from 9 downto 0
|
||||
do (setf ratings (ratings-update ratings map h)))
|
||||
ratings))
|
||||
|
||||
(defun rating (map)
|
||||
(loop for r across (aops:flatten (ratings map)) sum r)
|
||||
)
|
||||
|
||||
(defun part1 (data)
|
||||
(format nil "~A" (score data)))
|
||||
|
||||
(defun part2 (data)
|
||||
(format nil "~A" (rating data)))
|
||||
|
||||
(defun solve-day ()
|
||||
(format t "part1: ~A~%" (part1 input-data))
|
||||
(format t "part2: ~A~%" (part2 input-data)))
|
||||
|
||||
(defun submit ()
|
||||
(let ((p1 (part1 input-data))
|
||||
(p2 (part2 input-data)))
|
||||
(if p1 (submit-part1 2024 10 p1))
|
||||
(if p2 (submit-part2 2024 10 p2))))
|
16
tests/2024/day10-test.lisp
Normal file
16
tests/2024/day10-test.lisp
Normal file
|
@ -0,0 +1,16 @@
|
|||
(defpackage :aoc/2024/10/tests
|
||||
(:use :cl :aoc :aoc/tests :aoc/2024/tests :parachute :aoc/2024/10))
|
||||
|
||||
(in-package :aoc/2024/10/tests)
|
||||
|
||||
(define-test suite-2024-10
|
||||
;:parent suite-2024
|
||||
)
|
||||
|
||||
(define-test+run test-part1
|
||||
:parent suite-2024-10
|
||||
(is equal "36" (part1 sample-data)))
|
||||
|
||||
(define-test+run test-part2
|
||||
:parent suite-2024-10
|
||||
(is equal "81" (part2 sample-data)))
|
Loading…
Reference in a new issue