From 47907ef5621130af664c5a8c4bc679b514e0c5fa Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Thu, 8 Dec 2022 00:31:35 +0100 Subject: [PATCH] Alternative implementation that does not use unsafe or a tree structures (is slower however) --- 2022/src/bin/day7_alt.rs | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 2022/src/bin/day7_alt.rs diff --git a/2022/src/bin/day7_alt.rs b/2022/src/bin/day7_alt.rs new file mode 100644 index 0000000..0d9a770 --- /dev/null +++ b/2022/src/bin/day7_alt.rs @@ -0,0 +1,107 @@ +#![feature(test)] +use std::{path::PathBuf, collections::HashMap, ops::AddAssign}; + +use anyhow::Result; +use aoc::Solver; + +// -- Runners -- +fn main() -> Result<()> { + Day::solve() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_test1() -> Result<()> { + Day::test(aoc::Part::ONE, "test-1", 95437) + } + #[test] + fn part1_solution() -> Result<()> { + Day::test(aoc::Part::ONE, "input", 2031851) + } + #[test] + fn part2_test1() -> Result<()> { + Day::test(aoc::Part::TWO, "test-1", 24933642) + } + #[test] + fn part2_solution() -> Result<()> { + Day::test(aoc::Part::TWO, "input", 2568781) + } + + // Benchmarks + extern crate test; + #[bench] + #[ignore] + fn part1_bench(b: &mut test::Bencher) { + Day::benchmark(aoc::Part::ONE, b) + } + #[bench] + #[ignore] + fn part2_bench(b: &mut test::Bencher) { + Day::benchmark(aoc::Part::TWO, b) + } +} + +// -- Helper functions -- +fn process(input: &str) -> Vec { + let mut path = PathBuf::new(); + let mut map = HashMap::new(); + + input + .lines() + .map(|line| line.rsplit_once(" ").unwrap()) + .for_each(|split| { + match split { + ("$ cd", "/") => { path.clear(); }, // Clear the path + ("$ cd", "..") => { path.pop(); }, // Go up one level in the path + ("$ cd", name) => { path.push(name); }, // Enter a directory + ("$", "ls") => {}, + ("dir", _name) => {}, + (size, _name) => { + let mut temp = path.clone(); + while { + // Update the size of the current and all parent directories + map.entry(temp.clone()).or_insert(0).add_assign(size.parse::().unwrap()); + temp.pop() + } {} + }, + } + }); + + map.iter().map(|(_, &size)| size).collect() +} + +// -- Solution -- +pub struct Day; +impl aoc::Solver for Day { + type Output = u32; + fn day() -> u8 { + 7 + } + + fn part1(input: &str) -> Self::Output { + process(input) + .iter() + .filter(|&&size| size < 100000) + .sum() + } + + fn part2(input: &str) -> Self::Output { + let mut sizes = process(input); + sizes.sort(); + + // The root is always the larges directory, so it will end up in the last element + let need_to_free = sizes.last().unwrap() - 40000000; + + sizes.iter() + .find_map(|&size| { + if size > need_to_free { + Some(size) + } else { + None + } + }).unwrap() + } +}