2021 Day 21 Complete
This commit is contained in:
2
2021/day21/input
Normal file
2
2021/day21/input
Normal file
@@ -0,0 +1,2 @@
|
||||
Player 1 starting position: 4
|
||||
Player 2 starting position: 2
|
137
2021/day21/main.go
Normal file
137
2021/day21/main.go
Normal file
@@ -0,0 +1,137 @@
|
||||
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)
|
||||
}
|
2
2021/day21/testinput
Normal file
2
2021/day21/testinput
Normal file
@@ -0,0 +1,2 @@
|
||||
Player 1 starting position: 4
|
||||
Player 2 starting position: 8
|
Reference in New Issue
Block a user