broken implementation of 7.1
This commit is contained in:
		
							
								
								
									
										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}"); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user