From abdebddd8f7b9502fc37efbd3c80b56dcd88869c Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Sat, 18 Nov 2023 18:42:07 -0600 Subject: [PATCH] day 07 complete!!! --- src/day07/file_tree.rs | 24 +++++++++---------- src/day07/input.txt | 1 - src/day07/parser.rs | 13 +++++------ src/day07/part1.rs | 46 +++++++++++++++++++++++++----------- src/day07/part2.rs | 53 +++++++++++++++++++++++++++++++----------- src/day07/solve.rs | 9 ++++--- 6 files changed, 97 insertions(+), 49 deletions(-) diff --git a/src/day07/file_tree.rs b/src/day07/file_tree.rs index 6d54f6e..defa846 100644 --- a/src/day07/file_tree.rs +++ b/src/day07/file_tree.rs @@ -44,12 +44,6 @@ impl From for Rc> { } } -impl Display for NodeRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.borrow()) - } -} - impl NodeRef { pub fn add_node(&mut self, mut node: Node) -> Result { node.set_parent(self); @@ -183,18 +177,24 @@ impl Node { } } +#[derive(Debug)] +enum Contents { + Size(usize), + Children(Vec), +} + +impl Display for NodeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.borrow()) + } +} + impl Display for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "- {} {}", self.name, self.contents) } } -#[derive(Debug)] -pub enum Contents { - Size(usize), - Children(Vec), -} - impl Display for Contents { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/day07/input.txt b/src/day07/input.txt index a8fc774..efd9044 100644 --- a/src/day07/input.txt +++ b/src/day07/input.txt @@ -1028,4 +1028,3 @@ $ cd nwqgchw $ ls 21374 lhfsc.lrh 121726 wdcsgg.cjt - diff --git a/src/day07/parser.rs b/src/day07/parser.rs index 3be66d7..a6e2968 100644 --- a/src/day07/parser.rs +++ b/src/day07/parser.rs @@ -1,6 +1,5 @@ -#![allow(unused)] use std::ops::Deref; -use std::{cell::RefCell, rc::Rc}; +use std::rc::Rc; use crate::file_tree::*; use once_cell::sync::Lazy; @@ -66,7 +65,7 @@ fn parse_ls(lines: &mut std::iter::Peekable>) -> Vec LsEntry::Dir(captures[2].to_string()), - s => LsEntry::File(ParseFile { + _ => LsEntry::File(ParseFile { size: str::parse(&captures[1]).unwrap_or_else(|_| panic!("invalid line {}", line)), name: captures[2].to_string(), }), @@ -76,8 +75,8 @@ fn parse_ls(lines: &mut std::iter::Peekable>) -> Vec Node { - unimplemented!() +pub fn parse(input: &str) -> NodeRef { + commands_to_tree(parse_to_commands(input)) } pub fn commands_to_tree(input: Vec) -> NodeRef { @@ -91,11 +90,11 @@ pub fn commands_to_tree(input: Vec) -> NodeRef { Command::Ls(ls) => { for entry in ls { match entry { - LsEntry::Dir(d) => { + LsEntry::Dir(_) => { //dirs dont exist until you cd into them. } LsEntry::File(f) => { - cursor.add_file(f.name, f.size); + cursor.add_file(f.name, f.size).unwrap(); } }; } diff --git a/src/day07/part1.rs b/src/day07/part1.rs index 69753ef..688f89a 100644 --- a/src/day07/part1.rs +++ b/src/day07/part1.rs @@ -1,17 +1,37 @@ -#![allow(unused)] use crate::file_tree::*; -use crate::parser::*; -pub fn part1() -> usize { - unimplemented!() +pub fn part1(input: NodeRef) -> usize { + let dirs = input.get_all_dirs(); + dirs.iter() + .map(|d| d.borrow().get_total_size()) + .filter(|s| *s <= 100000) + .sum() } -// #[cfg(test)] -// mod tests { -// use super::*; -// -// #[test] -// fn test_part1() { -// assert_eq!(part1(), 0); -// } -// } +#[cfg(test)] +mod tests { + use std::{ops::Deref, rc::Rc}; + + use super::*; + + #[test] + fn test_part1() { + let mut root = NodeRef::new_dir("/".to_string()); + let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap(); + cursor = cursor.add_dir("e".to_string()).unwrap(); + cursor.add_file("i".to_string(), 584).unwrap(); + cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(); + cursor.add_file("f".to_string(), 29116).unwrap(); + cursor.add_file("g".to_string(), 2557).unwrap(); + cursor.add_file("h.lst".to_string(), 62596).unwrap(); + cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(); + cursor.add_file("b.txt".to_string(), 14848514).unwrap(); + cursor.add_file("c.dat".to_string(), 8504156).unwrap(); + cursor = cursor.add_dir("d".to_string()).unwrap(); + cursor.add_file("j".to_string(), 4060174).unwrap(); + cursor.add_file("d.log".to_string(), 8033020).unwrap(); + cursor.add_file("d.ext".to_string(), 5626152).unwrap(); + cursor.add_file("k".to_string(), 7214296).unwrap(); + assert_eq!(part1(root), 95437); + } +} diff --git a/src/day07/part2.rs b/src/day07/part2.rs index 177e70a..bf69baa 100644 --- a/src/day07/part2.rs +++ b/src/day07/part2.rs @@ -1,17 +1,44 @@ -#![allow(unused)] use crate::file_tree::*; -use crate::parser::*; -pub fn part2() -> usize { - unimplemented!() +const TOTAL_SPACE: usize = 70000000; +const NEEDED_SPACE: usize = 30000000; + +pub fn part2(input: NodeRef) -> usize { + let used_space = input.borrow().get_total_size(); + let unused_space = TOTAL_SPACE - used_space; + let space_to_free = NEEDED_SPACE - unused_space; + let dirs = input.get_all_dirs(); + dirs.iter() + .map(|d| d.borrow().get_total_size()) + .filter(|s| *s >= space_to_free) + .min() + .unwrap() } -// #[cfg(test)] -// mod tests { -// use super::*; -// -// #[test] -// fn test_part2() { -// assert_eq!(part2(), 0); -// } -// } +#[cfg(test)] +mod tests { + use std::{ops::Deref, rc::Rc}; + + use super::*; + + #[test] + fn test_part2() { + let mut root = NodeRef::new_dir("/".to_string()); + let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap(); + cursor = cursor.add_dir("e".to_string()).unwrap(); + cursor.add_file("i".to_string(), 584).unwrap(); + cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(); + cursor.add_file("f".to_string(), 29116).unwrap(); + cursor.add_file("g".to_string(), 2557).unwrap(); + cursor.add_file("h.lst".to_string(), 62596).unwrap(); + cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(); + cursor.add_file("b.txt".to_string(), 14848514).unwrap(); + cursor.add_file("c.dat".to_string(), 8504156).unwrap(); + cursor = cursor.add_dir("d".to_string()).unwrap(); + cursor.add_file("j".to_string(), 4060174).unwrap(); + cursor.add_file("d.log".to_string(), 8033020).unwrap(); + cursor.add_file("d.ext".to_string(), 5626152).unwrap(); + cursor.add_file("k".to_string(), 7214296).unwrap(); + assert_eq!(part2(root), 24933642); + } +} diff --git a/src/day07/solve.rs b/src/day07/solve.rs index 893bc3d..74fa7a2 100644 --- a/src/day07/solve.rs +++ b/src/day07/solve.rs @@ -1,4 +1,7 @@ -#![allow(dead_code)] +use std::rc::Rc; + +use crate::file_tree::NodeRef; + mod part1; mod part2; mod parser; @@ -9,8 +12,8 @@ fn main() { let structured_input = parser::parse(input); println!("Part One"); - println!("Result: {}", part1::part1()); + println!("Result: {}", part1::part1(NodeRef(Rc::clone(&structured_input)))); println!("Part Two"); - println!("Result: {}", part2::part2()); + println!("Result: {}", part2::part2(NodeRef(Rc::clone(&structured_input)))); }