broken implementation of 7.1
This commit is contained in:
parent
a998e68b71
commit
393db1d3bf
42
2022/Cargo.lock
generated
42
2022/Cargo.lock
generated
@ -5,3 +5,45 @@ version = 3
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "advent-2022"
|
name = "advent-2022"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||||
|
@ -31,6 +31,9 @@ path = "src/day5.rs"
|
|||||||
name = "day6"
|
name = "day6"
|
||||||
path = "src/day6.rs"
|
path = "src/day6.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "day7"
|
||||||
|
path = "src/day7.rs"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
181
2022/src/day7.rs
Normal file
181
2022/src/day7.rs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
|
||||||
|
struct Directory {
|
||||||
|
name: String,
|
||||||
|
children: Vec<Node>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct File {
|
||||||
|
name: String,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Node {
|
||||||
|
Branch(Directory),
|
||||||
|
Leaf(File),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CMD_CD: Regex = Regex::new(r"^\$ cd (\w+)$").unwrap();
|
||||||
|
static ref CMD_LS: Regex = Regex::new(r"^\$ ls$").unwrap();
|
||||||
|
static ref DIR_LISTING: Regex = Regex::new(r"^dir (\w+)$").unwrap();
|
||||||
|
static ref FILE_LISTING: Regex = Regex::new(r"^(\d+) (\w+)$").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct DirListing {
|
||||||
|
name: String,
|
||||||
|
children: Vec<usize>,
|
||||||
|
parent: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NodeListing {
|
||||||
|
Branch(DirListing),
|
||||||
|
Leaf(File),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn build_map(data: &str) -> Result<HashMap<usize, NodeListing>, String> {
|
||||||
|
let root = DirListing {
|
||||||
|
name: "".to_string(),
|
||||||
|
children: vec![],
|
||||||
|
parent: None,
|
||||||
|
};
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(0, NodeListing::Branch(root));
|
||||||
|
|
||||||
|
let mut stack: Vec<usize> = vec![];
|
||||||
|
stack.push(0);
|
||||||
|
|
||||||
|
'lines: for line in data.trim().lines() {
|
||||||
|
if CMD_LS.is_match(line) {continue;}
|
||||||
|
|
||||||
|
if let Some(m) = CMD_CD.find_iter(line).next() {
|
||||||
|
let name = m.as_str();
|
||||||
|
if name == ".." {
|
||||||
|
stack.pop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_dir = match map.get(&stack.last().unwrap()).unwrap() {
|
||||||
|
NodeListing::Branch(dir) => dir,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
for id in current_dir.children {
|
||||||
|
let child_name = match map.get(&id).unwrap() {
|
||||||
|
NodeListing::Branch(dir) => dir.name,
|
||||||
|
NodeListing::Leaf(file) => file.name,
|
||||||
|
};
|
||||||
|
if child_name == name {
|
||||||
|
stack.push(id);
|
||||||
|
continue 'lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(format!("Attempted to cd into directory before ls-ing it: {}", line.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(m) = DIR_LISTING.find_iter(line).next() {
|
||||||
|
let parent_id = stack.last().unwrap();
|
||||||
|
let parent = match map.get_mut(parent_id).unwrap() {
|
||||||
|
NodeListing::Branch(dir) => dir,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let dir = DirListing {
|
||||||
|
name: m.as_str().to_string(),
|
||||||
|
children: vec![],
|
||||||
|
parent: Some(*parent_id),
|
||||||
|
};
|
||||||
|
// this is safe as long as we never remove anything from the map while we're building it
|
||||||
|
let dir_id = map.len();
|
||||||
|
map.insert(dir_id, NodeListing::Branch(dir));
|
||||||
|
parent.children.push(dir_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let matches = FILE_LISTING.find_iter(line);
|
||||||
|
if let (Some(s), Some(n)) = (matches.next(), matches.next()) {
|
||||||
|
let name = n.as_str().to_string();
|
||||||
|
let size = s.as_str().parse::<usize>()
|
||||||
|
.map_err(|_e| format!("Invalid file size: {}", line.to_string()))?;
|
||||||
|
|
||||||
|
let file_id = map.len();
|
||||||
|
let file = File {name, size};
|
||||||
|
map.insert(file_id, NodeListing::Leaf(file));
|
||||||
|
|
||||||
|
let parent = match map.get_mut(stack.last().unwrap()).unwrap() {
|
||||||
|
NodeListing::Branch(dir) => dir,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
parent.children.push(file_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(format!("Could not interpret line: {line}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn build_tree(map: &HashMap<usize, NodeListing>, root:&DirListing) -> Directory {
|
||||||
|
let root_listing = map.get(&root_id).unwrap();
|
||||||
|
let root_children = Vec::new();
|
||||||
|
for child_id in root_listing.children {
|
||||||
|
match map.get(&child_id).unwrap() {
|
||||||
|
NodeListing::Leaf(file) => {
|
||||||
|
root_children.push(Node::Leaf(file));
|
||||||
|
},
|
||||||
|
NodeListing::Branch(dir_listing) => {
|
||||||
|
let dir = build_tree(map, child_id);
|
||||||
|
root_children.push(Node::Branch(dir))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory {
|
||||||
|
name: root_listing.name.clone(),
|
||||||
|
children: root_children,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn get_sizes(root: &Directory, mut sizes: Vec<usize>) -> (usize, Vec<usize>) {
|
||||||
|
let dir_size = 0;
|
||||||
|
|
||||||
|
let mut returned_sizes;
|
||||||
|
for child in root.children {
|
||||||
|
match child {
|
||||||
|
Node::Leaf(file) => dir_size += file.size,
|
||||||
|
Node::Branch(dir) => {
|
||||||
|
let (child_size, rs) = get_sizes(dir, sizes);
|
||||||
|
returned_sizes = rs;
|
||||||
|
dir_size += child_size;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
returned_sizes.push(dir_size);
|
||||||
|
returned_sizes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() -> Result<(), String> {
|
||||||
|
let map = build_map(data);
|
||||||
|
let tree = build_tree(map, 0);
|
||||||
|
let (_total_size, dir_sizes) = get_sizes(&tree, vec![]);
|
||||||
|
|
||||||
|
let part1_sizes = dir_sizes.iter()
|
||||||
|
.filter(|s| s <= 100000)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
println!("Part 1: {part1_sizes}");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user