Pretty naive memoization for turn outcomes to solve part 2

This commit is contained in:
Daniel Flanagan 2021-12-21 13:19:41 -06:00
parent 9ba9242e3c
commit cd08ef848b
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4

View file

@ -1,29 +1,50 @@
import ./common, std/[sequtils, algorithm, sugar, sets, strformat, strutils, tables, options, json, hashes, random] import ./common, std/[sequtils, algorithm, sugar, sets, strformat, strutils, tables, options, json, hashes, random]
proc p1(input: Lines): uint64 = const BOARD_POSITIONS = 10
const DIE_FACES = 100
const TARGET_SCORE = 1000
const BOARD_POSITIONS = 10
proc p1(input: Lines): uint64 =
var scores = [0, 0] var scores = [0, 0]
var pos = [input[0].split(": ")[1].parseInt - 1, input[1].split(": ")[1].parseInt - 1] var pos = [input[0].split(": ")[1].parseInt - 1, input[1].split(": ")[1].parseInt - 1]
var rollNum = 1 var rollNum = 1
var turn = 0 var turn = 0
while scores[0] < TARGET_SCORE and scores[1] < TARGET_SCORE: while scores[0] < 1000 and scores[1] < 1000:
var move = 0 var move = 0
for _ in 1..3: for _ in 1..3:
move += rollNum mod DIE_FACES move += rollNum mod 100
inc rollNum inc rollNum
pos[turn] = (pos[turn] + move) mod BOARD_POSITIONS pos[turn] = (pos[turn] + move) mod BOARD_POSITIONS
scores[turn] += pos[turn] + 1 scores[turn] += pos[turn] + 1
echo &"{move}, {pos[turn]}, {scores}"
turn = (turn + 1) mod 2 turn = (turn + 1) mod 2
echo rollNum, scores
uint64(scores[turn mod 2] * (rollNum - 1)) uint64(scores[turn mod 2] * (rollNum - 1))
type DiracGamestate = tuple
scores: array[2, int]
positions: array[2, int]
turn: int
var turnOutcomes = newTable[DiracGamestate, array[2, uint64]]()
proc turn(g: DiracGamestate): array[2, uint64] =
if turnOutcomes.hasKey g: return turnOutcomes[g]
if g.scores[0] >= 21:
return [1'u64, 0]
elif g.scores[1] >= 21:
return [0'u64, 1]
for r in product(@[@[1,2,3],@[1,2,3],@[1,2,3]]):
let move = r.foldl(a + b)
var ng = g
ng.positions[ng.turn] = (ng.positions[ng.turn] + move) mod BOARD_POSITIONS
ng.scores[ng.turn] += ng.positions[ng.turn] + 1
ng.turn = (ng.turn + 1) mod 2
let r = turn(ng)
turnOutcomes[ng] = r
result[0] += r[0]
result[1] += r[1]
proc p2(input: Lines): uint64 = proc p2(input: Lines): uint64 =
0 var pos = [input[0].split(": ")[1].parseInt - 1, input[1].split(": ")[1].parseInt - 1]
var g: DiracGamestate = (scores: [0, 0], positions: pos, turn: 0)
let wins = turn(g)
wins.max
const input = """ const input = """
Player 1 starting position: 4 Player 1 starting position: 4