Skip to content

Commit a94feec

Browse files
committed
Part 1 solved
1 parent 2438512 commit a94feec

File tree

1 file changed

+72
-54
lines changed

1 file changed

+72
-54
lines changed

src/day_07.rs

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,74 @@
11
use crate::input_reader;
2-
use std::borrow::BorrowMut;
3-
use std::collections::HashMap;
4-
use std::cell::RefCell;
5-
use std::rc::Rc;
2+
use std::{collections::HashMap};
63

74
struct File {
85
name: String,
9-
size: i32
6+
size: usize
107
}
118

12-
struct Dir {
13-
parent: Option<String>,
14-
name: String,
15-
dirs: Vec<String>,
16-
files: Vec<File>
9+
fn finished_mapping(
10+
dirs: &Vec<Vec<&str>>,
11+
dir_size: &HashMap<Vec<&str>, usize>
12+
) -> bool {
13+
for dir in dirs {
14+
if !dir_size.contains_key(dir) {
15+
return false;
16+
}
17+
}
18+
return true;
1719
}
1820

19-
// impl Hash for Dir {
20-
// fn hash<H: Hasher>(&self, state: &mut H) {
21-
// self.name.hash(state);
22-
// }
23-
// }
24-
25-
// impl PartialEq for Dir {
26-
// fn eq(&self, other: &Self) -> bool {
27-
// self.name == other.name
28-
// }
29-
// }
30-
// impl Eq for Dir {}
31-
32-
impl Dir {
33-
pub fn add_file(&mut self, file: File) {
34-
self.files.push(file)
21+
fn part1(
22+
sub_dirs: HashMap<Vec<&str>, Vec<Vec<&str>>>,
23+
files: HashMap<Vec<&str>, Vec<File>>,
24+
root: Vec<&str>
25+
) {
26+
let mut dir_size: HashMap<Vec<&str>, usize> = HashMap::new();
27+
let cursor: &mut Vec<&str> = &mut root.clone();
28+
29+
'map_sub_dir: while !finished_mapping(sub_dirs.get(&root.clone()).unwrap(), &dir_size) {
30+
31+
let mut sum: usize = 0;
32+
33+
// If there are sub_dirs, get the size of each sub_dir. If the size has
34+
// not been calculated, move the cursor into the map and restart the
35+
// count.
36+
for sub_dir in sub_dirs.get(cursor).unwrap() {
37+
if dir_size.contains_key(sub_dir) {
38+
sum += dir_size.get(sub_dir).unwrap();
39+
} else {
40+
cursor.push(sub_dir.last().unwrap());
41+
continue 'map_sub_dir;
42+
}
43+
}
44+
45+
// Compute files
46+
for file in files.get(cursor).unwrap() {
47+
sum += file.size;
48+
}
49+
dir_size.insert(cursor.clone(), sum);
50+
51+
// Now that we've mapped this dir, let's continue mapping the
52+
// parent.
53+
cursor.pop();
3554
}
3655

37-
pub fn add_dir(&mut self, dir: String) {
38-
self.dirs.push(dir)
56+
let mut sum: usize = 0;
57+
for d in dir_size {
58+
if d.1 <= 100000 {
59+
sum += d.1;
60+
}
3961
}
62+
63+
println!("Part 1: {}", sum);
4064
}
4165

4266
pub fn run() {
4367
let input = input_reader::read_file_in_cwd("src/day_07.data");
4468

45-
let root = Dir { parent: None, name: "/".to_string(), dirs: vec![], files: vec![] };
46-
let mut dirs: HashMap<&str, Rc<RefCell<Dir>>> = HashMap::new();
47-
let mut current_dir_name = "/";
48-
dirs.insert(&current_dir_name,Rc::new(RefCell::new(root)));
49-
69+
let mut dirs: HashMap<Vec<&str>, Vec<Vec<&str>>> = HashMap::new();
70+
let mut files: HashMap<Vec<&str>, Vec<File>> = HashMap::new();
71+
let mut path: Vec<&str> = vec![];
5072

5173
// Split the input "$". Each "$" represents an executed command.
5274
let command_and_outputs: Vec<&str> = input.split("$ ").collect();
@@ -57,7 +79,7 @@ pub fn run() {
5779
// The split token will be blank, because the input starts with "$ ",
5880
// so we skip it.
5981
if command_and_output == "" {
60-
return
82+
continue;
6183
}
6284

6385
// The first line between each command execution is the command. The
@@ -70,42 +92,38 @@ pub fn run() {
7092
"cd" => {
7193
let new_dir_name = command_split[1];
7294

73-
// Skip "/", as that's the initial state we are in.
74-
if new_dir_name == "/" {
75-
return;
76-
}
77-
7895
if new_dir_name == ".." {
79-
let thing = dirs.get(current_dir_name).unwrap().borrow();
80-
current_dir_name = thing.parent.as_ref().unwrap().as_str();
81-
return;
96+
path.pop();
97+
continue;
8298
}
8399

84-
current_dir_name = new_dir_name
100+
path.push(new_dir_name);
85101
},
86102
"ls" => {
103+
let mut dir_dirs = vec![];
104+
let mut dir_files = vec![];
87105
let items: Vec<&str> = output.split("\n").collect();
88106
// Using a casual iterator, because I don't know yet how to
89107
// handle mutables and closures at the same time...
90108
for i in 0..items.len() {
91109
let item_info: Vec<&str> = items[i].split(" ").collect();
92110
if item_info[0] == "dir" {
93-
let sub_dir_name = item_info[0];
94-
// let sub_dir = &mut Dir { parent: Some(dir.to_string()), name: sub_dir_name.to_string(), dirs: vec![], files: vec![] };
95-
let current_dir = dirs.get_mut(current_dir_name).unwrap().borrow_mut();
96-
//current_dir.add_dir(sub_dir_name.to_string());
97-
let sub_dir = Box::new(&mut Dir { parent: None, name: "/".to_string(), dirs: vec![], files: vec![] });
98-
// let sub_dir = &mut Dir { parent: Some(current_dir_name.to_string()), name: sub_dir_name.to_string(), dirs: vec![], files: vec![] }
99-
//dirs.insert(sub_dir_name, sub_dir);
100-
} else {
101-
let file_size = item_info[0].parse::<i32>().unwrap();
111+
let sub_dir_name = item_info[1];
112+
let mut path_clone = path.clone();
113+
path_clone.push(sub_dir_name);
114+
dir_dirs.push(path_clone);
115+
} else if let Some(file_size) = item_info[0].parse::<usize>().ok() {
102116
let file_name = item_info[1];
103-
let new_file = File { size: file_size, name: file_name.to_string() };
104-
//dirs.get_mut(current_dir_name).unwrap().add_file(new_file);
117+
let file = File { size: file_size, name: file_name.to_string() };
118+
dir_files.push(file);
105119
}
106120
}
121+
122+
dirs.insert(path.clone(), dir_dirs);
123+
files.insert(path.clone(), dir_files);
107124
},
108125
_ => { /* Do nothing if command is not recognized */ }
109126
};
110127
}
128+
part1(dirs, files, vec!["/"]);
111129
}

0 commit comments

Comments
 (0)