blob: 9ca9b1baee5544c97081252299163e8833c26519 (
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
52
53
54
55
56
57
58
59
|
#lang racket
(require threading
memoize)
;; not going to bother importing the data since it's just two lines of text
(define player-1-start 4)
(define player-2-start 6)
(define track (sequence->stream (in-cycle (inclusive-range 1 10))))
(define current-turn (in-cycle (list 'player-1 'player-2)))
(define die-rolls (sequence->stream (in-cycle (inclusive-range 1 100))))
;; part 1
(~> (for/fold ([player-1-score 0]
[player-1-track (stream-tail track (sub1 player-1-start))]
[player-2-score 0]
[player-2-track (stream-tail track (sub1 player-2-start))]
[dice die-rolls]
[last-turn 0]
#:result (list (min player-1-score player-2-score) (* 3 last-turn)))
([turn-count (in-naturals 1)]
[turn-for current-turn]
#:break (or (player-1-score . >= . 1000) (player-2-score . >= . 1000)))
(define rolls (apply + (stream->list (stream-take dice 3))))
(match turn-for
['player-1
(define next-track (stream-tail player-1-track rolls))
(values (+ player-1-score (stream-first next-track))
next-track
player-2-score
player-2-track
(stream-tail dice 3)
turn-count)]
['player-2
(define next-track (stream-tail player-2-track rolls))
(values player-1-score
player-1-track
(+ player-2-score (stream-first next-track))
next-track
(stream-tail dice 3)
turn-count)]))
(apply * _))
;; part 2
(define d3 (list 1 2 3))
(define roll-space (~>> (cartesian-product d3 d3 d3) (map (λ~>> (apply +)))))
(define/memo
(next-turns p1-score p2-score p1-start p2-start)
(cond
[(p1-score . >= . 21) '(1 0)]
[(p2-score . >= . 21) '(0 1)]
[else
(for/fold ([wins '(0 0)]) ([roll (in-list roll-space)])
(define move-to (add1 (modulo (sub1 (+ roll p1-start)) 10)))
(define possible-wins (next-turns p2-score (+ p1-score move-to) p2-start move-to))
(list (+ (first wins) (second possible-wins)) (+ (second wins) (first possible-wins))))]))
(~>> (next-turns 0 0 player-1-start player-2-start) (apply max))
|