day 21 part 2 WIP
This commit is contained in:
@@ -49,13 +49,76 @@
|
||||
(set! next (cdr next))
|
||||
value)))))
|
||||
|
||||
(define (vector-sum vec start end)
|
||||
(vector-fold
|
||||
(lambda (i a x)
|
||||
(if (and (>= i start)
|
||||
(< i end))
|
||||
(+ a x)
|
||||
a))
|
||||
0 vec))
|
||||
|
||||
;;; TODO: handle not playing if opponent already won
|
||||
;;; not loose winning games in the process x_x
|
||||
(define (dirac-roll! ongoings)
|
||||
(let [(new (make-vector 220 0))]
|
||||
; keep the ones that already won
|
||||
(vector-copy! new 210 ongoings 210) ; this should keep winning games, why do I loose some?
|
||||
; for each possible combination of 3 rolls of 3-sided dice
|
||||
(for-each
|
||||
(lambda (dice-1)
|
||||
(for-each
|
||||
(lambda (dice-2)
|
||||
(for-each
|
||||
(lambda (dice-3)
|
||||
; increase scores of ongoing games
|
||||
(vector-for-each
|
||||
(lambda (index ongoing)
|
||||
(when (and (> ongoing 0) (< index 210))
|
||||
(let* [(position (mod index 10))
|
||||
(score (div index 10))
|
||||
(new-position (mod (+ position dice-1 dice-2 dice-3) 10))
|
||||
(new-score (min 21 (+ score new-position 1)))
|
||||
(new-index (+ new-position (* new-score 10)))]
|
||||
(vector-set! new new-index
|
||||
(+ ongoing (vector-ref new new-index))))))
|
||||
ongoings))
|
||||
'(1 2 3)))
|
||||
'(1 2 3)))
|
||||
'(1 2 3))
|
||||
(vector-copy! ongoings 0 new)))
|
||||
|
||||
(define (print-ongoing vec)
|
||||
(vector-for-each
|
||||
(lambda (index ongoing)
|
||||
(when (> ongoing 0)
|
||||
(printf " ~12a games with score ~a at position ~a~%"
|
||||
ongoing (div index 10) (+ (mod index 10) 1))))
|
||||
vec))
|
||||
|
||||
(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)]
|
||||
; the vectors track the number of games going on at given position and score,
|
||||
; where position = index % 10 and score = index / 10
|
||||
; 10 because there are 10 positions on board
|
||||
; max score is 21 so 22 entries total accounting for starting zero
|
||||
; => 10 * 22 = 220 entries
|
||||
(let [(player-1 (make-vector 220 0))
|
||||
(player-2 (make-vector 220 0))]
|
||||
(vector-set! player-1 position-1 1)
|
||||
(vector-set! player-2 position-2 1)
|
||||
(printf "Player 1 starting at ~a, player 2 at ~a~%" position-1 position-2)
|
||||
(let loop ()
|
||||
'no-idea-yet)))
|
||||
(set! wins-1 (dirac-roll! player-1))
|
||||
(set! wins-2 (dirac-roll! player-2))
|
||||
(printf "P1:~%") (print-ongoing player-1)
|
||||
(printf "P2:~%") (print-ongoing player-2)
|
||||
; compute how many games are still going (not reached 21)
|
||||
(if (= (+ (vector-sum player-1 0 210) (vector-sum player-2 0 210)) 0)
|
||||
; sum how many winning games (the ones that reached 21)
|
||||
; and return biggest
|
||||
(max (vector-sum player-1 210 220)
|
||||
(vector-sum player-2 210 220))
|
||||
(loop)))))
|
||||
|
||||
(let-values [((position-1 position-2) (read-starting-positions "input"))]
|
||||
(printf "part 1:~% Rolls * Opponent Score = ~a~%"
|
||||
|
||||
Reference in New Issue
Block a user