Add solution for 2022 day 07
This commit is contained in:
parent
500d952ee3
commit
2ec8b3934e
4
2022/Cargo.lock
generated
4
2022/Cargo.lock
generated
@ -32,6 +32,10 @@ dependencies = [
|
|||||||
"itertools",
|
"itertools",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aoc-2022-07"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
|
@ -6,6 +6,7 @@ members = [
|
|||||||
"./day-04",
|
"./day-04",
|
||||||
"./day-05",
|
"./day-05",
|
||||||
"./day-06",
|
"./day-06",
|
||||||
|
"./day-07",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
| 04 | ✓ | ✓ | [Rust] |
|
| 04 | ✓ | ✓ | [Rust] |
|
||||||
| 05 | ✓ | ✓ | [Rust] |
|
| 05 | ✓ | ✓ | [Rust] |
|
||||||
| 06 | ✓ | ✓ | [Rust] |
|
| 06 | ✓ | ✓ | [Rust] |
|
||||||
| 07 | | | |
|
| 07 | ✓ | ✓ | [Rust] |
|
||||||
| 08 | | | |
|
| 08 | | | |
|
||||||
| 09 | | | |
|
| 09 | | | |
|
||||||
| 10 | | | |
|
| 10 | | | |
|
||||||
|
6
2022/day-07/Cargo.toml
Normal file
6
2022/day-07/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "aoc-2022-07"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
5
2022/day-07/Justfile
Normal file
5
2022/day-07/Justfile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@part PART INPUT_FILE="inputs/puzzle.txt":
|
||||||
|
cargo --quiet run --bin part_{{PART}} -- {{INPUT_FILE}}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cargo clean
|
1052
2022/day-07/inputs/puzzle.txt
Normal file
1052
2022/day-07/inputs/puzzle.txt
Normal file
File diff suppressed because it is too large
Load Diff
23
2022/day-07/inputs/test.txt
Normal file
23
2022/day-07/inputs/test.txt
Normal file
@ -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
|
17
2022/day-07/src/bin/part_one.rs
Normal file
17
2022/day-07/src/bin/part_one.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use aoc_2022_07::{parse_input, path_sizes, DirMap};
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let infile_path = env::args().nth(1).expect("input file");
|
||||||
|
let paths = parse_input(infile_path)?;
|
||||||
|
|
||||||
|
let mut sizes = DirMap::new();
|
||||||
|
path_sizes(&paths, &mut sizes);
|
||||||
|
|
||||||
|
let sum: usize = sizes.values().filter(|&&val| val <= 100_000).sum();
|
||||||
|
|
||||||
|
println!("{sum:#?}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
29
2022/day-07/src/bin/part_two.rs
Normal file
29
2022/day-07/src/bin/part_two.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use aoc_2022_07::{parse_input, path_sizes, DirMap};
|
||||||
|
|
||||||
|
const MAX_DISK_SPACE: usize = 70_000_000;
|
||||||
|
const REQUIRED_SIZE: usize = 30_000_000;
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let infile_path = env::args().nth(1).expect("input file");
|
||||||
|
let paths = parse_input(infile_path)?;
|
||||||
|
|
||||||
|
let mut sizes = DirMap::new();
|
||||||
|
path_sizes(&paths, &mut sizes);
|
||||||
|
|
||||||
|
let used_disk_space = *sizes.get("/").unwrap();
|
||||||
|
let free_disk_space = MAX_DISK_SPACE - used_disk_space;
|
||||||
|
let req_disk_space = REQUIRED_SIZE - free_disk_space;
|
||||||
|
|
||||||
|
let values = sizes
|
||||||
|
.values()
|
||||||
|
.filter(|&&v| v >= req_disk_space)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let smol = values.iter().min().unwrap();
|
||||||
|
|
||||||
|
println!("{smol}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
134
2022/day-07/src/lib.rs
Normal file
134
2022/day-07/src/lib.rs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs::File,
|
||||||
|
io::{self, BufRead, BufReader},
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum Content {
|
||||||
|
File { size: usize, path: String },
|
||||||
|
Dir { path: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Command {
|
||||||
|
ChangeDirectory(String),
|
||||||
|
List,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FileList = Vec<Content>;
|
||||||
|
pub type DirMap<T = FileList> = HashMap<String, T>;
|
||||||
|
|
||||||
|
pub fn parse_input<P>(path: P) -> io::Result<DirMap>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let reader = BufReader::new(file);
|
||||||
|
let mut cwd = String::from("");
|
||||||
|
|
||||||
|
let mut paths = DirMap::new();
|
||||||
|
let mut cur_content = FileList::new();
|
||||||
|
|
||||||
|
for line in reader.lines() {
|
||||||
|
let line = line?;
|
||||||
|
|
||||||
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
|
||||||
|
let cmd = match *parts.first().expect("invalid line") {
|
||||||
|
"$" => {
|
||||||
|
if !cur_content.is_empty() {
|
||||||
|
paths.insert(cwd.clone(), cur_content.drain(..).collect());
|
||||||
|
}
|
||||||
|
Some(parse_cmd(&parts[1..]))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match cmd {
|
||||||
|
Some(Command::ChangeDirectory(cd_path)) => {
|
||||||
|
cwd = match (cd_path.as_ref(), cwd.as_ref()) {
|
||||||
|
("/", "/") => cwd,
|
||||||
|
("/", _) => "/".into(),
|
||||||
|
("..", _) => match cwd.rsplit_once("/").unwrap() {
|
||||||
|
("", _) => "/".into(),
|
||||||
|
(p, _) => p.into(),
|
||||||
|
},
|
||||||
|
(p, "/") => format!("/{p}"),
|
||||||
|
(p, _) => format!("{cwd}/{p}"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Some(Command::List) => (),
|
||||||
|
_ => {
|
||||||
|
let content = parse_content_part(&line);
|
||||||
|
cur_content.push(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cur_content.is_empty() {
|
||||||
|
paths.insert(cwd.clone(), cur_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path_sizes(dirs: &DirMap, mut size_map: &mut DirMap<usize>) {
|
||||||
|
for (path, contents) in dirs {
|
||||||
|
let size = size_at_path(&path, &contents, &dirs, &mut size_map);
|
||||||
|
size_map.insert(path.to_owned(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_at_path(
|
||||||
|
cur_path: &str,
|
||||||
|
contents: &[Content],
|
||||||
|
dirs: &DirMap,
|
||||||
|
size_map: &mut DirMap<usize>,
|
||||||
|
) -> usize {
|
||||||
|
let mut sum = 0;
|
||||||
|
|
||||||
|
for content in contents {
|
||||||
|
sum += match content {
|
||||||
|
Content::File { size, .. } => *size,
|
||||||
|
Content::Dir { path } => {
|
||||||
|
let dir_path = join_paths(cur_path, path);
|
||||||
|
let dir_content = dirs.get(&dir_path).expect("invalid dir path");
|
||||||
|
size_at_path(&dir_path, dir_content, dirs, size_map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_paths(a: &str, b: &str) -> String {
|
||||||
|
match a {
|
||||||
|
"/" => format!("/{b}"),
|
||||||
|
_ => format!("{a}/{b}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_content_part(input: &str) -> Content {
|
||||||
|
let parts: Vec<_> = input.split_whitespace().collect();
|
||||||
|
|
||||||
|
match parts[..] {
|
||||||
|
["dir", path, ..] => Content::Dir {
|
||||||
|
path: path.to_owned(),
|
||||||
|
},
|
||||||
|
[size, path, ..] => Content::File {
|
||||||
|
size: size.parse().unwrap(),
|
||||||
|
path: path.to_owned(),
|
||||||
|
},
|
||||||
|
_ => panic!("invalid content"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_cmd(input: &[&str]) -> Command {
|
||||||
|
match input[..] {
|
||||||
|
["cd", ch_dir, ..] => Command::ChangeDirectory(ch_dir.to_owned()),
|
||||||
|
["ls", ..] => Command::List,
|
||||||
|
_ => panic!("unexpected command line input"),
|
||||||
|
}
|
||||||
|
}
|
@ -9,4 +9,4 @@
|
|||||||
- [2019](2019/README.md) (0% completed)
|
- [2019](2019/README.md) (0% completed)
|
||||||
- [2020](2020/README.md) (20% completed)
|
- [2020](2020/README.md) (20% completed)
|
||||||
- [2021](2021/README.md) (68% completed)
|
- [2021](2021/README.md) (68% completed)
|
||||||
- [2022](2022/README.md) (24% completed)
|
- [2022](2022/README.md) (28% completed)
|
||||||
|
Loading…
Reference in New Issue
Block a user