Last active
December 21, 2021 09:39
-
-
Save neofight78/9906c65f241e8a33329d9d67824c77fc to your computer and use it in GitHub Desktop.
Advent of Code 2021 - Day 21: Dirac Dice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn part1() { | |
let mut player_a = Player { | |
position: 1, | |
score: 0, | |
}; | |
let mut player_b = Player { | |
position: 5, | |
score: 0, | |
}; | |
let mut die = 1; | |
while player_b.score < 1000 { | |
player_a.update_after_rolls(&[die, die + 1, die + 2]); | |
die += 3; | |
if player_a.score >= 1000 { | |
break; | |
} | |
player_b.update_after_rolls(&[die, die + 1, die + 2]); | |
die += 3; | |
} | |
let result = usize::min(player_a.score, player_b.score) * (die - 1); | |
println!("The losing score * number of rolls = {}", result); | |
} | |
fn part2() { | |
let player_a = Player { | |
position: 1, | |
score: 0, | |
}; | |
let player_b = Player { | |
position: 5, | |
score: 0, | |
}; | |
let combos = generate_combos(); | |
let (player_a_wins, player_b_wins) = | |
count_wins(player_a, player_b, &combos, &mut HashMap::new()); | |
println!("Player A won {} times.", player_a_wins); | |
println!("Player B won {} times.", player_b_wins); | |
} | |
fn generate_combos() -> Vec<[usize; 3]> { | |
let mut rolls = Vec::new(); | |
for a in 1..=3 { | |
for b in 1..=3 { | |
for c in 1..=3 { | |
rolls.push([a, b, c]); | |
} | |
} | |
} | |
rolls | |
} | |
fn count_wins( | |
current: Player, | |
next: Player, | |
combos: &[[usize; 3]], | |
results: &mut HashMap<(Player, Player), (u64, u64)>, | |
) -> (u64, u64) { | |
if current.score >= 21 { | |
return (1, 0); | |
} | |
if next.score >= 21 { | |
return (0, 1); | |
} | |
if let Some(results) = results.get(&(current, next)) { | |
return *results; | |
} | |
let mut current_win_total = 0; | |
let mut next_win_total = 0; | |
for combo in combos { | |
let mut player = current; | |
player.update_after_rolls(combo); | |
let (next_wins, current_wins) = count_wins(next, player, combos, results); | |
current_win_total += current_wins; | |
next_win_total += next_wins; | |
} | |
results.insert((current, next), (current_win_total, next_win_total)); | |
(current_win_total, next_win_total) | |
} | |
#[derive(Clone, Copy, Eq, Hash, PartialEq)] | |
struct Player { | |
position: usize, | |
score: usize, | |
} | |
impl Player { | |
fn update_after_rolls(&mut self, rolls: &[usize; 3]) { | |
self.position = (((self.position + rolls[0] + rolls[1] + rolls[2]) - 1) % 10) + 1; | |
self.score += self.position; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment