package main import "fmt" type player struct { position int score int roundsPlayed int } type game struct { players [2]player currentPlayer int winner int winscore int } func main() { n := 6 player1 := player{8, 0, 0} player2 := player{7, 0, 0} part1(player1, player2, n) part2(player1, player2) } func part2(player1 player, player2 player) { diceResultMap := generateDiceResultMap() gameMap := make(map[game]int64) startGame := game{[2]player{player1, player2}, 0, -1, 21} gameMap[startGame] = 1 for i := 0; i < 20; i++ { tmpGameMap := make(map[game]int64) for game, gameAmount := range gameMap { if game.winner == -1 { for diceResult1, diceResultAmount1 := range diceResultMap { tmpGame := game tmpGame.playOneRoung(diceResult1) tmpGameMap[tmpGame] += gameAmount * diceResultAmount1 } } else { tmpGameMap[game] += gameAmount } } gameMap = tmpGameMap printGameMapInfos(gameMap) fmt.Println() } } func printGameMapInfos(gameMap map[game]int64) { fmt.Println(len(gameMap)) var amountGames int64 var winnersPlayer1 int64 var winnersPlayer2 int64 var winSum int64 var bothWinners int64 var noWin int64 for key, val := range gameMap { if key.winner == 0 { winnersPlayer1 += val winSum += val } if key.winner == 1 { winnersPlayer2 += val winSum += val } if key.winner == -1 { noWin += val } amountGames += val } fmt.Printf("Amount Games: %d \n", amountGames) fmt.Printf("Winners: %d \n", winSum) fmt.Printf("Games Winner 1: %d \n", winnersPlayer1) fmt.Printf("Games Winner 2: %d \n", winnersPlayer2) fmt.Printf("Games No Win: %d \n", noWin) fmt.Printf("Games Both Win: %d \n", bothWinners) } func (game *game) playOneRoung(increase int) { if increasePlayer(&game.players[game.currentPlayer], increase, game.winscore) { game.winner = game.currentPlayer } if game.currentPlayer == 1 { game.currentPlayer = 0 } else { game.currentPlayer = 1 } } func generateDiceResultMap() map[int]int64 { tmpDiceResultMap := make(map[int]int64) for a := 1; a < 4; a++ { for b := 1; b < 4; b++ { for c := 1; c < 4; c++ { tmpDiceResultMap[a+b+c] += 1 } } } return tmpDiceResultMap } func part1(player1 player, player2 player, n int) (diceRolls int) { game := game{[2]player{player1, player2}, 0, -1, 1000} for { game.playOneRoung(n) reduceN(&n, &diceRolls) if game.winner != -1 { fmt.Println(min(game.players[0].score, game.players[1].score) * diceRolls) return } } } func reduceN(n *int, counter *int) { *n-- if *n < 0 { *n = 9 } *counter += 3 } func increasePlayer(player *player, n int, winscore int) bool { (*player).position += n if (*player).position > 10 { (*player).position -= 10 } (*player).score += (*player).position (*player).roundsPlayed++ return (*player).score >= winscore } func min(a, b int) int { if a < b { return a } return b }