From d578f1035e5ca7284523721496948da851be18fc Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Wed, 1 Nov 2023 18:58:39 -0500 Subject: [PATCH] hit a bit of a dead end. Can build a tree, but traversing it is HARD. API sucks too. Might start over. --- src/day07/file_tree.rs | 147 ++++++++++++++++++++++--- src/day07/parser.rs | 238 ++++++++++++++++++++--------------------- src/day07/part1.rs | 18 ++-- src/day07/part2.rs | 18 ++-- 4 files changed, 270 insertions(+), 151 deletions(-) diff --git a/src/day07/file_tree.rs b/src/day07/file_tree.rs index 147b42f..3d717c5 100644 --- a/src/day07/file_tree.rs +++ b/src/day07/file_tree.rs @@ -1,35 +1,30 @@ #![allow(unused)] use std::{ cell::RefCell, + fmt::{Debug, Display}, + iter, ops::Deref, rc::{Rc, Weak}, + slice::Iter, }; -// #[derive(Debug)] -// pub struct NodeRef(Rc>); - -#[derive(Debug)] +//these cant be just a type, as methods need to be impl'd on them. pub struct FileRef(Rc>); - -#[derive(Debug)] pub struct DirRef(Rc>); -#[derive(Debug)] pub struct WeakDirRef(Weak>); -#[derive(Debug)] pub enum Node { Dir(DirRef), File(FileRef), } -#[derive(Debug)] pub struct File { parent: WeakDirRef, pub name: String, pub size: usize, } -#[derive(Debug, Default)] +#[derive(Default)] pub struct Dir { parent: Option, pub name: String, @@ -50,6 +45,7 @@ impl DirRef { }) .sum() } + fn new(name: String) -> Self { DirRef(Rc::new(RefCell::new(Dir { parent: None, @@ -59,19 +55,41 @@ impl DirRef { } //needs to be impled on the ref because of the need to get a weak backreference to self. - fn add(&self, node: Node) { + fn add(&self, node: Node) -> Node { + let ret; match node { Node::Dir(ref dir) => { - dir.0.borrow_mut().parent = Some(WeakDirRef(Rc::downgrade(&self.0))) + dir.0.borrow_mut().parent = Some(WeakDirRef(Rc::downgrade(&self.0))); + ret = Node::Dir(DirRef(Rc::clone(&dir.0))); + } + Node::File(ref file) => { + file.0.borrow_mut().parent = WeakDirRef(Rc::downgrade(&self.0)); + ret = Node::File(FileRef(Rc::clone(&file.0))); } - Node::File(ref file) => file.0.borrow_mut().parent = WeakDirRef(Rc::downgrade(&self.0)), } self.0.borrow_mut().children.push(node); + ret + } + + //because a file always has a parent, it needs to be created off of a node. + fn new_file(&self, name: String, size: usize) -> FileRef { + let file = File { + parent: WeakDirRef(Rc::downgrade(&self.0)), + name, + size, + }; + let file_ref = FileRef(Rc::new(RefCell::new(file))); + //have to unpack and repack to make a copy. + self.0 + .borrow_mut() + .children + .push(Node::File(FileRef(Rc::clone(&file_ref.0)))); + file_ref } } impl File { - fn get_parent(&self)-> &WeakDirRef { + fn get_parent(&self) -> &WeakDirRef { &self.parent } } @@ -85,3 +103,104 @@ impl Dir { &self.parent } } + +impl Node { + fn get_dir(&self) -> Option { + match self { + Node::Dir(dir) => Some(DirRef(Rc::clone(&dir.0))), + Node::File(_) => None, + } + } +} + +//transparent +impl Debug for DirRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // f.debug_tuple("DirRef").field(self.0.borrow().deref()).finish() + let this = self.0.borrow(); + write!(f, "{:?}", this); + Ok(()) + } +} + +//transparent +impl Debug for FileRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // f.debug_tuple("FileRef").field(self.0.borrow().deref()).finish() + let this = self.0.borrow(); + write!(f, "{:?}", this); + Ok(()) + } +} + +impl Debug for File { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // f.debug_struct("File") + // .field("name", &self.name) + // .field("size", &self.size) + // .finish() + write!(f, "- {} (file, size = {})", self.name, self.size); + Ok(()) + } +} + +impl Debug for Node { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // match self { + // Self::Dir(arg0) => f.debug_tuple("Dir").field(arg0).finish(), + // Self::File(arg0) => f.debug_tuple("File").field(arg0).finish(), + // } + match self { + Node::Dir(dir) => write!(f, "{:?}", dir), + Node::File(file) => write!(f, "{:?}", file), + } + } +} + +impl Debug for Dir { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // f.debug_struct("Dir") + // .field("name", &self.name) + // .field("children", &self.children) + // .finish() + writeln!(f, "- {} (dir)", self.name); + for node in &self.children { + //padding + for (index, line) in format!("{:#?}", node).lines().enumerate() { + writeln!(f, " {line}")?; + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn dir_tree_sizes() { + let root = DirRef::new("/".to_string()); + let a = root.add(Node::Dir(DirRef::new("a".to_string()))); + let e = a + .get_dir() + .unwrap() + .add(Node::Dir(DirRef::new("e".to_string()))); + let i = e.get_dir().unwrap().new_file("i".to_string(), 584); + let f = a.get_dir().unwrap().new_file("f".to_string(), 29116); + let g = a.get_dir().unwrap().new_file("g".to_string(), 2557); + let h = a.get_dir().unwrap().new_file("h.lst".to_string(), 62596); + let b = root.new_file("b.txt".to_string(), 14848514); + let c = root.new_file("c.txt".to_string(), 8504156); + let d = root.add(Node::Dir(DirRef::new("a".to_string()))); + let j = d.get_dir().unwrap().new_file("j".to_string(), 4060174); + let dlog = d.get_dir().unwrap().new_file("d.log".to_string(), 8033020); + let dext = d.get_dir().unwrap().new_file("d.ext".to_string(), 5626152); + let k = d.get_dir().unwrap().new_file("k".to_string(), 7214296); + println!("{:#?}", root); + assert_eq!(e.get_dir().unwrap().total_size(), 584); + assert_eq!(a.get_dir().unwrap().total_size(), 94853); + assert_eq!(d.get_dir().unwrap().total_size(), 24933642); + assert_eq!(root.total_size(), 48381165) + } +} diff --git a/src/day07/parser.rs b/src/day07/parser.rs index ff597d9..4a05093 100644 --- a/src/day07/parser.rs +++ b/src/day07/parser.rs @@ -35,122 +35,122 @@ pub fn parse_to_commands(input: &str) -> Vec { unimplemented!() } -#[cfg(test)] -mod tests { - use super::*; - - /* #[test] - fn test_parse() { - let input = "$ cd / -$ ls -dir a -14848514 b.txt -8504156 c.dat -dir d -$ cd a -$ ls -dir e -29116 f -2557 g -62596 h.lst -$ cd e -$ ls -584 i -$ cd .. -$ cd .. -$ cd d -$ ls -4060174 j -8033020 d.log -5626152 d.ext -7214296 k"; - assert_eq!(parse(input), 0); - } */ - - #[test] - fn test_parse_to_commands() { - let input = "$ cd / -$ ls -dir a -14848514 b.txt -8504156 c.dat -dir d -$ cd a -$ ls -dir e -29116 f -2557 g -62596 h.lst -$ cd e -$ ls -584 i -$ cd .. -$ cd .. -$ cd d -$ ls -4060174 j -8033020 d.log -5626152 d.ext -7214296 k"; - assert_eq!( - parse_to_commands(input), - vec![ - Command::CdRoot, - Command::Ls(vec![ - LsEntry::Dir(String::from("a")), - LsEntry::File(ParseFile { - size: 14848514, - name: String::from("b.txt") - }), - LsEntry::File(ParseFile { - size: 8504156, - name: String::from("c.dat") - }), - LsEntry::Dir(String::from("d")) - ]), - Command::Cd(String::from("a")), - Command::Ls(vec![ - LsEntry::Dir(String::from("e")), - LsEntry::File(ParseFile { - size: 29116, - name: String::from("f") - }), - LsEntry::File(ParseFile { - size: 2557, - name: String::from("g") - }), - LsEntry::File(ParseFile { - size: 62596, - name: String::from("h.lst") - }), - ]), - Command::Cd(String::from("e")), - Command::Ls(vec![LsEntry::File(ParseFile { - size: 484, - name: String::from("i") - }),]), - Command::CdUp, - Command::CdUp, - Command::Cd(String::from("d")), - Command::Ls(vec![ - LsEntry::File(ParseFile { - size: 4060174, - name: String::from("j") - }), - LsEntry::File(ParseFile { - size: 8033020, - name: String::from("d.log") - }), - LsEntry::File(ParseFile { - size: 5626152, - name: String::from("d.ext") - }), - LsEntry::File(ParseFile { - size: 7214296, - name: String::from("k") - }), - ]), - ] - ) - } -} +// #[cfg(test)] +// mod tests { +// use super::*; +// +// /* #[test] +// fn test_parse() { +// let input = "$ cd / +// $ ls +// dir a +// 14848514 b.txt +// 8504156 c.dat +// dir d +// $ cd a +// $ ls +// dir e +// 29116 f +// 2557 g +// 62596 h.lst +// $ cd e +// $ ls +// 584 i +// $ cd .. +// $ cd .. +// $ cd d +// $ ls +// 4060174 j +// 8033020 d.log +// 5626152 d.ext +// 7214296 k"; +// assert_eq!(parse(input), 0); +// } */ +// +// #[test] +// fn test_parse_to_commands() { +// let input = "$ cd / +// $ ls +// dir a +// 14848514 b.txt +// 8504156 c.dat +// dir d +// $ cd a +// $ ls +// dir e +// 29116 f +// 2557 g +// 62596 h.lst +// $ cd e +// $ ls +// 584 i +// $ cd .. +// $ cd .. +// $ cd d +// $ ls +// 4060174 j +// 8033020 d.log +// 5626152 d.ext +// 7214296 k"; +// assert_eq!( +// parse_to_commands(input), +// vec![ +// Command::CdRoot, +// Command::Ls(vec![ +// LsEntry::Dir(String::from("a")), +// LsEntry::File(ParseFile { +// size: 14848514, +// name: String::from("b.txt") +// }), +// LsEntry::File(ParseFile { +// size: 8504156, +// name: String::from("c.dat") +// }), +// LsEntry::Dir(String::from("d")) +// ]), +// Command::Cd(String::from("a")), +// Command::Ls(vec![ +// LsEntry::Dir(String::from("e")), +// LsEntry::File(ParseFile { +// size: 29116, +// name: String::from("f") +// }), +// LsEntry::File(ParseFile { +// size: 2557, +// name: String::from("g") +// }), +// LsEntry::File(ParseFile { +// size: 62596, +// name: String::from("h.lst") +// }), +// ]), +// Command::Cd(String::from("e")), +// Command::Ls(vec![LsEntry::File(ParseFile { +// size: 484, +// name: String::from("i") +// }),]), +// Command::CdUp, +// Command::CdUp, +// Command::Cd(String::from("d")), +// Command::Ls(vec![ +// LsEntry::File(ParseFile { +// size: 4060174, +// name: String::from("j") +// }), +// LsEntry::File(ParseFile { +// size: 8033020, +// name: String::from("d.log") +// }), +// LsEntry::File(ParseFile { +// size: 5626152, +// name: String::from("d.ext") +// }), +// LsEntry::File(ParseFile { +// size: 7214296, +// name: String::from("k") +// }), +// ]), +// ] +// ) +// } +// } diff --git a/src/day07/part1.rs b/src/day07/part1.rs index 1f5e47a..69753ef 100644 --- a/src/day07/part1.rs +++ b/src/day07/part1.rs @@ -6,12 +6,12 @@ pub fn part1() -> usize { unimplemented!() } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_part1() { - assert_eq!(part1(), 0); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; +// +// #[test] +// fn test_part1() { +// assert_eq!(part1(), 0); +// } +// } diff --git a/src/day07/part2.rs b/src/day07/part2.rs index c4f18d4..177e70a 100644 --- a/src/day07/part2.rs +++ b/src/day07/part2.rs @@ -6,12 +6,12 @@ pub fn part2() -> usize { unimplemented!() } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_part2() { - assert_eq!(part2(), 0); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; +// +// #[test] +// fn test_part2() { +// assert_eq!(part2(), 0); +// } +// }