aboutsummaryrefslogtreecommitdiff
path: root/racket/aoc2021/day-04/day-04.rkt
blob: c572f740d176332187be518a734a1e78a4a03f5c (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
41
42
43
44
45
46
47
48
49
50
51
#lang racket
(require advent-of-code
         threading
         (only-in algorithms chunks-of))

(define data
  (for/list ([l (in-lines (open-aoc-input (find-session) 2021 4 #:cache (string->path "./cache")))]
             #:unless (equal? l ""))
    l))

(define call-sheet (~> data car (string-split ",") (map string->number _)))
(define bingo-cards
  (~> data cdr (map string-split _) (map (λ (row) (map string->number row)) _) (chunks-of 5)))

(define test-card (first bingo-cards))

(define (mark-card card call)
  (for/list ([row (in-list card)])
    (for/list ([col (in-list row)])
      (if (eq? col call) 'X col))))

(define (check-card card)
  (for/or ([row (in-sequences card (apply map list card))])
    (equal? row '(X X X X X))))

(define (multiply-by-last-call n call)
  (match n
    ['X 0]
    [n (* n call)]))

(define (evaluate-cards cards calls [check (curry ormap check-card)] [exception not])
  (for/fold ([current-cards cards]
             [last-call 0]
             #:result (~> current-cards
                          (findf check-card _)
                          flatten
                          (map (λ (n) (multiply-by-last-call n last-call)) _)
                          (apply + _)))
            ([call (in-list calls)])
    #:break (check current-cards)
    (values (for/list ([card (in-list current-cards)] #:unless (exception card))
              (mark-card card call))
            call)))

;; part 1
(evaluate-cards bingo-cards call-sheet)
;; part 2
(evaluate-cards bingo-cards
                call-sheet
                (λ (cards) (and (= (length cards) 1) (check-card (first cards))))
                check-card)