Day 21 Part 2

This commit is contained in:
Sven Weidauer 2021-12-21 11:25:58 +01:00
parent 65b3920d51
commit c957038fd7

View file

@ -2,34 +2,80 @@
struct Day21: Puzzle { struct Day21: Puzzle {
func run() { func run() {
part1() part1()
part2()
} }
let player1 = Player(position: 6)
let player2 = Player(position: 7)
func part1() { func part1() {
var die = Die() var die = Die()
var player1 = Player(position: 6) var player1 = player1
var player2 = Player(position: 7) var player2 = player2
while true { while true {
if player1.move(die.roll3()) { if player1.move(die.roll3()) >= 1000 {
print("Part 1: Player 1 won. ", die.rolls * player2.score) print("Part 1: Player 1 won. ", die.rolls * player2.score)
break break
} }
if player2.move(die.roll3()) { if player2.move(die.roll3()) >= 1000 {
print("Part 1: Player 2 won. ", die.rolls * player1.score) print("Part 1: Player 2 won. ", die.rolls * player1.score)
break break
} }
} }
} }
struct Player { func part2() {
var universes: [Universe: Int] = [Universe(player1: player1, player2: player2): 1]
var player1Wins = 0
var player2Wins = 0
while !universes.isEmpty {
var newUniverses: [Universe: Int] = [:]
for (universe, universeCount) in universes {
for (offset, player1RollCount) in rollCounts.enumerated() {
var u = universe
if u.player1.move(offset + minRoll) >= quantumMax {
player1Wins += universeCount * player1RollCount
continue
}
for (offset, player2RollCount) in rollCounts.enumerated() {
var u2 = u
if u2.player2.move(offset + minRoll) >= quantumMax {
player2Wins += universeCount * player1RollCount * player2RollCount
continue
}
newUniverses[u2, default: 0] += universeCount * player1RollCount * player2RollCount
}
}
}
universes = newUniverses
}
print("Part 2: ", max(player1Wins, player2Wins))
}
let quantumMax = 21
let minRoll = 3
// 3 4 5 6 7 8 9
let rollCounts = [1, 3, 6, 7, 6, 3, 1]
struct Universe: Hashable {
var player1: Player
var player2: Player
}
struct Player: Hashable {
var position: Int var position: Int
var score: Int = 0 var score: Int = 0
mutating func move(_ roll: Int) -> Bool { mutating func move(_ roll: Int) -> Int {
position = 1 + (position + roll - 1) % 10 position = 1 + (position + roll - 1) % 10
score += position score += position
return score >= 1000 return score
} }
} }