blob: 7a357c59e1c3e97150094d499c035f8e62d65c28 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#lang racket
(require advent-of-code
data/applicative
data/either
data/monad
megaparsack
megaparsack/text
threading)
(struct card (n wins))
(define card/p
(do (string/p "Card")
(many/p space/p)
[n <- integer/p]
(string/p ":")
(many/p space/p)
[winners <- (many-until/p integer/p #:sep (many/p space/p) #:end (try/p (string/p " | ")))]
(many/p space/p)
[has <- (many+/p integer/p #:sep (many/p space/p))]
(pure (card n (set-count (set-intersect (first winners) has))))))
(define raw-cards (~> (open-aoc-input (find-session) 2023 4 #:cache #true) port->lines))
;; part 1
(for/sum ([raw-card (in-list raw-cards)]
#:do [(match-define (success (card _ wins)) (parse-string card/p raw-card))]
#:unless (= wins 0))
(expt 2 (sub1 wins)))
;; part 2
(for/fold ([counts (for/hash ([n (in-inclusive-range 1 (length raw-cards))])
(values n 1))]
#:result (apply + (hash-values counts)))
([raw-card (in-list raw-cards)]
#:do [(match-define (success (card n wins)) (parse-string card/p raw-card))])
(define bonus-range (inclusive-range (+ n 1) (+ n wins)))
(define won-cards (hash-ref counts n))
(foldl (λ (n acc) (hash-update acc n (curry + won-cards))) counts bonus-range))
|