61 lines
1.8 KiB
Scheme
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))))
|