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]] | ||||
| name = "advent-2022" | ||||
| 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" | ||||
| 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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										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