refactor day 7 to be more iterator-y

This commit is contained in:
2022-12-08 01:03:28 +01:00
parent 34f39613f8
commit 3bb12b8b15

View File

@@ -11,7 +11,7 @@ pub fn process_part_1(input: &str) -> u32 {
let (_, commands) = parse_commands(input).unwrap(); let (_, commands) = parse_commands(input).unwrap();
let directories = build_directory_tree_from_commands(commands); 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 { pub fn process_part_2(input: &str) -> u32 {
@@ -25,16 +25,16 @@ pub fn process_part_2(input: &str) -> u32 {
directories directories
.values() .values()
.filter(|size| **size >= wanted_space) .filter(|&size| *size >= wanted_space)
.map(|size| *size) .map(|&size| size)
.min() .min()
.unwrap_or(0) .unwrap_or(0)
} }
fn build_directory_tree_from_commands(commands: Vec<Command>) -> BTreeMap<String, u32> { fn build_directory_tree_from_commands(commands: Vec<Command>) -> BTreeMap<String, u32> {
let mut cwd: Vec<&str> = vec![]; commands
let mut directories: BTreeMap<String, u32> = BTreeMap::new(); .iter()
for command in commands { .fold((vec![], BTreeMap::new()), |(mut cwd, mut dirs), command| {
match command { match command {
Command::Cd("/") => { Command::Cd("/") => {
cwd = vec![]; cwd = vec![];
@@ -42,27 +42,31 @@ fn build_directory_tree_from_commands(commands: Vec<Command>) -> BTreeMap<String
Command::Cd("..") => { Command::Cd("..") => {
cwd.pop(); cwd.pop();
} }
Command::Cd(name) => { Command::Cd(dir) => {
cwd.push(name); cwd.push(*dir);
} }
Command::Ls(files) => { Command::Ls(files) => {
for file in files { // We don't actually care about individual files, just sum the files together
match file { // so we aren't looking up the BTreeMap as often
DirEntry::File { name: _name, size } => { let total_size = files
.iter()
.filter_map(|e| match e {
DirEntry::File { size, .. } => Some(size),
_ => None,
})
.sum();
for i in 0..=cwd.len() { for i in 0..=cwd.len() {
directories dirs.entry(cwd[..i].join("/"))
.entry(cwd[..i].join("/")) .and_modify(|f| *f += total_size)
.and_modify(|f| *f += size) .or_insert(total_size);
.or_insert(size);
}
}
_ => {}
} }
} }
} }
}
} (cwd, dirs)
directories })
.1
} }
#[derive(Debug)] #[derive(Debug)]
@@ -74,7 +78,11 @@ enum Command<'a> {
#[derive(Debug)] #[derive(Debug)]
enum DirEntry<'a> { enum DirEntry<'a> {
Dir(&'a str), 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<Command>> { fn parse_commands(input: &str) -> IResult<&str, Vec<Command>> {