mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 12:50:32 +01:00
Finally discovered that pos != new_pos
This commit is contained in:
@@ -7,7 +7,7 @@ use criterion::criterion_main;
|
||||
use criterion::BenchmarkId;
|
||||
use criterion::Criterion;
|
||||
|
||||
const DAYS_IMPLEMENTED: usize = 20;
|
||||
const DAYS_IMPLEMENTED: usize = 21;
|
||||
|
||||
fn read_input(day: usize) -> Vec<u8> {
|
||||
let input_path = format!("inputs/{:02}.txt", day);
|
||||
|
||||
@@ -96,8 +96,57 @@ pub fn part1(input: &mut dyn Read) -> String {
|
||||
(loser_score * rolls).to_string()
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
const MAX_TURNS: usize = 21; // Trivial upper bound, could be lower
|
||||
const ROLLS: [i32; 7] = [3, 4, 5, 6, 7, 8, 9];
|
||||
const FREQS: [u64; 7] = [1, 3, 6, 7, 6, 3, 1];
|
||||
|
||||
fn multiverse_recursive(
|
||||
remaining: &mut [u64],
|
||||
wins: &mut [u64],
|
||||
turn: usize,
|
||||
alive: u64,
|
||||
pos: i32,
|
||||
score: i32,
|
||||
) {
|
||||
for (roll, freq) in ROLLS.into_iter().zip(FREQS) {
|
||||
let new_pos = (pos + roll - 1) % 10 + 1;
|
||||
let new_score = score + new_pos;
|
||||
let new_alive = alive * freq;
|
||||
|
||||
if new_score >= 21 {
|
||||
wins[turn] += new_alive;
|
||||
} else {
|
||||
remaining[turn] += new_alive;
|
||||
multiverse_recursive(remaining, wins, turn + 1, new_alive, new_pos, new_score);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn multiverse(pos: i32) -> ([u64; MAX_TURNS], [u64; MAX_TURNS]) {
|
||||
let mut alive = [0; MAX_TURNS];
|
||||
let mut wins = [0; MAX_TURNS];
|
||||
|
||||
alive[0] = 1;
|
||||
|
||||
multiverse_recursive(&mut alive, &mut wins, 1, 1, pos, 0);
|
||||
|
||||
(wins, alive)
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let (a, b) = read_input(input);
|
||||
|
||||
let (a_wins, a_alive) = multiverse(a);
|
||||
let (b_wins, b_alive) = multiverse(b);
|
||||
|
||||
let a_winner: u64 = a_wins[1..]
|
||||
.into_iter()
|
||||
.zip(b_alive)
|
||||
.map(|(&a, b)| a * b)
|
||||
.sum();
|
||||
let b_winner: u64 = b_wins.into_iter().zip(a_alive).map(|(a, b)| a * b).sum();
|
||||
|
||||
a_winner.max(b_winner).to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -112,4 +161,9 @@ mod tests {
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 739785);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE, 444356092776315u64);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user