From 3bb12b8b15d0e8249344b79b960f1e0f923cf2d2 Mon Sep 17 00:00:00 2001 From: Jur van den Berg Date: Thu, 8 Dec 2022 01:03:28 +0100 Subject: [PATCH] refactor day 7 to be more iterator-y --- src/day07.rs | 72 +++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/day07.rs b/src/day07.rs index 0bf541c..c73daf6 100644 --- a/src/day07.rs +++ b/src/day07.rs @@ -11,7 +11,7 @@ pub fn process_part_1(input: &str) -> u32 { let (_, commands) = parse_commands(input).unwrap(); let directories = build_directory_tree_from_commands(commands); - directories.values().filter(|size| **size <= 100_000).sum() + directories.values().filter(|&size| *size <= 100_000).sum() } pub fn process_part_2(input: &str) -> u32 { @@ -25,44 +25,48 @@ pub fn process_part_2(input: &str) -> u32 { directories .values() - .filter(|size| **size >= wanted_space) - .map(|size| *size) + .filter(|&size| *size >= wanted_space) + .map(|&size| size) .min() .unwrap_or(0) } fn build_directory_tree_from_commands(commands: Vec) -> BTreeMap { - let mut cwd: Vec<&str> = vec![]; - let mut directories: BTreeMap = BTreeMap::new(); - for command in commands { - match command { - Command::Cd("/") => { - cwd = vec![]; - } - Command::Cd("..") => { - cwd.pop(); - } - Command::Cd(name) => { - cwd.push(name); - } - Command::Ls(files) => { - for file in files { - match file { - DirEntry::File { name: _name, size } => { - for i in 0..=cwd.len() { - directories - .entry(cwd[..i].join("/")) - .and_modify(|f| *f += size) - .or_insert(size); - } - } - _ => {} + commands + .iter() + .fold((vec![], BTreeMap::new()), |(mut cwd, mut dirs), command| { + match command { + Command::Cd("/") => { + cwd = vec![]; + } + Command::Cd("..") => { + cwd.pop(); + } + Command::Cd(dir) => { + cwd.push(*dir); + } + Command::Ls(files) => { + // We don't actually care about individual files, just sum the files together + // so we aren't looking up the BTreeMap as often + let total_size = files + .iter() + .filter_map(|e| match e { + DirEntry::File { size, .. } => Some(size), + _ => None, + }) + .sum(); + + for i in 0..=cwd.len() { + dirs.entry(cwd[..i].join("/")) + .and_modify(|f| *f += total_size) + .or_insert(total_size); } } } - } - } - directories + + (cwd, dirs) + }) + .1 } #[derive(Debug)] @@ -74,7 +78,11 @@ enum Command<'a> { #[derive(Debug)] enum DirEntry<'a> { Dir(&'a str), - File { name: &'a str, size: u32 }, + #[allow(dead_code)] + File { + name: &'a str, + size: u32, + }, } fn parse_commands(input: &str) -> IResult<&str, Vec> {