day-13.lisp (2160B)
1 (defpackage #:aoc/day-13 2 (:use #:cl #:aoc/utils) 3 (:export #:day-13)) 4 (in-package #:aoc/day-13) 5 6 (defstruct claw-machine 7 (button-a) 8 (button-b) 9 (prize)) 10 11 (defun parse-coord-line (line) 12 (let* ((offset (if (char= (aref line 0) #\P) 1 0)) 13 (colon (position #\: line)) 14 (pair (uiop:split-string (subseq line (+ colon 2)) :separator '(#\,))) 15 (x (first pair)) 16 (y (second pair)) 17 (x (parse-integer x :start (1+ offset))) 18 (y (parse-integer y :start (+ 2 offset)))) 19 (cons x y))) 20 21 (defun parse-claw-machine (input) 22 (let ((l-1 (read-line input nil)) 23 (l-2 (read-line input nil)) 24 (l-3 (read-line input nil))) 25 (read-line input nil) 26 (when (or (null l-1) (null l-2) (null l-3)) 27 (return-from parse-claw-machine nil)) 28 (make-claw-machine :button-a (parse-coord-line l-1) 29 :button-b (parse-coord-line l-2) 30 :prize (parse-coord-line l-3)))) 31 32 (defun parse-claw-machines (input) 33 (loop for machine = (parse-claw-machine input) 34 until (null machine) 35 collect machine)) 36 37 (defun play (machine prize-x prize-y) 38 (let* ((button-a (claw-machine-button-a machine)) 39 (button-b (claw-machine-button-b machine)) 40 (xb (* (point-x button-b) (point-y button-a))) 41 (yb (* (point-y button-b) (point-x button-a))) 42 (px (* prize-x (point-y button-a))) 43 (py (* prize-y (point-x button-a))) 44 (b (/ (- py px) (- yb xb))) 45 (a (/ (- prize-x (* (point-x button-b) b)) 46 (point-x button-a)))) 47 (when (and (integerp a) 48 (integerp b)) 49 (+ (* a 3) b)))) 50 51 (defun day-13 (input) 52 (loop with machines = (parse-claw-machines input) 53 for machine in machines 54 for prize = (claw-machine-prize machine) 55 for prize-x = (point-x prize) 56 for prize-y = (point-y prize) 57 sum (or (play machine prize-x prize-y) 0) into task-1 58 sum (or (play machine 59 (+ prize-x 10000000000000) 60 (+ prize-y 10000000000000)) 61 0) into task-2 62 finally (return (values task-1 task-2))))