aboutsummaryrefslogtreecommitdiff
path: root/aoc2023-racket/day-14/day-14.rkt
blob: d0b7cad8d8a349527cb3c22fbfb7fe7a0907e26f (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
#lang racket

(require advent-of-code
         threading
         "../../jj-aoc.rkt")

(define input
  (~> (fetch-aoc-input (find-session) 2023 14 #:cache #true)
      string-split
      (map string->list _)
      transpose))

(define (roll-boulders board)
  (for/list ([col (in-list board)])
    (~> col (chunks-by (curry equal? #\#)) (append-map (curryr sort char>?) _))))

(define (score board)
  (for*/sum ([col (in-list board)] 
             [(row n) (in-indexed (reverse col))] 
             #:when (equal? row #\O))
            (add1 n)))

;; part 1
(~> input 
    roll-boulders 
    score)

;; part 2
(define (rotate-board xss)
  (~> xss 
      (map reverse _) 
      transpose))

(define (full-cycle board)
  (foldl (λ (_ acc) (~> acc roll-boulders rotate-board)) board (range 4)))

(define (spin-to-win board)
  (define cache (make-hash))
  (define (do-spin board n)
    (match (hash-ref cache board 'not-found)
      ['not-found
       (hash-set! cache board n)
       (do-spin (full-cycle board) (sub1 n))]
      [seen
       (define to-end (modulo n (- seen n)))
       (score (foldl (λ (_ acc) (full-cycle acc)) board (range to-end)))]))
  (do-spin board 1000000000))

(~> input spin-to-win)