[rs] Solve 2022_07 part 1
This commit is contained in:
parent
d1f20886fb
commit
04f61205cb
7 changed files with 1198 additions and 0 deletions
1045
inputs/2022/2022_07.input
Normal file
1045
inputs/2022/2022_07.input
Normal file
File diff suppressed because it is too large
Load diff
2
inputs/2022/2022_07.solution
Normal file
2
inputs/2022/2022_07.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Part 1: 1243729
|
||||
Part 2: ???
|
||||
|
|
@ -46,6 +46,7 @@ days! {
|
|||
Y2022D04: "2022_04",
|
||||
Y2022D05: "2022_05",
|
||||
Y2022D06: "2022_06",
|
||||
Y2022D07: "2022_07",
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
|
|
@ -75,6 +76,7 @@ fn main() -> io::Result<()> {
|
|||
Day::Y2022D04 => y2022::d04::solve(input),
|
||||
Day::Y2022D05 => y2022::d05::solve(input),
|
||||
Day::Y2022D06 => y2022::d06::solve(input),
|
||||
Day::Y2022D07 => y2022::d07::solve(input),
|
||||
}
|
||||
eprintln!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ pub mod d03;
|
|||
pub mod d04;
|
||||
pub mod d05;
|
||||
pub mod d06;
|
||||
pub mod d07;
|
||||
|
|
|
|||
123
rs/src/y2022/d07.rs
Normal file
123
rs/src/y2022/d07.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
enum LsItem {
|
||||
File(usize, String),
|
||||
Dir(String),
|
||||
}
|
||||
|
||||
enum Command {
|
||||
Cd(String),
|
||||
Ls(Vec<LsItem>),
|
||||
}
|
||||
|
||||
enum Fs {
|
||||
Dir(HashMap<String, Fs>),
|
||||
File(usize),
|
||||
}
|
||||
|
||||
impl Fs {
|
||||
fn as_dir(&mut self) -> &mut HashMap<String, Self> {
|
||||
match self {
|
||||
Fs::Dir(map) => map,
|
||||
Fs::File(_) => panic!("Not a directory"),
|
||||
}
|
||||
}
|
||||
|
||||
fn at_path(&mut self, path: &[String]) -> &mut Self {
|
||||
let mut result = self;
|
||||
for segment in path {
|
||||
result = result.as_dir().get_mut(segment).unwrap();
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
match self {
|
||||
Fs::Dir(map) => map.values().map(|v| v.size()).sum(),
|
||||
Fs::File(size) => *size,
|
||||
}
|
||||
}
|
||||
|
||||
fn dirs(&self) -> Vec<&Self> {
|
||||
let mut result = vec![];
|
||||
if let Fs::Dir(map) = self {
|
||||
result.push(self);
|
||||
for value in map.values() {
|
||||
result.extend(value.dirs());
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
fn command_chunks(input: &str) -> Vec<(String, Vec<String>)> {
|
||||
let mut lines = input.lines().peekable();
|
||||
let mut chunks = vec![];
|
||||
while let Some(command) = lines.next() {
|
||||
assert!(command.starts_with("$ "));
|
||||
let mut items = vec![];
|
||||
while let Some(item) = lines.peek() {
|
||||
if item.starts_with("$ ") {
|
||||
break;
|
||||
}
|
||||
items.push(item.to_string());
|
||||
lines.next();
|
||||
}
|
||||
chunks.push((command.to_string(), items));
|
||||
}
|
||||
chunks
|
||||
}
|
||||
|
||||
pub fn solve(input: String) {
|
||||
// Parse commands
|
||||
let commands = command_chunks(&input)
|
||||
.into_iter()
|
||||
.map(|(command, items)| {
|
||||
if let Some(name) = command.strip_prefix("$ cd ") {
|
||||
Command::Cd(name.to_string())
|
||||
} else {
|
||||
assert_eq!(command, "$ ls");
|
||||
let ls_items = items
|
||||
.into_iter()
|
||||
.map(|item| {
|
||||
let (left, name) = item.split_once(' ').unwrap();
|
||||
if left == "dir" {
|
||||
LsItem::Dir(name.to_string())
|
||||
} else {
|
||||
LsItem::File(left.parse::<usize>().unwrap(), name.to_string())
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
Command::Ls(ls_items)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Build fs tree
|
||||
let mut fs = Fs::Dir(HashMap::new());
|
||||
let mut path = vec![];
|
||||
for command in commands {
|
||||
match command {
|
||||
Command::Cd(to) if to == "/" => path = vec![],
|
||||
Command::Cd(to) if to == ".." => _ = path.pop(), // Learned a new trick
|
||||
Command::Cd(to) => path.push(to),
|
||||
Command::Ls(items) => {
|
||||
for item in items {
|
||||
let map = fs.at_path(&path).as_dir();
|
||||
match item {
|
||||
LsItem::File(size, name) => map.insert(name, Fs::File(size)),
|
||||
LsItem::Dir(name) => map.insert(name, Fs::Dir(HashMap::new())),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let part1 = fs
|
||||
.dirs()
|
||||
.into_iter()
|
||||
.map(|d| d.size())
|
||||
.filter(|s| *s <= 100000)
|
||||
.sum::<usize>();
|
||||
println!("Part 1: {part1}");
|
||||
}
|
||||
23
sample_inputs/2022/2022_07.input
Normal file
23
sample_inputs/2022/2022_07.input
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
|
||||
2
sample_inputs/2022/2022_07.solution
Normal file
2
sample_inputs/2022/2022_07.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Part 1: 95437
|
||||
Part 2: ???
|
||||
Loading…
Add table
Add a link
Reference in a new issue