This commit is contained in:
Max Känner 2022-12-07 15:50:56 +01:00
parent d1be2b22e0
commit 21c07db495
4 changed files with 1188 additions and 2 deletions

56
day7/Cargo.lock generated Normal file
View File

@ -0,0 +1,56 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "blanket"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b04ce3d2372d05d1ef4ea3fdf427da6ae3c17ca06d688a107b5344836276bc3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "day7"
version = "0.1.0"
dependencies = [
"blanket",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
blanket = "0.2"

1015
day7/input.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,117 @@
fn main() {
println!("Hello, world!");
use std::{fs::read_to_string, iter::Peekable, str::Lines};
#[derive(PartialEq, Debug)]
struct File {
name: String,
size: usize,
}
impl File {
fn size(&self) -> usize {
self.size
}
}
#[derive(PartialEq, Debug)]
struct Directory {
path: String,
files: Vec<File>,
}
fn size_of_dir(dirs: &[Directory], dir: &str) -> usize {
dirs.iter()
.filter_map(|d| {
if d.path.contains(dir) {
Some(d.files.iter().map(File::size).sum::<usize>())
} else {
None
}
})
.sum()
}
fn parse_command(
lines: &mut Peekable<Lines>,
cwd: &str,
directorys: &mut Vec<Directory>,
) -> Result<String, String> {
let command = lines.next().unwrap().split_whitespace().collect::<Vec<_>>();
if command.len() < 2 || command[0] != "$" {
return Err("first line is not a command".to_owned());
}
match command[1] {
"cd" => {
if command.len() != 3 {
return Err("cd needs exactly 1 argument".to_owned());
}
match command[2] {
"/" => Ok("/".to_owned()),
".." => {
if cwd == "/" {
Ok(cwd.to_owned())
} else {
let dirs = cwd.split_inclusive('/').collect::<Vec<_>>();
let nwd = dirs[..(dirs.len() - 1)]
.iter()
.fold(String::new(), |s, v| s + v);
Ok(nwd)
}
}
dir => Ok(cwd.to_owned() + dir + "/"),
}
}
"ls" => {
while let Some(line) = lines.peek() {
if line.split_whitespace().collect::<Vec<_>>().first() == Some(&"$") {
break;
}
let line = lines.next().unwrap();
let node = line.split_whitespace().collect::<Vec<_>>();
if node.len() != 2 {
return Err("ls needs two inputs per line".to_owned());
}
match node[0] {
"dir" => directorys.push(Directory {
path: cwd.to_owned() + node[1] + "/",
files: vec![],
}),
size => directorys
.iter_mut()
.find(|d| d.path == cwd)
.unwrap()
.files
.push(File {
name: node[1].to_owned(),
size: size.parse().expect("invalid Size"),
}),
}
}
Ok(cwd.to_owned())
}
_ => Err("unknown command".to_owned()),
}
}
fn main() {
const TOTAL_SPACE: usize = 70000000;
const NEEDED_FREE: usize = 30000000;
let input = read_to_string("input.txt").unwrap();
let mut lines = input.lines().peekable();
let mut dirs = vec![Directory {
path: "/".to_owned(),
files: vec![],
}];
let mut cwd = "/".to_owned();
while lines.peek().is_some() {
cwd = parse_command(&mut lines, &cwd, &mut dirs).expect("invalid input");
}
let sizes = dirs.iter().map(|d| size_of_dir(&dirs, &d.path));
let sol1: usize = sizes.clone().filter(|s| s < &100_000).sum();
println!("{sol1}");
let used = size_of_dir(&dirs, "/");
let free = TOTAL_SPACE - used;
let additional = NEEDED_FREE - free;
println!("{used} Bytes used, {free} Bytes free, {additional} Bytes need to be freed");
let sol2 = sizes.filter(|s| s >= &additional).min().unwrap();
println!("Deleting Directory with size {sol2}");
}