package main import ( "fmt" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToStringSlice() var starting []int for i := range inp { starting = append(starting, int(inp[i][len(inp[i])-1]-'0')) } part1(starting) fmt.Println() part2(starting) } type player struct { number int position, score int } func (p *player) move(spaces int) { p.position = (p.position + spaces) % 10 if p.position == 0 { p.position = 10 } p.score += p.position } type die struct { value int rolls int } func (d *die) roll() int { d.rolls++ d.value++ if d.value > 100 { d.value = 1 } return d.value } func part1(pos []int) { var players []player for i := range pos { players = append(players, player{number: i + 1, position: pos[i]}) } die := die{value: 0} pTurn := 0 for players[0].score < 1000 && players[1].score < 1000 { turn := die.roll() + die.roll() + die.roll() players[pTurn].move(turn) pTurn = (pTurn + 1) % len(players) } var loser player for i := range players { if loser.number == 0 || players[i].score < loser.score { loser = players[i] } } fmt.Println("# Part 1") fmt.Printf("Player %d loses, score %d\n", (loser.number), loser.score*die.rolls) } func part2(pos []int) { var players []player for i := range pos { players = append(players, player{number: i + 1, position: pos[i]}) } diracIt(pos[0], pos[1]) } type gameState struct { p1, p2 int s1, s2 int } // Run the games with the dirac die. func diracIt(p1, p2 int) { move := func(pos, roll int) int { pos += roll pos = pos % 10 if pos == 0 { return 10 } return pos } states := map[gameState]int64{{p1, p2, 0, 0}: 1} rolls := map[int]int64{} for r1 := 1; r1 <= 3; r1++ { for r2 := 1; r2 <= 3; r2++ { for r3 := 1; r3 <= 3; r3++ { rolls[r1+r2+r3] += 1 } } } var p1w, p2w int64 = 0, 0 for len(states) != 0 { for turn := 1; turn <= 2; turn++ { nextStates := map[gameState]int64{} for state, count := range states { for roll, rCount := range rolls { p1, p2 := state.p1, state.p2 s1, s2 := state.s1, state.s2 n := count * rCount if turn == 1 { p1 = move(p1, roll) s1 += p1 if s1 > 20 { p1w += n } else { nextStates[gameState{p1, p2, s1, s2}] += n } } else { p2 = move(p2, roll) s2 += p2 if s2 > 20 { p2w += n } else { nextStates[gameState{p1, p2, s1, s2}] += n } } } } states = nextStates } } fmt.Println("# Part 2") fmt.Printf("Player 1 Wins: %d\nPlayer 2 Wins: %d\n", p1w, p2w) }