This commit is contained in:
Dylan "smellyfis" Thies
2022-12-17 11:49:38 -05:00
parent 545f3422e8
commit 2580cdb10e
2 changed files with 112 additions and 39 deletions

23
day7/input Normal file
View File

@@ -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

View File

@@ -1,47 +1,70 @@
use std::cell::RefCell;
use std::fs::File; use std::fs::File;
use std::rc::Rc;
use std::io::{prelude::*, BufReader}; use std::io::{prelude::*, BufReader};
use std::rc::Rc;
trait Sizer {
fn size(&self) -> usize;
}
#[derive(Clone, Debug)]
struct MyFile { struct MyFile {
name: String, _name: String,
size: usize, size: usize,
} }
struct MyDir <'a>{ impl Sizer for MyFile {
name: String, fn size(&self) -> usize {
objects: Vec<FileSystemTypes<'a>>, self.size
//TODO should this bee reference counted }
parent_dir: Option<&'a MyDir<'a>>,
} }
impl <'a> MyDir<'a> { #[derive(Clone, Debug)]
fn move_up(&self) -> Option<&MyDir>{ struct MyDir {
self.parent_dir name: String,
objects: Vec<FileSystemTypes>,
parent_dir: Option<Rc<RefCell<MyDir>>>,
}
impl MyDir {
fn move_up(&self) -> Option<Rc<RefCell<MyDir>>> {
self.parent_dir.clone()
} }
fn move_down(&self, dir:impl Into<String>) -> Option<&MyDir> { fn move_down(&self, dir: impl Into<String>) -> Option<Rc<RefCell<MyDir>>> {
let dir = dir.into(); let dir = dir.into();
self.objects.iter() Some(
self.objects
.iter()
.filter_map(|x| match x { .filter_map(|x| match x {
FileSystemTypes::MyDir(y) => Some(y), FileSystemTypes::MyDir(y) => Some(y),
_ => None, _ => None,
}) })
.find(|x| x.name == dir) .find(|x| *x.borrow().name == dir)?
.clone(),
)
} }
fn touch(&mut self, name: impl Into<String>, size:usize) { fn touch(&mut self, name: impl Into<String>, size: usize) {
self.objects.push(FileSystemTypes::MyFile(MyFile{name:name.into(), size})); self.objects.push(FileSystemTypes::MyFile(MyFile {
_name: name.into(),
size,
}));
} }
fn mkdir(&'a mut self, name: impl Into<String>) { //has to be a static method...
self.objects.push(FileSystemTypes::MyDir(MyDir::new(name, Some(self)))); fn mkdir(self_: Rc<RefCell<MyDir>>, name: impl Into<String>) {
self_
.borrow_mut()
.objects
.push(FileSystemTypes::MyDir(Rc::new(RefCell::new(MyDir::new(
name,
Some(self_.clone()),
)))));
//me.clone()
} }
fn new(name: impl Into<String>, parent_dir: Option<Rc<RefCell<MyDir>>>) -> Self {
fn new(name: impl Into<String>, parent_dir: Option<&'a MyDir<'a>>) -> Self {
let name: String = name.into(); let name: String = name.into();
let parent_dir = match parent_dir { let parent_dir = parent_dir.map(|x| x.clone());
Some(x) => Some(x),
None => None,
};
MyDir { MyDir {
name, name,
objects: Vec::new(), 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::<usize>()
}
}
enum FileSystemTypes <'a>{ #[derive(Clone, Debug)]
enum FileSystemTypes {
MyFile(MyFile), MyFile(MyFile),
MyDir(MyDir<'a>), MyDir(Rc<RefCell<MyDir>>),
}
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<()> { fn main() -> std::io::Result<()> {
@@ -61,21 +102,23 @@ fn main() -> std::io::Result<()> {
let reader = BufReader::new(file); let reader = BufReader::new(file);
//create root file object on heap //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; let mut ls_mode = false;
//set a pointer to the currently on MyDir, in this case start at roo //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 // loop through the input files lines
reader.lines().for_each(|line| { reader.lines().for_each(|line| {
//need to unwrap the line cause lines() returns an Option //need to unwrap the line cause lines() returns an Option
let line = line.unwrap(); let line = line.unwrap();
//if we are listing files we need to get the information from the input //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 //do adding to cursor
match line.split_whitespace().collect::<Vec<_>>()[..] { match line.split_whitespace().collect::<Vec<_>>()[..] {
["dir", name] => cursor.mkdir(name), ["dir", name] => MyDir::mkdir(cursor.clone(), name),
[size, name] => cursor.touch(name, size.parse::<usize>().unwrap()), [size, name] => cursor
.borrow_mut()
.touch(name, size.parse::<usize>().unwrap()),
_ => panic!("oops {}", line), _ => panic!("oops {}", line),
}; };
// end the for_each // end the for_each
@@ -83,14 +126,21 @@ fn main() -> std::io::Result<()> {
} }
ls_mode = false; ls_mode = false;
//parse all other lines as commands //parse all other lines as commands
match line.split_whitespace().collect::<Vec<_>>()[..] { cursor = match line.split_whitespace().collect::<Vec<_>>()[..] {
["$", "ls"] => ls_mode = true, ["$", "ls"] => {
["$", "cd", "/"] => cursor = Box::from(&root).as_mut(), //set current directory back to root ls_mode = true;
["$", "cd", ".."] => cursor = Box::from(cursor.move_up().unwrap()).as_mut(), cursor.clone()
["$", "cd", dir] => cursor = Box::from(cursor.move_down(dir).unwrap()).as_mut(), }
["$", "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), _ => 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(()) Ok(())
} }