From 2580cdb10e094a6ad4680ea1447e16d339ae0471 Mon Sep 17 00:00:00 2001 From: "Dylan \"smellyfis\" Thies" Date: Sat, 17 Dec 2022 11:49:38 -0500 Subject: [PATCH] stop gap --- day7/input | 23 +++++++++ day7/src/main.rs | 128 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 112 insertions(+), 39 deletions(-) create mode 100644 day7/input diff --git a/day7/input b/day7/input new file mode 100644 index 0000000..09a921e --- /dev/null +++ b/day7/input @@ -0,0 +1,23 @@ +$ 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 diff --git a/day7/src/main.rs b/day7/src/main.rs index 371954c..8f6507a 100644 --- a/day7/src/main.rs +++ b/day7/src/main.rs @@ -1,47 +1,70 @@ +use std::cell::RefCell; use std::fs::File; -use std::rc::Rc; use std::io::{prelude::*, BufReader}; +use std::rc::Rc; +trait Sizer { + fn size(&self) -> usize; +} + +#[derive(Clone, Debug)] struct MyFile { - name: String, + _name: String, size: usize, } -struct MyDir <'a>{ - name: String, - objects: Vec>, - //TODO should this bee reference counted - parent_dir: Option<&'a MyDir<'a>>, +impl Sizer for MyFile { + fn size(&self) -> usize { + self.size + } } -impl <'a> MyDir<'a> { - fn move_up(&self) -> Option<&MyDir>{ - self.parent_dir +#[derive(Clone, Debug)] +struct MyDir { + name: String, + objects: Vec, + parent_dir: Option>>, +} + +impl MyDir { + fn move_up(&self) -> Option>> { + self.parent_dir.clone() } - fn move_down(&self, dir:impl Into) -> Option<&MyDir> { + fn move_down(&self, dir: impl Into) -> Option>> { let dir = dir.into(); - self.objects.iter() - .filter_map(|x| match x { - FileSystemTypes::MyDir(y) => Some(y), - _ => None, - }) - .find(|x| x.name == dir) + Some( + self.objects + .iter() + .filter_map(|x| match x { + FileSystemTypes::MyDir(y) => Some(y), + _ => None, + }) + .find(|x| *x.borrow().name == dir)? + .clone(), + ) } - fn touch(&mut self, name: impl Into, size:usize) { - self.objects.push(FileSystemTypes::MyFile(MyFile{name:name.into(), size})); + fn touch(&mut self, name: impl Into, size: usize) { + self.objects.push(FileSystemTypes::MyFile(MyFile { + _name: name.into(), + size, + })); } - fn mkdir(&'a mut self, name: impl Into) { - self.objects.push(FileSystemTypes::MyDir(MyDir::new(name, Some(self)))); + //has to be a static method... + fn mkdir(self_: Rc>, name: impl Into) { + self_ + .borrow_mut() + .objects + .push(FileSystemTypes::MyDir(Rc::new(RefCell::new(MyDir::new( + name, + Some(self_.clone()), + ))))); + //me.clone() } - - fn new(name: impl Into, parent_dir: Option<&'a MyDir<'a>>) -> Self { + fn new(name: impl Into, parent_dir: Option>>) -> Self { let name: String = name.into(); - let parent_dir = match parent_dir { - Some(x) => Some(x), - None => None, - }; + let parent_dir = parent_dir.map(|x| x.clone()); MyDir { name, objects: Vec::new(), @@ -49,10 +72,28 @@ impl <'a> MyDir<'a> { } } } +impl Sizer for MyDir { + fn size(&self) -> usize { + self.objects + .iter() + .map(|obj| obj.size()) + .sum::() + } +} -enum FileSystemTypes <'a>{ +#[derive(Clone, Debug)] +enum FileSystemTypes { MyFile(MyFile), - MyDir(MyDir<'a>), + MyDir(Rc>), +} + +impl Sizer for FileSystemTypes { + fn size(&self) -> usize { + match self { + FileSystemTypes::MyFile(file) => file.size(), + FileSystemTypes::MyDir(dir) => dir.borrow().size(), + } + } } fn main() -> std::io::Result<()> { @@ -61,21 +102,23 @@ fn main() -> std::io::Result<()> { let reader = BufReader::new(file); //create root file object on heap - let root = MyDir::new("/", None); + let root = Rc::new(RefCell::new(MyDir::new("/", None))); let mut ls_mode = false; //set a pointer to the currently on MyDir, in this case start at roo - let mut cursor = Box::from(&root).as_mut(); + let mut cursor = root.clone(); // loop through the input files lines reader.lines().for_each(|line| { //need to unwrap the line cause lines() returns an Option let line = line.unwrap(); //if we are listing files we need to get the information from the input - if ls_mode && line.as_bytes()[0] != '$' as u8 { + if ls_mode && line.as_bytes()[0] != b'$' { //do adding to cursor match line.split_whitespace().collect::>()[..] { - ["dir", name] => cursor.mkdir(name), - [size, name] => cursor.touch(name, size.parse::().unwrap()), + ["dir", name] => MyDir::mkdir(cursor.clone(), name), + [size, name] => cursor + .borrow_mut() + .touch(name, size.parse::().unwrap()), _ => panic!("oops {}", line), }; // end the for_each @@ -83,14 +126,21 @@ fn main() -> std::io::Result<()> { } ls_mode = false; //parse all other lines as commands - match line.split_whitespace().collect::>()[..] { - ["$", "ls"] => ls_mode = true, - ["$", "cd", "/"] => cursor = Box::from(&root).as_mut(), //set current directory back to root - ["$", "cd", ".."] => cursor = Box::from(cursor.move_up().unwrap()).as_mut(), - ["$", "cd", dir] => cursor = Box::from(cursor.move_down(dir).unwrap()).as_mut(), + cursor = match line.split_whitespace().collect::>()[..] { + ["$", "ls"] => { + ls_mode = true; + cursor.clone() + } + ["$", "cd", "/"] => root.clone(), //set current directory back to root + ["$", "cd", ".."] => cursor.borrow().move_up().unwrap().clone(), + ["$", "cd", dir] => cursor.borrow().move_down(dir).unwrap().clone(), _ => panic!("unknown command {}", line), } }); + let mut part1 = vec![root.borrow().size()]; + // TODO do a recursive function that get current directory size and puts it in vector then go + // into each sub directory + // find all less than 100_000 and sum Ok(()) }