diff --git a/.gitignore b/.gitignore index beb2254..78e1dfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target -build \ No newline at end of file +build +.vscode \ No newline at end of file diff --git a/rust/day7/exemple b/rust/day7/exemple new file mode 100644 index 0000000..bcbb513 --- /dev/null +++ b/rust/day7/exemple @@ -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 \ No newline at end of file diff --git a/rust/day7/input b/rust/day7/input new file mode 100644 index 0000000..e69de29 diff --git a/rust/day7/maybe/maybe.rs b/rust/day7/maybe/maybe.rs new file mode 100644 index 0000000..5353c7b --- /dev/null +++ b/rust/day7/maybe/maybe.rs @@ -0,0 +1,100 @@ +use std::cell::RefCell; + +#[derive(Clone)] +pub struct File { + size: u64, +} + +impl File { + pub fn new(s: u64) -> File { + File { size: (s) } + } + + pub fn get_size(&self) -> u64 { + self.size + } +} + +#[derive(Clone)] +pub struct Directory { + name: String, + files: Vec, + directories: Vec>, + is_empty: bool, + parent_dir: String, +} + +impl Directory { + pub fn new(n: &str, parent: &str) -> Directory { + Directory { + name: n.to_string(), + files: Vec::new(), + directories: Vec::new(), + is_empty: true, + parent_dir: parent.to_string(), + } + } + + pub fn new_file(&mut self, s: u64) { + self.is_empty = false; + self.files.push(File::new(s)); + } + + pub fn new_directory(&mut self, n: &str) { + self.is_empty = false; + self.directories.push(RefCell::new(Directory::new(n, &self.name))); + } + + pub fn get_name(&self) -> &str { + self.name.as_str() + } + + pub fn get_directory(&mut self, n: &str) -> Option<&mut RefCell> { + self.directories.iter_mut().find(|dir| dir.borrow().get_name() == n) + } + + pub fn get_parent(&mut self) -> &str { + self.parent_dir.as_str() + } + + pub fn print(&self) { + println!("{}", self.name); + for f in self.files.iter() { + println!("File: {}", f.get_size()); + } + for d in self.directories.iter() { + d.borrow().printlevel(1); + } + } + + fn printlevel(&self, level: u64) { + let mut space = String::new(); + for _i in 0..level { + space.push('\t'); + } + println!("{}{}", space.clone().pop().unwrap(), self.name); + for f in self.files.iter() { + println!("{}->File: {}", space, f.get_size()); + } + for d in self.directories.iter() { + d.borrow().printlevel(level + 1); + } + } +} + +fn _main() { + // Root directory doesn't need a parent + let mut root = Directory::new("/", "/"); + root.new_file(146); + root.new_directory("toto"); + root.new_file(14323); + let toto = root.get_directory("toto").unwrap(); + // root il existe plus + toto.borrow().new_file(5472); + toto.borrow().new_directory("tata"); + //let tata = toto.get_directory("tata").unwrap().borrow(); + //tata.new_file(77557); + let root_name = root.get_name(); + toto.borrow().new_file(2426); + println!("Toto Parent: {}", root.get_parent()); +} diff --git a/rust/day7/src/main.rs b/rust/day7/src/main.rs index d0320f3..9d3940a 100644 --- a/rust/day7/src/main.rs +++ b/rust/day7/src/main.rs @@ -1,99 +1,36 @@ -use std::borrow::BorrowMut; +use std::fs::read_to_string; +mod system; -#[derive(Clone)] -pub struct File { - size: u64, -} - -impl File { - pub fn new(s: u64) -> File { - File { size: (s) } - } - - pub fn get_size(&self) -> u64 { - self.size - } -} - -#[derive(Clone)] -pub struct Directory { - name: String, - files: Vec, - directories: Vec, - is_empty: bool, - parent_dir: String, -} - -impl Directory { - pub fn new(n: &str, parent: &str) -> Directory { - Directory { - name: n.to_string(), - files: Vec::new(), - directories: Vec::new(), - is_empty: true, - parent_dir: parent.to_string(), - } - } - - pub fn new_file(&mut self, s: u64) { - self.is_empty = false; - self.files.push(File::new(s)); - } - - pub fn new_directory(&mut self, n: &str) { - self.is_empty = false; - self.directories.push(Directory::new(n, &self.name)); - } - - pub fn get_name(&mut self) -> &str { - self.name.as_str() - } - - pub fn get_directory(&mut self, n: &str) -> Option<&mut Directory> { - self.directories.iter_mut().find(|dir| dir.get_name() == n) - } - - pub fn get_parent(&mut self) -> &str { - self.parent_dir.as_str() - } - - pub fn print(&mut self) { - println!("{}", self.name); - for f in self.files.iter() { - println!("File: {}", f.get_size()); - } - for d in self.directories.iter() { - d.printlevel(1); - } - } - - fn printlevel(&self, level: u64) { - let mut space = String::new(); - for _i in 0..level { - space.push('\t'); - } - println!("{}{}", space.clone().pop().unwrap(), self.name); - for f in self.files.iter() { - println!("{}->File: {}", space, f.get_size()); - } - for d in self.directories.iter() { - d.printlevel(level + 1); +fn decode(cmd: Vec<&str>) -> system::Disk { + let mut index = 1; // ignoring the first cd / + let mut disk = system::Disk::new(); + while index < cmd.len() { + if cmd[index].contains("ls") { + index +=1; + while (index < cmd.len()) && !(cmd[index].contains("ls") || cmd[index].contains("cd")) { + let info : Vec<&str> = cmd[index].split(' ').collect(); + match info[0] { + "dir" => disk.create_directory(info[1]), + &_ => disk.create_file(info[0].parse::().unwrap(),info[1]) + } + index +=1; + } + } else if cmd[index].contains("cd") { + let info : Vec<&str> = cmd[index].split(' ').collect(); + match info[2] { + ".." => disk.goto_parent(), + &_ => disk.change_directory(info[2]) + } + index +=1; + } else { + index += 1; } } + disk } fn main() { - // Root directory doesn't need a parent - let mut root = Directory::new("/", "/"); - root.new_file(146); - root.new_directory("toto"); - root.new_file(14323); - let toto = root.get_directory("toto").unwrap(); - toto.new_file(5472); - toto.new_directory("tata"); - let tata = toto.get_directory("tata").unwrap(); - tata.new_file(77557); - let root_name = root.get_name(); - toto.new_file(2426); - println!("Toto Parent: {}",root.get_parent()); + let file_content = read_to_string("exemple").unwrap(); + let final_disk = decode(file_content.split("\n").collect()); + final_disk.print(); } diff --git a/rust/day7/src/system.rs b/rust/day7/src/system.rs new file mode 100644 index 0000000..c04ecdf --- /dev/null +++ b/rust/day7/src/system.rs @@ -0,0 +1,111 @@ +#[derive(Debug)] +pub struct File { + size: u64, + name: String, +} + +#[derive(Debug)] +pub struct Directory { + name: String, + index: usize, + files: Vec, + child: Vec, + parent: usize, + sublevel: u64, +} + +pub struct Disk { + dir_list: Vec, + selected_dir: usize, +} + +impl Directory { + pub fn new(n: &str, index: usize, parent: usize, sublevel: u64) -> Directory { + Directory { + name: n.to_string(), + index: index, + files: Vec::new(), + child: Vec::new(), + parent: parent, + sublevel: sublevel, + } + } + + pub fn create_file(&mut self, size: u64, name: &str) { + self.files.push(File { + size: size, + name: name.to_string(), + }); + } +} + +impl Disk { + pub fn new() -> Disk { + let mut disk = Disk { + dir_list: Vec::new(), + selected_dir: 0, + }; + disk.dir_list.push(Directory::new("/", 0, 0, 0)); + disk + } + + pub fn create_file(&mut self, size: u64, name: &str) { + self.dir_list[self.selected_dir].create_file(size, name); + } + + pub fn create_directory(&mut self, name: &str) { + let index = self.dir_list.len(); + self.dir_list[self.selected_dir].child.push(index); + self.dir_list.push(Directory::new( + name, + self.dir_list.len(), + self.selected_dir, + self.dir_list[self.selected_dir].sublevel + 1, + )); + } + + pub fn change_directory(&mut self, name: &str) { + let found_index: usize; + match self.dir_list.iter_mut().find(|dir| dir.name == name) { + None => { + println!("There is no such folder '{}' in the disk.", name); + return; + } + Some(found_dir) => found_index = found_dir.index, + } + match self.dir_list[self.selected_dir] + .child + .iter() + .find(|&&index| index == found_index) + { + None => println!( + "There is no such folder '{}' in the directory '{}'", + name, self.dir_list[self.selected_dir].name + ), + Some(&found_index) => self.selected_dir = found_index, + } + } + + pub fn goto_parent(&mut self) { + self.selected_dir = self.dir_list[self.selected_dir].parent; + } + + pub fn print(&self) { + let root = &self.dir_list[0]; + self.printdir(root); + } + + fn printdir(&self, dir: &Directory) { + let mut space = String::new(); + for _ in 0..dir.sublevel { + space.push('\t'); + } + println!("{}{} (dir)", space, dir.name); + for d in &dir.child { + self.printdir(&self.dir_list[*d]) + } + for f in dir.files.iter() { + println!("{}\tFile: {}, size: {}", space, f.name, f.size); + } + } +}