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)]
 | 
			
		||||
enum Module {
 | 
			
		||||
    Broadcaster,
 | 
			
		||||
    FlipFlop,
 | 
			
		||||
    FlipFlop(bool),
 | 
			
		||||
    Conjuction,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +19,7 @@ impl FromStr for Module {
 | 
			
		||||
    type Err = ParseModuleError;
 | 
			
		||||
    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
			
		||||
        Ok(match s {
 | 
			
		||||
            "%" => Module::FlipFlop,
 | 
			
		||||
            "%" => Module::FlipFlop(false),
 | 
			
		||||
            "&" => Module::Conjuction,
 | 
			
		||||
            _ => Module::Broadcaster,
 | 
			
		||||
        })
 | 
			
		||||
@@ -22,16 +27,37 @@ impl FromStr for Module {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
struct Location {
 | 
			
		||||
struct Node {
 | 
			
		||||
    index: usize,
 | 
			
		||||
    module: Module,
 | 
			
		||||
    inputs: HashMap<String, Option<bool>>,
 | 
			
		||||
    outputs: Vec<String>,
 | 
			
		||||
    inputs: Vec<usize>,
 | 
			
		||||
    outputs: Vec<usize>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn parse_input(input: &str) -> (Vec<Location>, HashMap<String, usize>) {
 | 
			
		||||
    let mut locations = Vec::new();
 | 
			
		||||
fn parse_input(input: &str) -> Vec<Node> {
 | 
			
		||||
    let mut nodes = Vec::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() {
 | 
			
		||||
        let (from, to) = line.split_once(" -> ").unwrap();
 | 
			
		||||
        let (module, mut name) = from.split_at(1);
 | 
			
		||||
@@ -40,53 +66,96 @@ fn parse_input(input: &str) -> (Vec<Location>, HashMap<String, usize>) {
 | 
			
		||||
            name = from;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let l = Location {
 | 
			
		||||
            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);
 | 
			
		||||
 | 
			
		||||
        let index = mapper[name];
 | 
			
		||||
        for destination in to.split(", ") {
 | 
			
		||||
            let index = mapper[name];
 | 
			
		||||
            locations[index]
 | 
			
		||||
                .inputs
 | 
			
		||||
                .entry(destination.to_string())
 | 
			
		||||
                .or_default();
 | 
			
		||||
            let to_index = mapper[destination];
 | 
			
		||||
            nodes[index].outputs.push(to_index);
 | 
			
		||||
            nodes[to_index].inputs.push(index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (locations, mapper)
 | 
			
		||||
    nodes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 low = 0;
 | 
			
		||||
    let mut graph = vec![vec![None; input.len()]; input.len()];
 | 
			
		||||
 | 
			
		||||
    let mut highs = 0;
 | 
			
		||||
    let mut lows = 0;
 | 
			
		||||
 | 
			
		||||
    let broadcaster = nodes
 | 
			
		||||
        .iter()
 | 
			
		||||
        .find(|x| x.module == Module::Broadcaster)?
 | 
			
		||||
        .index;
 | 
			
		||||
 | 
			
		||||
    for _ in 0..1000 {
 | 
			
		||||
        let mut stack = vec!["broadcaster".to_string()];
 | 
			
		||||
        let mut stack = VecDeque::from([broadcaster]);
 | 
			
		||||
        while !stack.is_empty() {
 | 
			
		||||
            let mut new_stack = Vec::new();
 | 
			
		||||
            let mut new_stack = VecDeque::new();
 | 
			
		||||
 | 
			
		||||
            while let Some(s) = stack.pop() {
 | 
			
		||||
                let index = mapper[&s];
 | 
			
		||||
                let loc = &locations[index];
 | 
			
		||||
            while let Some(index) = stack.pop_front() {
 | 
			
		||||
                let node = &nodes[index];
 | 
			
		||||
                let mut new_module = None;
 | 
			
		||||
 | 
			
		||||
                match loc.module {
 | 
			
		||||
                match node.module {
 | 
			
		||||
                    Module::Broadcaster => {
 | 
			
		||||
                        for dest in loc.outputs.iter() {
 | 
			
		||||
                            let index = mapper[dest];
 | 
			
		||||
                            let loc = &locations[index];
 | 
			
		||||
                        for dest_index in node.outputs.iter() {
 | 
			
		||||
                            graph[index][*dest_index] = Some(false);
 | 
			
		||||
                            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> {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user