Add Day 7 solution
This commit is contained in:
parent
9cdf54cf59
commit
c10b78d032
|
@ -0,0 +1,123 @@
|
|||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::File;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::str;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FsNode {
|
||||
name: String,
|
||||
is_dir: bool,
|
||||
size: u64,
|
||||
sub_items: HashMap<String, FsNode>
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
let file = File::open("resources/day7input.txt").expect("Input file not found.");
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
let mut current_dir = VecDeque::from([String::from("_")]);
|
||||
let mut root_node = FsNode {
|
||||
name: String::from("_"),
|
||||
is_dir: true,
|
||||
size: 0,
|
||||
sub_items: HashMap::new()
|
||||
};
|
||||
|
||||
let mut current_node = &mut root_node;
|
||||
|
||||
for line in reader.lines() {
|
||||
let linex = line.unwrap();
|
||||
let parts: Vec<&str> = linex.split_whitespace().collect();
|
||||
if parts[0] == "$" {
|
||||
match parts[1] {
|
||||
"cd" => {
|
||||
let dir = parts[2];
|
||||
if dir == "/" {
|
||||
current_dir = VecDeque::from([String::from("_")]);
|
||||
current_node = &mut root_node;
|
||||
} else if dir == ".." {
|
||||
current_dir.pop_back();
|
||||
current_node = find_node_by_path(&mut root_node,VecDeque::from(current_dir.clone())).unwrap();
|
||||
} else {
|
||||
current_dir.push_back(String::from(dir));
|
||||
current_node = current_node.sub_items.get_mut(dir).unwrap();
|
||||
}
|
||||
}
|
||||
"ls" => {}
|
||||
_ => eprintln!("error: invalid command {:?}", parts[1])
|
||||
}
|
||||
} else if parts[0] == "dir" {
|
||||
current_node.sub_items.insert(String::from(parts[1]),FsNode {
|
||||
name: String::from(parts[1]),
|
||||
is_dir: true,
|
||||
size: 0,
|
||||
sub_items: HashMap::new()
|
||||
});
|
||||
} else {
|
||||
current_node.sub_items.insert(String::from(parts[1].to_string()),FsNode {
|
||||
name: String::from(parts[1].to_string()),
|
||||
is_dir: false,
|
||||
size: parts[0].parse::<u64>().unwrap(),
|
||||
sub_items: HashMap::new()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let mut sizes:Vec<u64> = Vec::new();
|
||||
let mut sum: u64 = 0;
|
||||
let mut answer2: u64 = 0;
|
||||
let fs_size: u64 = 70000000;
|
||||
let fs_min_space: u64 = 30000000;
|
||||
let used_space = calculate_dir_sizes(&root_node, &mut sizes);
|
||||
let free_space = fs_size-used_space;
|
||||
println!("used space: {:?}", used_space);
|
||||
println!("free space: {:?}", free_space);
|
||||
|
||||
sizes.sort();
|
||||
for x in sizes {
|
||||
if x <= 100000 {
|
||||
sum += x;
|
||||
}
|
||||
if answer2 == 0 && free_space+x >= fs_min_space {
|
||||
answer2 = x;
|
||||
}
|
||||
}
|
||||
|
||||
println!("Day 7 Answer 1: {:?}", sum);
|
||||
println!("Day 7 Answer 2: {:?}", answer2);
|
||||
}
|
||||
|
||||
fn find_node_by_path(node: &mut FsNode, mut path: VecDeque<String>) -> Option<&mut FsNode> {
|
||||
let name = path.pop_front()?; // Return None if the path is empty
|
||||
if path.len() == 0 && name == "_" {
|
||||
return Some(node);
|
||||
}
|
||||
if name == "_" {
|
||||
return find_node_by_path(node, path);
|
||||
}
|
||||
if let Some(sub_item) = node.sub_items.get_mut(name.as_str()) {
|
||||
return if path.len() == 0 && sub_item.name == name && sub_item.is_dir {
|
||||
Some(sub_item)
|
||||
} else {
|
||||
find_node_by_path(sub_item, path)
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn calculate_dir_sizes(node: &FsNode, dir_sizes: &mut Vec<u64>) -> u64 {
|
||||
let mut sum: u64 = 0;
|
||||
if node.sub_items.len() > 0 {
|
||||
for (_, sub_node) in &node.sub_items {
|
||||
if sub_node.is_dir {
|
||||
let size = calculate_dir_sizes(sub_node, dir_sizes);
|
||||
sum += size;
|
||||
dir_sizes.push(size);
|
||||
} else {
|
||||
sum += sub_node.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
|
@ -6,6 +6,7 @@ mod day3;
|
|||
mod day4;
|
||||
mod day5;
|
||||
mod day6;
|
||||
mod day7;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -19,6 +20,7 @@ fn main() {
|
|||
"day4" => day4::run(),
|
||||
"day5" => day5::run(),
|
||||
"day6" => day6::run(),
|
||||
"day7" => day7::run(),
|
||||
_ => eprintln!("error: invalid day")
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue