advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

day-5.lisp (1266B)


      1 (defpackage #:aoc/day-5
      2   (:use #:cl #:aoc/utils)
      3   (:export #:day-5))
      4 (in-package #:aoc/day-5)
      5 
      6 (defun parse-rule (line)
      7   (mapcar #'parse-integer
      8           (uiop:split-string line :separator '(#\|))))
      9 
     10 (defun parse-update (line)
     11   (mapcar #'parse-integer
     12           (uiop:split-string line :separator '(#\,))))
     13 
     14 (defun order-update (update rule-map)
     15   (sort update (lambda (first second)
     16                  (not (gethash (list second first) rule-map)))))
     17 
     18 (defun middle-page-number (update)
     19   (nth (floor (length update) 2) update))
     20 
     21 (defun process-updates (input rule-map)
     22   (loop for line = (read-line input nil)
     23         until (null line)
     24         for update = (parse-update line)
     25         for sorted = (order-update (copy-seq update) rule-map)
     26         for middle = (middle-page-number sorted)
     27         if (seq= update sorted)
     28           sum middle into task-1
     29         else
     30           sum middle into task-2
     31         finally (return (values task-1 task-2))))
     32 
     33 (defun day-5 (input)
     34   (loop with rule-map = (make-hash-table :test #'equal)
     35         with task-1 = 0
     36         with task-2 = 0
     37         for line = (read-line input nil)
     38         when (string= line "")
     39           do (return (process-updates input rule-map))
     40         do (setf (gethash (parse-rule line) rule-map) t)))