advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

day-8.lisp (2623B)


      1 (defpackage #:aoc/day-8
      2   (:use #:cl #:aoc/utils)
      3   (:export #:day-8))
      4 (in-package #:aoc/day-8)
      5 
      6 (defun find-antennas (map)
      7   (loop with antennas = (make-hash-table)
      8         for x from 0 below (input-map-width map)
      9         do (loop for y from 0 below (input-map-height map)
     10                  for point = (cons x y)
     11                  for cell = (map-cell map point)
     12                  unless (char= cell #\.)
     13                    do (setf (gethash cell antennas)
     14                             (cons point (gethash cell antennas))))
     15         finally (return antennas)))
     16 
     17 (defun antinode-location (location-1 location-2)
     18   (when (equal location-1 location-2)
     19     (return-from antinode-location nil))
     20   (point+ location-1 (point- location-1 location-2)))
     21 
     22 (defun antinode-locations (location-1 location-2 width height)
     23   (when (equal location-1 location-2)
     24     (return-from antinode-locations nil))
     25   (loop with diff = (point- location-1 location-2)
     26         for point = (point+ (or point location-1) diff)
     27         while (point-in-bounds-p point width height)
     28         collect point))
     29 
     30 (defun compute-antinodes (map antennas)
     31   (loop with antinodes-task-1 = (make-hash-table :test #'equal)
     32         with antinodes-task-2 = (make-hash-table :test #'equal)
     33         with map-width = (input-map-width map)
     34         with map-height = (input-map-height map)
     35         for antenna-locations being the hash-values of antennas
     36         do (loop for location-1 in antenna-locations
     37                  do (setf (gethash location-1 antinodes-task-2) t)
     38                  do (loop for location-2 in antenna-locations
     39                           for antinode-task-1 = (antinode-location location-1 location-2)
     40                           when (and antinode-task-1
     41                                     (point-in-bounds-p antinode-task-1 map-width map-height))
     42                             do (setf (gethash antinode-task-1 antinodes-task-1) t)
     43                           do (loop for antinode-task-2 in (antinode-locations location-1
     44                                                                               location-2
     45                                                                               map-width
     46                                                                               map-height)
     47                                    do (setf (gethash antinode-task-2 antinodes-task-2) t))))
     48         finally (return (values (hash-table-count antinodes-task-1)
     49                                 (hash-table-count antinodes-task-2)))))
     50 
     51 (defun day-8 (input)
     52   (let* ((map (make-map input))
     53          (antennas (find-antennas map)))
     54     (compute-antinodes map antennas)))