Added day 7
This commit is contained in:
parent
16a9a199f8
commit
ab84537ca5
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,148 @@
|
|||
use regex::Regex;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Directory {
|
||||
subdirs: HashSet<String>,
|
||||
files: HashMap<String, u32>,
|
||||
}
|
||||
|
||||
impl Directory {
|
||||
fn new() -> Directory {
|
||||
Directory {
|
||||
subdirs: HashSet::new(),
|
||||
files: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_file(&mut self, name: &str, size: u32) {
|
||||
self.files.insert(name.to_owned(), size);
|
||||
}
|
||||
|
||||
fn add_subdir(&mut self, name: &str) {
|
||||
self.subdirs.insert(name.to_owned());
|
||||
}
|
||||
|
||||
fn get_file_sizes(&self) -> u32 {
|
||||
self.files.values().fold(0, |a, b| a + b)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_directory_size(path: &Vec<String>, directories: &HashMap<Vec<String>, Directory>) -> u32 {
|
||||
let mut result = directories[path].get_file_sizes();
|
||||
|
||||
for subdir in directories[path].subdirs.iter() {
|
||||
let mut sub_path = path.clone();
|
||||
sub_path.push(subdir.to_owned());
|
||||
|
||||
result += get_directory_size(&sub_path, directories);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn sum_up_dirs(path: &Vec<String>, directories: &HashMap<Vec<String>, Directory>) -> u32 {
|
||||
let mut result = 0;
|
||||
let own_size = get_directory_size(path, directories);
|
||||
if own_size < 100000 {
|
||||
result += own_size;
|
||||
}
|
||||
|
||||
for subdir in directories[path].subdirs.iter() {
|
||||
let mut sub_path = path.clone();
|
||||
sub_path.push(subdir.to_owned());
|
||||
result += sum_up_dirs(&sub_path, directories);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn find_optimal_deletion(
|
||||
path: &Vec<String>,
|
||||
optimal_size: u32,
|
||||
current_optimum: u32,
|
||||
directories: &HashMap<Vec<String>, Directory>,
|
||||
) -> u32 {
|
||||
let own_size = get_directory_size(path, directories);
|
||||
let mut result = if own_size >= optimal_size && own_size < current_optimum {
|
||||
own_size
|
||||
} else {
|
||||
current_optimum
|
||||
};
|
||||
|
||||
for subdir in directories[path].subdirs.iter() {
|
||||
let mut sub_path = path.clone();
|
||||
sub_path.push(subdir.to_owned());
|
||||
result = find_optimal_deletion(&sub_path, optimal_size, result, directories);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let file = File::open("inputs/day7.txt")?;
|
||||
let mut lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
|
||||
|
||||
let mut directories = HashMap::new();
|
||||
let mut current_path: Vec<String> = Vec::new();
|
||||
|
||||
let cd_re = Regex::new(r"^\$ cd (.+)$").unwrap();
|
||||
let dir_re = Regex::new(r"^dir (.+)$").unwrap();
|
||||
let file_re = Regex::new(r"^([0-9]+) (.+)$").unwrap();
|
||||
|
||||
for line in lines {
|
||||
if let Some(result) = cd_re.captures(&line) {
|
||||
let target = &result[1];
|
||||
if target == "/" {
|
||||
current_path = vec!["/".to_owned()];
|
||||
} else if target == ".." {
|
||||
current_path.pop().unwrap();
|
||||
} else {
|
||||
current_path.push(target.to_owned());
|
||||
}
|
||||
|
||||
if !directories.contains_key(¤t_path) {
|
||||
directories.insert(current_path.clone(), Directory::new());
|
||||
}
|
||||
} else if let Some(result) = dir_re.captures(&line) {
|
||||
directories
|
||||
.get_mut(¤t_path)
|
||||
.unwrap()
|
||||
.add_subdir(&result[1]);
|
||||
let mut subdir_path = current_path.clone();
|
||||
subdir_path.push(result[1].to_owned());
|
||||
if !directories.contains_key(&subdir_path) {
|
||||
directories.insert(subdir_path, Directory::new());
|
||||
}
|
||||
} else if let Some(result) = file_re.captures(&line) {
|
||||
let size: u32 = result[1].parse().unwrap();
|
||||
let name = &result[2];
|
||||
|
||||
directories
|
||||
.get_mut(¤t_path)
|
||||
.unwrap()
|
||||
.add_file(name, size);
|
||||
}
|
||||
}
|
||||
|
||||
let answer1 = sum_up_dirs(&vec!["/".to_owned()], &directories);
|
||||
|
||||
println!("Answer Part1: {}", answer1);
|
||||
|
||||
let unused_space = 70000000 - get_directory_size(&vec!["/".to_owned()], &directories);
|
||||
let minimum_deletion_size = 30000000 - unused_space;
|
||||
|
||||
let answer2 = find_optimal_deletion(
|
||||
&vec!["/".to_owned()],
|
||||
minimum_deletion_size,
|
||||
30000000,
|
||||
&directories,
|
||||
);
|
||||
|
||||
println!("Answer Part2: {}", answer2);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue