AoC/day21.swift

102 lines
2.6 KiB
Swift
Raw Normal View History

2021-12-21 10:53:36 +01:00
@main
struct Day21: Puzzle {
func run() {
part1()
2021-12-21 11:25:58 +01:00
part2()
2021-12-21 10:53:36 +01:00
}
2021-12-21 11:25:58 +01:00
let player1 = Player(position: 6)
let player2 = Player(position: 7)
2021-12-21 10:53:36 +01:00
func part1() {
var die = Die()
2021-12-21 11:25:58 +01:00
var player1 = player1
var player2 = player2
2021-12-21 10:53:36 +01:00
while true {
2021-12-21 11:25:58 +01:00
if player1.move(die.roll3()) >= 1000 {
2021-12-21 10:53:36 +01:00
print("Part 1: Player 1 won. ", die.rolls * player2.score)
break
}
2021-12-21 11:25:58 +01:00
if player2.move(die.roll3()) >= 1000 {
2021-12-21 10:53:36 +01:00
print("Part 1: Player 2 won. ", die.rolls * player1.score)
break
}
}
}
2021-12-21 11:25:58 +01:00
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 {
2021-12-21 10:53:36 +01:00
var position: Int
var score: Int = 0
2021-12-21 11:25:58 +01:00
mutating func move(_ roll: Int) -> Int {
2021-12-21 10:53:36 +01:00
position = 1 + (position + roll - 1) % 10
score += position
2021-12-21 11:25:58 +01:00
return score
2021-12-21 10:53:36 +01:00
}
}
struct Die {
2021-12-21 11:25:58 +01:00
var rolls = 0
var nextRoll = 1
2021-12-21 10:53:36 +01:00
2021-12-21 11:25:58 +01:00
mutating func roll() -> Int {
defer {
rolls += 1
nextRoll += 1
}
2021-12-21 10:53:36 +01:00
2021-12-21 11:25:58 +01:00
return nextRoll
}
2021-12-21 10:53:36 +01:00
2021-12-21 11:25:58 +01:00
mutating func roll3() -> Int {
roll() + roll() + roll()
}
2021-12-21 10:53:36 +01:00
}
}