diff --git a/y2024/src/days/d20.rs b/y2024/src/days/d20.rs index fa0101b..9ded393 100644 --- a/y2024/src/days/d20.rs +++ b/y2024/src/days/d20.rs @@ -6,26 +6,14 @@ use std::{ use itertools::Itertools; pub fn process_part1(input: &str) -> u32 { - simulate_all(input, 100).values().copied().sum() - //simulate_all(input) - // .iter() - // .map( - // |(time_saved, count)| { - // if *time_saved >= 100 { - // *count - // } else { - // 0 - // } - // }, - // ) - // .sum() + simulate_all(input, 100, 2).values().copied().sum() } pub fn process_part2(input: &str) -> u32 { - simulate_all(input, 100).values().copied().sum() + simulate_all(input, 100, 20).values().copied().sum() } -fn simulate_all(input: &str, time_to_saved: usize) -> HashMap { +fn simulate_all(input: &str, time_to_save: usize, max_cheat_time: usize) -> HashMap { let mut start = (0, 0); let grid = input .lines() @@ -45,15 +33,12 @@ fn simulate_all(input: &str, time_to_saved: usize) -> HashMap { .collect_vec(); let no_cheat = simulate(&grid, start); let mut saved = HashMap::new(); - for (tile_idx, tile) in no_cheat[..no_cheat.len() - time_to_saved] - .iter() - .enumerate() - { - for (cheat_idx, cheat) in no_cheat[tile_idx + time_to_saved..].iter().enumerate() { + for (tile_idx, tile) in no_cheat[..no_cheat.len() - time_to_save].iter().enumerate() { + for (cheat_idx, cheat) in no_cheat[tile_idx..].iter().enumerate() { let manhattan = tile.0.abs_diff(cheat.0) + tile.1.abs_diff(cheat.1); - if manhattan <= 2 { - let time_saved = (time_to_saved + cheat_idx).saturating_sub(2); - if time_saved != 0 { + if manhattan <= max_cheat_time { + let time_saved = cheat_idx - manhattan; + if time_saved >= time_to_save { saved .entry(time_saved as u32) .and_modify(|count| *count += 1) @@ -110,7 +95,6 @@ fn simulate(grid: &[Vec], start: (usize, usize)) -> Vec<(usize, usize) let arrived_reindeer = next_paths.remove(idx); arrived.push(arrived_reindeer); } - //log_maze(&grid, maze_runner); } } visited @@ -192,31 +176,6 @@ impl TryFrom for GridTile { } } -fn log_maze(grid: &[Vec], maze_runner: &MazeRunner) { - for (yidx, row) in grid.iter().enumerate() { - for (xidx, tile) in row.iter().enumerate() { - let contains = { - maze_runner.visited.contains(&(xidx, yidx)) - || maze_runner.visited.contains(&(xidx, yidx)) - || maze_runner.visited.contains(&(xidx, yidx)) - || maze_runner.visited.contains(&(xidx, yidx)) - }; - if contains && !(*tile == GridTile::Start || *tile == GridTile::End) { - print!("O"); - } else if *tile == GridTile::Wall { - print!("#"); - } else if *tile == GridTile::Path { - print!("."); - } else if *tile == GridTile::Start { - print!("S"); - } else if *tile == GridTile::End { - print!("E"); - } - } - println!(); - } -} - #[cfg(test)] mod tests { use std::time::Instant; @@ -245,7 +204,7 @@ mod tests { fn part1() { let now = Instant::now(); println!("Test 2:"); - let result = simulate_all(INPUT, 0); + let result = simulate_all(INPUT, 2, 2); result .iter() .sorted_by(|a, b| a.0.cmp(b.0)) @@ -253,13 +212,14 @@ mod tests { println!("There are {count} cheats that saved {saved} picoseconds"); }); println!("Ran in {}", get_elapsed_string(now.elapsed())); + assert_eq!(result.values().copied().sum::(), 44); } #[test] fn part2() { let now = Instant::now(); println!("Test 2:"); - let result = simulate_all(INPUT, 2); + let result = simulate_all(INPUT, 50, 20); result .iter() .sorted_by(|a, b| a.0.cmp(b.0)) @@ -267,5 +227,6 @@ mod tests { println!("There are {count} cheats that saved {saved} picoseconds"); }); println!("Ran in {}", get_elapsed_string(now.elapsed())); + assert_eq!(result.values().copied().sum::(), 285); } }