Pretty naive memoization for turn outcomes to solve part 2
This commit is contained in:
parent
9ba9242e3c
commit
cd08ef848b
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue