Skip to content

Instantly share code, notes, and snippets.

@qookei
Created December 13, 2024 17:49
Show Gist options
  • Save qookei/e698a8c32af61166dde82142d6357ca3 to your computer and use it in GitHub Desktop.
Save qookei/e698a8c32af61166dde82142d6357ca3 to your computer and use it in GitHub Desktop.
(use-modules (srfi srfi-1)
(ice-9 match) (ice-9 peg)
(ice-9 textual-ports)
(ice-9 pretty-print))
(define-peg-string-patterns
"top <-- (entry NL?)* !.
entry <-- button NL button NL prize NL
prize <-- PRIZE vec
button <-- BUTTON ('A'/'B') COLON vec
vec <-- X number COMMA Y number
number <-- [0-9]+
X < 'X' ('+'/'=')
Y < 'Y' ('+'/'=')
BUTTON < 'Button '
PRIZE < 'Prize: '
COLON < ': '
COMMA < ', '
NL < '\n'
")
(define (parse-number num)
(string->number (second num)))
(define (parse-vec vec)
(cons (parse-number (second vec))
(parse-number (third vec))))
(define (parse-button btn)
(parse-vec (third btn)))
(define (parse-prize prize)
(parse-vec (second prize)))
(define (parse-entry entry)
(list (parse-button (second entry))
(parse-button (third entry))
(parse-prize (fourth entry))))
;; /
;; | a*Xa + b*Xb = Xp
;; | a*Ya + b*Yb = Yp
;; \
;; /
;; | a + b*Xb/Xa = Xp/Xa
;; | a + b*Yb/Ya = Yp/Ya
;; \
;; ----------------------
;; b*Xb/Xa - b*Yb/Ya = Xp/Xa - Yp/Ya
;; b*(Xb/Xa - Yb/Ya) = Xp/Xa - Yp/Ya
;; b = (Xp/Xa - Yp/Ya) / (Xb/Xa - Yb/Ya)
;; =>
;; a + b*Xb/Xa = Xp/Xa
;; a = Xp/Xa - b*Xb/Xa
;; a = (Xp - b*Xb)/Xa
;; Valid solution only if a,b in N_+
(define (win-cost entry)
(match-let* ([(a-button b-button prize) entry]
[b (/ (- (/ (car prize) (car a-button))
(/ (cdr prize) (cdr a-button)))
(- (/ (car b-button) (car a-button))
(/ (cdr b-button) (cdr a-button))))]
[a (/ (- (car prize)
(* b (car b-button)))
(car a-button))]
[cost (+ (* 3 a) b)])
(if (and (integer? a)
(integer? b))
cost
0)))
(define (part2-entry entry)
(list (first entry)
(second entry)
(cons (+ 10000000000000
(car (third entry)))
(+ 10000000000000
(cdr (third entry))))))
(let* ([input (get-string-all (current-input-port))]
[peg-tree (peg:tree (match-pattern top input))]
[entries (map parse-entry (cdr peg-tree))])
(pretty-print (fold + 0 (map win-cost entries)))
(pretty-print (fold + 0 (map (compose win-cost part2-entry) entries))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment