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 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<Command>) -> BTreeMap<String, u32> {
let mut cwd: Vec<&str> = vec![];
let mut directories: BTreeMap<String, u32> = 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<Command>> {