generated from janezicmatej/aoc-template
wip: part 1 debugging
This commit is contained in:
parent
0000037022
commit
00000380c1
|
@ -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> {
|
||||||
|
|
Loading…
Reference in New Issue