advent-of-code/2018/day09/day09.ss
2024-11-12 21:46:18 +01:00

61 lines
1.8 KiB
Scheme

(import :std/srfi/1)
(export main)
(def (rotate-right deque k)
(def left (car deque))
(def right (cadr deque))
(if (= k 0)
deque
(if (null? right)
(rotate-right [[] (reverse left)] k)
(rotate-right [(cons (car right) left) (cdr right)] (1- k)))))
(def (rotate-left deque k)
(def left (car deque))
(def right (cadr deque))
(if (= k 0)
deque
(if (null? left)
(rotate-left [(reverse right) '()] k)
(rotate-left [(cdr left) (cons (car left) right)] (1- k)))))
(def (deque-car deque)
(match deque
([left right] (car right))))
(def (deque-cdr deque)
(match deque
([left right] [left (cdr right)])))
(def (deque-cons x deque)
(match deque
([left right] [left (cons x right)])))
(def (display-deque deque)
(displayln (reverse (car deque)) " " (cadr deque)))
(def (play circle marbles scores player)
;; (display-deque circle)
(match marbles
([] scores)
([marble . rest]
(def new-player (remainder (1+ player) (vector-length scores)))
(if (= 0 (remainder marble 23))
(let ((new-circle (rotate-left circle 7)))
(vector-set! scores player (+ marble (deque-car new-circle) (vector-ref scores player)))
(play (deque-cdr new-circle) (cdr marbles) scores new-player))
(let ((new-circle (deque-cons marble (rotate-right circle 2))))
(play new-circle (cdr marbles) scores new-player))))))
(def (marbles-game n-players last-marble)
(apply max (vector->list (play [[] [0]] (iota last-marble 1) (make-vector n-players 0) 0))))
(def (main (n-players "9") (last-marble "25") . args)
(displayln (marbles-game 9 25))
(displayln (marbles-game 10 1618))
(displayln (marbles-game 13 7999))
(displayln (marbles-game 17 1104))
(displayln (marbles-game 21 6111))
(displayln (marbles-game 30 5807))
(displayln (marbles-game (string->number n-players) (string->number last-marble))))