Skip to content

Instantly share code, notes, and snippets.

@neofight78
Last active December 21, 2021 09:39
Show Gist options
  • Save neofight78/9906c65f241e8a33329d9d67824c77fc to your computer and use it in GitHub Desktop.
Save neofight78/9906c65f241e8a33329d9d67824c77fc to your computer and use it in GitHub Desktop.
Advent of Code 2021 - Day 21: Dirac Dice
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