Cleanup for 2022 day 7: Turned into a lib and introduced parse errors
This commit is contained in:
parent
c61f28a057
commit
d3d1566086
2 changed files with 39 additions and 26 deletions
|
@ -1,4 +1,17 @@
|
||||||
use std::fs;
|
use core::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum ParseError {
|
||||||
|
LineMalformed(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ParseError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::LineMalformed(v) => write!(f, "Line is malformed: {v}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct FileSystem {
|
struct FileSystem {
|
||||||
nodes: Vec<Node>,
|
nodes: Vec<Node>,
|
||||||
|
@ -78,7 +91,7 @@ impl FileSystem {
|
||||||
self.nodes[cwd].last_child = Some(NodeID { index: new_node });
|
self.nodes[cwd].last_child = Some(NodeID { index: new_node });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_terminal_output(&mut self, terminal_output: &str) {
|
fn parse_terminal_output(&mut self, terminal_output: &str) -> Result<(), ParseError> {
|
||||||
for line in terminal_output.lines() {
|
for line in terminal_output.lines() {
|
||||||
if line.starts_with("$ cd") {
|
if line.starts_with("$ cd") {
|
||||||
self.cd(&line[5..]);
|
self.cd(&line[5..]);
|
||||||
|
@ -86,8 +99,11 @@ impl FileSystem {
|
||||||
continue;
|
continue;
|
||||||
} else if let Some((size, name)) = line.split_once(' ') {
|
} else if let Some((size, name)) = line.split_once(' ') {
|
||||||
self.ensure_child_exists(name, size.parse().ok());
|
self.ensure_child_exists(name, size.parse().ok());
|
||||||
|
} else {
|
||||||
|
return Err(ParseError::LineMalformed(line.to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_directory_sizes(&self, anchor: NodeID) -> Vec<(String, usize)> {
|
fn get_directory_sizes(&self, anchor: NodeID) -> Vec<(String, usize)> {
|
||||||
|
@ -109,18 +125,13 @@ impl FileSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_file(path: &str) -> String {
|
pub fn run(terminal_output: &str) -> Result<(usize, usize), ParseError> {
|
||||||
fs::read_to_string(path)
|
|
||||||
.expect("File not Found")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn analyze_filesystem(terminal_output: &str) -> (usize, usize) {
|
|
||||||
let mut file_system = FileSystem {
|
let mut file_system = FileSystem {
|
||||||
nodes: Vec::new(),
|
nodes: Vec::new(),
|
||||||
current_working_dir: NodeID { index: 0 },
|
current_working_dir: NodeID { index: 0 },
|
||||||
};
|
};
|
||||||
file_system.init();
|
file_system.init();
|
||||||
file_system.parse_terminal_output(terminal_output);
|
file_system.parse_terminal_output(terminal_output)?;
|
||||||
|
|
||||||
let directory_sizes = file_system.get_directory_sizes(NodeID { index: 0 });
|
let directory_sizes = file_system.get_directory_sizes(NodeID { index: 0 });
|
||||||
let dir_sizes_under_100k_sum: usize = directory_sizes.iter()
|
let dir_sizes_under_100k_sum: usize = directory_sizes.iter()
|
||||||
|
@ -132,27 +143,29 @@ fn analyze_filesystem(terminal_output: &str) -> (usize, usize) {
|
||||||
.filter(|(_, size)| *size>=total_size-40_000_000)
|
.filter(|(_, size)| *size>=total_size-40_000_000)
|
||||||
.map(|(_, size)| *size)
|
.map(|(_, size)| *size)
|
||||||
.min()
|
.min()
|
||||||
.unwrap();
|
.unwrap_or_default();
|
||||||
|
|
||||||
(dir_sizes_under_100k_sum, smallest_dir_to_delete_size)
|
Ok((dir_sizes_under_100k_sum, smallest_dir_to_delete_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[cfg(test)]
|
||||||
let terminal_output = read_file("input");
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
let (dir_sizes_under_100k_sum, smallest_dir_to_delete_size) = analyze_filesystem(&terminal_output);
|
fn read_file(name: &str) -> String {
|
||||||
println!("There are {} Bytes in directories of at most 100 kB total size.", dir_sizes_under_100k_sum);
|
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
|
||||||
println!("The smallest dir that would free up enough space has {} Bytes", smallest_dir_to_delete_size);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sample_input() {
|
fn test_sample() {
|
||||||
let terminal_output = read_file("tests/sample_input");
|
let sample_input = read_file("tests/sample_input");
|
||||||
assert_eq!(analyze_filesystem(&terminal_output), (95437, 24933642));
|
assert_eq!(run(&sample_input), Ok((95437, 24933642)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn challenge_input() {
|
fn test_challenge() {
|
||||||
let terminal_output = read_file("tests/input");
|
let challenge_input = read_file("tests/challenge_input");
|
||||||
assert_eq!(analyze_filesystem(&terminal_output), (1743217, 8319096));
|
assert_eq!(run(&challenge_input), Ok((1743217, 8319096)));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue