diff --git a/src/main.rs b/src/main.rs index 697cdec..8c700eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ -use advent_of_code::{prob1, prob2, prob3, prob4, prob5, prob6}; +use advent_of_code::{prob1, prob2, prob3, prob4, prob5, prob6, prob7}; +use color_eyre::eyre::Result; -fn main() { +fn main() -> Result<()> { + color_eyre::install()?; { let file_path = "prob1.txt"; let max_part1 = prob1::solve_part1(file_path); @@ -53,4 +55,10 @@ fn main() { let solution = prob6::solve_part2(include_str!("../prob6_part1.txt")); println!("Solution for problem 6 part 2: {solution}"); } + { + let _file_path = "prob7.txt"; + let solution = prob7::solve_part1(include_str!("../prob7.txt"))?; + println!("Solution for problem 7 part 1: {solution}"); + } + Ok(()) } diff --git a/src/prob7.rs b/src/prob7.rs index c55f7e0..6cf4dac 100644 --- a/src/prob7.rs +++ b/src/prob7.rs @@ -1,11 +1,9 @@ -use std::collections::HashMap; - use camino::Utf8PathBuf; -use nom::combinator::all_consuming; +use id_tree::{InsertBehavior, Node, Tree}; use nom::{ branch::alt, bytes::complete::{tag, take_while1}, - combinator::map, + combinator::{all_consuming, map}, sequence::{preceded, separated_pair}, Finish, IResult, }; @@ -46,9 +44,10 @@ impl From for Command { } } -struct Node { - children: HashMap, - size: u32, +#[derive(Debug, Default)] +struct FsEntry { + path: Utf8PathBuf, + size: u64, } fn parse_entry(input: &str) -> IResult<&str, Entry> { @@ -87,7 +86,15 @@ fn parse_line(input: &str) -> IResult<&str, Line> { ))(input) } -pub fn solve_part1(content: &str) { +fn total_size(tree: &Tree, node: &Node) -> color_eyre::Result { + let mut total = node.data().size; + for child in node.children() { + total += total_size(tree, tree.get(child)?)?; + } + Ok(total) +} + +fn generate_tree(content: &str) -> color_eyre::Result> { let lines = content.lines().map(|line| { all_consuming(parse_line)(line) .finish() @@ -95,7 +102,58 @@ pub fn solve_part1(content: &str) { .1 }); + let mut tree = Tree::::new(); + let root = tree.insert( + Node::new(FsEntry { + path: "/".into(), + size: 0, + }), + InsertBehavior::AsRoot, + )?; + let mut curr = root; + for line in lines { println!("{line:?}"); + match line { + Line::Command(cmd) => match cmd { + Command::Ls => {} + Command::Cd(path) => match path.as_str() { + "/" => {} + ".." => { + curr = tree.get(&curr)?.parent().unwrap().clone(); + } + _ => { + curr = tree.insert( + Node::new(FsEntry { + path: path.clone(), + size: 0, + }), + InsertBehavior::UnderNode(&curr), + )?; + } + }, + }, + Line::Entry(entry) => match entry { + Entry::Dir(_) => {} + Entry::File(size, name) => { + curr = tree.insert( + Node::new(FsEntry { path: name, size }), + InsertBehavior::UnderNode(&curr), + )?; + } + }, + } } + Ok(tree) +} + +pub fn solve_part1(content: &str) -> color_eyre::Result { + let tree = generate_tree(content)?; + let sum = tree + .traverse_pre_order(tree.root_node_id().unwrap())? + .filter(|n| !n.children().is_empty()) + .map(|n| total_size(&tree, n).unwrap()) + .filter(|&s| s <= 100_000) + .sum::(); + Ok(sum) }