generated from janezicmatej/aoc-template
	wip: part 1 debugging
This commit is contained in:
		| @@ -0,0 +1,5 @@ | |||||||
|  | broadcaster -> a, b, c | ||||||
|  | %a -> b | ||||||
|  | %b -> c | ||||||
|  | %c -> inv | ||||||
|  | &inv -> a | ||||||
|   | |||||||
							
								
								
									
										149
									
								
								src/bin/20.rs
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								src/bin/20.rs
									
									
									
									
									
								
							| @@ -1,9 +1,14 @@ | |||||||
| use std::{collections::HashMap, str::FromStr}; | use std::{ | ||||||
|  |     collections::{HashMap, VecDeque}, | ||||||
|  |     mem::swap, | ||||||
|  |     process::Output, | ||||||
|  |     str::FromStr, | ||||||
|  | }; | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||||||
| enum Module { | enum Module { | ||||||
|     Broadcaster, |     Broadcaster, | ||||||
|     FlipFlop, |     FlipFlop(bool), | ||||||
|     Conjuction, |     Conjuction, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -14,7 +19,7 @@ impl FromStr for Module { | |||||||
|     type Err = ParseModuleError; |     type Err = ParseModuleError; | ||||||
|     fn from_str(s: &str) -> Result<Self, Self::Err> { |     fn from_str(s: &str) -> Result<Self, Self::Err> { | ||||||
|         Ok(match s { |         Ok(match s { | ||||||
|             "%" => Module::FlipFlop, |             "%" => Module::FlipFlop(false), | ||||||
|             "&" => Module::Conjuction, |             "&" => Module::Conjuction, | ||||||
|             _ => Module::Broadcaster, |             _ => Module::Broadcaster, | ||||||
|         }) |         }) | ||||||
| @@ -22,16 +27,37 @@ impl FromStr for Module { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| struct Location { | struct Node { | ||||||
|  |     index: usize, | ||||||
|     module: Module, |     module: Module, | ||||||
|     inputs: HashMap<String, Option<bool>>, |     inputs: Vec<usize>, | ||||||
|     outputs: Vec<String>, |     outputs: Vec<usize>, | ||||||
| } | } | ||||||
|  |  | ||||||
| fn parse_input(input: &str) -> (Vec<Location>, HashMap<String, usize>) { | fn parse_input(input: &str) -> Vec<Node> { | ||||||
|     let mut locations = Vec::new(); |     let mut nodes = Vec::new(); | ||||||
|     let mut mapper: HashMap<String, usize> = HashMap::new(); |     let mut mapper: HashMap<String, usize> = HashMap::new(); | ||||||
|  |  | ||||||
|  |     for line in input.lines() { | ||||||
|  |         let (from, _) = line.split_once(" -> ").unwrap(); | ||||||
|  |         let (module, mut name) = from.split_at(1); | ||||||
|  |         let module: Module = module.parse().unwrap(); | ||||||
|  |         if module == Module::Broadcaster { | ||||||
|  |             name = from; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         *mapper.entry(name.to_string()).or_default() = nodes.len(); | ||||||
|  |  | ||||||
|  |         let l = Node { | ||||||
|  |             module, | ||||||
|  |             index: nodes.len(), | ||||||
|  |             inputs: Vec::new(), | ||||||
|  |             outputs: Vec::new(), | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         nodes.push(l); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     for line in input.lines() { |     for line in input.lines() { | ||||||
|         let (from, to) = line.split_once(" -> ").unwrap(); |         let (from, to) = line.split_once(" -> ").unwrap(); | ||||||
|         let (module, mut name) = from.split_at(1); |         let (module, mut name) = from.split_at(1); | ||||||
| @@ -40,53 +66,96 @@ fn parse_input(input: &str) -> (Vec<Location>, HashMap<String, usize>) { | |||||||
|             name = from; |             name = from; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let l = Location { |         let index = mapper[name]; | ||||||
|             module, |  | ||||||
|             inputs: HashMap::new(), |  | ||||||
|             outputs: to.split(", ").map(String::from).collect(), |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         locations.push(l); |  | ||||||
|         *mapper.entry(name.to_string()).or_default() = locations.len() - 1; |  | ||||||
|     } |  | ||||||
|     for line in input.lines() { |  | ||||||
|         let (from, to) = line.split_once(" -> ").unwrap(); |  | ||||||
|         let (_, name) = from.split_at(1); |  | ||||||
|  |  | ||||||
|         for destination in to.split(", ") { |         for destination in to.split(", ") { | ||||||
|             let index = mapper[name]; |             let to_index = mapper[destination]; | ||||||
|             locations[index] |             nodes[index].outputs.push(to_index); | ||||||
|                 .inputs |             nodes[to_index].inputs.push(index); | ||||||
|                 .entry(destination.to_string()) |  | ||||||
|                 .or_default(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     (locations, mapper) |     nodes | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn part_one(input: &str) -> Option<usize> { | pub fn part_one(input: &str) -> Option<usize> { | ||||||
|     let (locations, mapper) = parse_input(input); |     let mut nodes = parse_input(input); | ||||||
|  |  | ||||||
|     let mut high = 0; |     let mut graph = vec![vec![None; input.len()]; input.len()]; | ||||||
|     let mut low = 0; |  | ||||||
|  |     let mut highs = 0; | ||||||
|  |     let mut lows = 0; | ||||||
|  |  | ||||||
|  |     let broadcaster = nodes | ||||||
|  |         .iter() | ||||||
|  |         .find(|x| x.module == Module::Broadcaster)? | ||||||
|  |         .index; | ||||||
|  |  | ||||||
|     for _ in 0..1000 { |     for _ in 0..1000 { | ||||||
|         let mut stack = vec!["broadcaster".to_string()]; |         let mut stack = VecDeque::from([broadcaster]); | ||||||
|         while !stack.is_empty() { |         while !stack.is_empty() { | ||||||
|             let mut new_stack = Vec::new(); |             let mut new_stack = VecDeque::new(); | ||||||
|  |  | ||||||
|             while let Some(s) = stack.pop() { |             while let Some(index) = stack.pop_front() { | ||||||
|                 let index = mapper[&s]; |                 let node = &nodes[index]; | ||||||
|                 let loc = &locations[index]; |                 let mut new_module = None; | ||||||
|  |  | ||||||
|                 match loc.module { |                 match node.module { | ||||||
|                     Module::Broadcaster => { |                     Module::Broadcaster => { | ||||||
|                         for dest in loc.outputs.iter() { |                         for dest_index in node.outputs.iter() { | ||||||
|                             let index = mapper[dest]; |                             graph[index][*dest_index] = Some(false); | ||||||
|                             let loc = &locations[index]; |                             new_stack.push_back(*dest_index); | ||||||
|  |                             lows += 1; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     Module::FlipFlop(high) => { | ||||||
|  |                         let mut swapper = None; | ||||||
|  |                         for in_index in nodes[index].inputs.iter() { | ||||||
|  |                             let value = &mut graph[*in_index][index]; | ||||||
|  |                             if value.is_some() { | ||||||
|  |                                 debug_assert!(swapper.is_none()); | ||||||
|  |                                 swap(&mut swapper, value); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         if !swapper.unwrap() { | ||||||
|  |                             let signal = !high; | ||||||
|  |  | ||||||
|  |                             for dest_index in nodes[index].outputs.iter() { | ||||||
|  |                                 graph[index][*dest_index] = Some(signal); | ||||||
|  |                                 new_stack.push_back(*dest_index); | ||||||
|  |                                 if signal { | ||||||
|  |                                     highs += 1; | ||||||
|  |                                 } else { | ||||||
|  |                                     lows += 1; | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |  | ||||||
|  |                             new_module = Some(Module::FlipFlop(signal)); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     Module::Conjuction => { | ||||||
|  |                         let mut all = true; | ||||||
|  |  | ||||||
|  |                         for in_index in nodes[index].inputs.iter() { | ||||||
|  |                             let value = graph[*in_index][index]; | ||||||
|  |                             all &= value.unwrap_or(false); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         for dest_index in nodes[index].outputs.iter() { | ||||||
|  |                             graph[index][*dest_index] = Some(!all); | ||||||
|  |                             new_stack.push_back(*dest_index); | ||||||
|  |                             if !all { | ||||||
|  |                                 highs += 1; | ||||||
|  |                             } else { | ||||||
|  |                                 lows += 1; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 let node = &mut nodes[index]; | ||||||
|  |                 if let Some(module) = new_module { | ||||||
|  |                     node.module = module; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -94,7 +163,7 @@ pub fn part_one(input: &str) -> Option<usize> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Some(high * low) |     Some(highs * lows) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn part_two(input: &str) -> Option<u32> { | pub fn part_two(input: &str) -> Option<u32> { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user