advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

day-10.lisp (1947B)


      1 (defpackage #:aoc/day-10
      2   (:use #:cl #:aoc/utils)
      3   (:export #:day-10))
      4 (in-package #:aoc/day-10)
      5 
      6 (defun find-trailheads (map)
      7   (loop for y from 0 below (input-map-height map)
      8         nconc (loop for x from 0 below (input-map-width map)
      9                     for point = (cons x y)
     10                     for cell = (map-cell map point)
     11                     when (char= cell #\0)
     12                       collect point)))
     13 
     14 (defparameter *trail-neighbours*
     15   (list (cons 0 -1)
     16         (cons -1 0)
     17         (cons 1 0)
     18         (cons 0 1)))
     19 
     20 (defun score (map trailhead)
     21   (let ((map-width (input-map-width map))
     22         (map-height (input-map-height map))
     23         (points (make-hash-table :test #'equal))
     24         (rating 0))
     25     (labels ((%walk (pos)
     26                (when (char= (map-cell map pos) #\9)
     27                  (setf (gethash pos points) t)
     28                  (incf rating)
     29                  (return-from %walk nil))
     30                (loop with height = (char-number (map-cell map pos))
     31                      for np in (loop for nd in *trail-neighbours*
     32                                      for np = (point+ pos nd)
     33                                      when (point-in-bounds-p np map-width map-height)
     34                                        collect np)
     35                      for nc = (map-cell map np)
     36                      when (and (not (char= nc #\.))
     37                                (= (- (char-number nc)
     38                                      height)
     39                                   1))
     40                        do (%walk np))))
     41       (%walk trailhead)
     42       (values (length (hash-table-keys points))
     43               rating))))
     44 
     45 (defun day-10 (input)
     46   (loop with map = (make-map input)
     47         with trailheads = (find-trailheads map)
     48         for trailhead in trailheads
     49         for (score rating) = (multiple-value-list (score map trailhead))
     50         sum score into task-1
     51         sum rating into task-2
     52         finally (return (values task-1 task-2))))