-
Notifications
You must be signed in to change notification settings - Fork 0
/
day09.rkt
53 lines (43 loc) · 1.71 KB
/
day09.rkt
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
#lang racket
(struct marble (value left right) #:mutable)
(define (initialize)
(define initial-marble (marble 0 #f #f))
(set-marble-left! initial-marble initial-marble)
(set-marble-right! initial-marble initial-marble)
initial-marble)
(define (insert-marble current value)
(let* ([new-left (marble-right current)]
[new-right (marble-right new-left)]
[new-marble (marble value new-left new-right)])
(set-marble-right! new-left new-marble)
(set-marble-left! new-right new-marble)
new-marble))
(define (remove-marble current)
(let* ([to-remove (for/fold ([m current])
([_ (in-range 7)])
(marble-left m))]
[left-marble (marble-left to-remove)]
[right-marble (marble-right to-remove)])
(set-marble-right! left-marble right-marble)
(set-marble-left! right-marble left-marble)
(values right-marble (marble-value to-remove))))
(define (play players rounds)
(define (current-player rd) (modulo rd players))
(let ([circle (initialize)]
[scores (make-vector (add1 players))])
(for/fold ([current-marble circle]
#:result (apply max (vector->list scores)))
([rd (in-inclusive-range 1 rounds)])
(cond
[(zero? (modulo rd 23))
(define-values (new-current value) (remove-marble current-marble))
(let* ([player (current-player rd)]
[current-score (vector-ref scores player)])
(vector-set! scores player (+ current-score rd value)))
new-current]
[else
(insert-marble current-marble rd)]))))
(define players-nr 410)
(define marbles-nr 72059)
(play players-nr marbles-nr)
(play players-nr (* 100 marbles-nr))