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)))