advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

day-20.lisp (2027B)


      1 (defpackage #:aoc/day-20
      2   (:use #:cl #:aoc/utils)
      3   (:export #:day-20))
      4 (in-package #:aoc/day-20)
      5 
      6 (defparameter *directions* '((1 . 0) (-1 . 0)
      7                              (0 . 1) (0 . -1)))
      8 
      9 (defun find-start-end (map)
     10   (loop with start = nil
     11         with end = nil
     12         for y from 0 below (input-map-height map)
     13         thereis (loop for x from 0 below (input-map-width map)
     14                       for pos = (cons x y)
     15                       for cell = (map-cell map pos)
     16                       when (char= #\S cell)
     17                         do (setf start pos)
     18                       when (char= #\E cell)
     19                         do (setf end pos))
     20         finally (return (values start end))))
     21 
     22 (defun day-20 (input)
     23   (loop with map = (make-map input)
     24         with (start end) = (multiple-value-list (find-start-end map))
     25         with width = (input-map-width map)
     26         with height = (input-map-height map)
     27         with pos = start
     28         with last = nil
     29         with steps = nil
     30         with task-1 fixnum = 0
     31         with task-2 fixnum = 0
     32         for picoseconds fixnum from 0
     33         do (loop for (pos-2 . picoseconds-2) in steps
     34                  for distance = (manhattan-distance pos pos-2)
     35                  for saved fixnum = (- picoseconds (+ (the fixnum picoseconds-2) distance))
     36                  do (when (>= saved 100)
     37                       (when (<= distance 2)
     38                         (incf task-1))
     39                       (when (<= distance 20)
     40                         (incf task-2))))
     41            (push (cons pos picoseconds) steps)
     42         when (equal pos end)
     43           do (return (values task-1 task-2))
     44         do (psetf last pos
     45                   pos (loop for dir in *directions*
     46                             for next = (point+ pos dir)
     47                             when (and (point-in-bounds-p next width height)
     48                                       (not (equal last next))
     49                                       (char/= (map-cell map next) #\#))
     50                               do (return next)))))