(load "../common.scm") (define (read-starting-positions filename) (call-with-input-file filename (lambda (file) (let* [(player-1 (begin (get-string-n file (string-length "Player 1 starting position: ")) (get-number file))) (player-2 (begin (get-string-n file (string-length "Player 2 starting position: ")) (get-number file)))] ; subtracting one to play with a board numbered 0..9 instead of 1..10, just easier (values (- player-1 1) (- player-2 1)))))) (define (deterministic-dice) (let [(value -1)] (lambda () (set! value (mod (+ value 1) 100)) (+ value 1)))) (define (roll! position-score dice) (set-car! position-score (mod (+ (car position-score) (dice) (dice) (dice)) 10)) (set-cdr! position-score (+ (car position-score) (cdr position-score) 1))) (define (play-deterministic position-1 position-2) (let [(player-1 (cons position-1 0)) (player-2 (cons position-2 0)) (dice (deterministic-dice)) (rolls 0)] (let loop () (roll! player-1 dice) (set! rolls (+ rolls 3)) (if (>= (cdr player-1) 1000) (* (cdr player-2) rolls) (begin (roll! player-2 dice) (set! rolls (+ rolls 3)) (if (>= (cdr player-1) 1000) (* (cdr player-1) rolls) (loop))))))) (define (dirac-dice outcome) (let [(next outcome)] (lambda () (if (null? next) #f (let [(value (car next))] (set! next (cdr next)) value))))) (define (play-dirac position-1 position-2) (let [(player-1 (list (cons position-1 0))) (player-2 (list (cons position-2 0))) (wins-1 0) (wins-2 0)] (let loop () 'no-idea-yet))) (let-values [((position-1 position-2) (read-starting-positions "input"))] (printf "part 1:~% Rolls * Opponent Score = ~a~%" (play-deterministic position-1 position-2)) (printf "part 2:~% Max Winning Universes: ~a~%" (play-dirac position-1 position-2)))