This commit is contained in:
JonOfUs 2023-12-20 14:13:43 +01:00
parent b6bdd16242
commit 526f9a0dc9
6 changed files with 211 additions and 8 deletions

View file

5
res/20/example1 Normal file
View file

@ -0,0 +1,5 @@
broadcaster -> a, b, c
%a -> b
%b -> c
%c -> inv
&inv -> a

5
res/20/example2 Normal file
View file

@ -0,0 +1,5 @@
broadcaster -> a
%a -> inv, con
&inv -> b
%b -> con
&con -> output

58
res/20/input Normal file
View file

@ -0,0 +1,58 @@
%hb -> mj
%mx -> mt, xz
%xh -> qc
%tg -> cq
%kp -> xz, nj
%mj -> jj, lv
%cq -> jm
%mt -> sj, xz
&jj -> hb, lz, rk, xv, vj, vh, lv
%rm -> bz, xq
%hx -> bz
%xv -> lz
%xx -> kp, xz
%pt -> vx
&xz -> bq, gr, sj, rv, zf
%vx -> gf, cv
%xb -> xz, bq
%xk -> gf, rd
%lv -> zk
&rk -> gh
%kn -> gf, tz
&gh -> rx
%sj -> vp
%jm -> vm, bz
%rr -> rv, xz
%tz -> rz
%gg -> kn
&cd -> gh
%qc -> kh, bz
%kb -> gf
%vp -> xz, xx
%fb -> bz, tg
%rd -> cp
%qn -> vh, jj
%xr -> jj
%tp -> rm, bz
%cp -> gg
&bz -> qx, cq, xh, fb, tg
%qq -> pt, gf
%xq -> bz, hx
%gx -> jj, qv
%bq -> rr
%cv -> gf, kb
%zk -> jj, xv
&zf -> gh
&qx -> gh
%vh -> gx
%qv -> xr, jj
%lz -> qn
broadcaster -> fb, xk, gr, vj
%nj -> xz
%gr -> xz, xb
%kh -> tp, bz
%vm -> bz, xh
%rz -> qq, gf
&gf -> tz, cd, rd, xk, pt, cp, gg
%rv -> mx
%vj -> hb, jj

View file

@ -1,16 +1,151 @@
use std::fs; use std::{
collections::{HashMap, VecDeque},
fs,
};
#[derive(Debug, Clone)]
enum ModuleTypes {
Broadcast,
FlipFlop(bool),
Conjunction(HashMap<String, bool>),
}
pub fn solve() { pub fn solve() {
let path = "res/20/example"; let path = "res/20/input";
let mut _contents = fs::read_to_string(path).expect("I/O error, wrong path?"); let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
//let contents = BufReader::new(fs::File::open(path).expect("I/O error, wrong path?")); //let contents = BufReader::new(fs::File::open(path).expect("I/O error, wrong path?"));
let result: usize = 0; let mut modules: HashMap<String, (ModuleTypes, Vec<String>)> = contents
.lines()
.map(|line| {
let (t, outputs) = line.split_once(" -> ").unwrap();
let outputs: Vec<String> = outputs.split(", ").map(|out| String::from(out)).collect();
if t.starts_with("%") {
(t.replace("%", ""), (ModuleTypes::FlipFlop(false), outputs))
} else if t.starts_with("&") {
(
t.replace("&", ""),
(ModuleTypes::Conjunction(HashMap::new()), outputs),
)
} else {
(String::from(t), (ModuleTypes::Broadcast, outputs))
}
})
.collect();
let mut tmp_map: HashMap<String, HashMap<String, bool>> = HashMap::new();
for (mod_name, module) in modules.iter() {
module.1.iter().for_each(|name| {
if name.as_str() == "output" || !modules.contains_key(name) {
return;
}
match modules.get(name).unwrap().0 {
ModuleTypes::Conjunction(_) => {
let entry = tmp_map.entry(name.clone()).or_insert(HashMap::new());
entry.insert(mod_name.clone(), false);
}
_ => {}
};
})
}
for (name, map) in tmp_map {
modules.get_mut(&name).unwrap().0 = ModuleTypes::Conjunction(map)
}
let mut cycle_finder: HashMap<u8, (usize, bool)> = HashMap::new();
let mut high_cnt: usize = 0;
let mut low_cnt: usize = 0;
let mut queue: VecDeque<(String, String, bool)> = VecDeque::new();
let mut rx_cnt: usize = 0;
'outer: for i in 0..1000000 {
low_cnt += 1; // button pressed
modules["broadcaster"]
.1
.iter()
.for_each(|item| queue.push_back((String::from("broadcaster"), item.clone(), false)));
while !queue.is_empty() {
let (prev, next, val) = queue.pop_front().unwrap();
if i < 1000 {
if val {
high_cnt += 1
} else {
low_cnt += 1
}
}
if next.as_str() == "output" {
continue;
}
if next.as_str() == "rx" {
let parent = match &modules["gh"].0 {
ModuleTypes::Conjunction(par_map) => par_map,
_ => panic!(),
};
if parent.iter().any(|(_, v)| *v) {
let mut parent: Vec<(String, bool)> =
parent.iter().map(|(s, v)| (s.clone(), *v)).collect();
parent.sort();
let par_val: u8 = parent
.iter()
.enumerate()
.map(|(i, (_, v))| if *v { 1 << i } else { 0 })
.sum();
if !cycle_finder.contains_key(&par_val) {
cycle_finder.insert(par_val, (i + 1, false));
} else {
let v = cycle_finder[&par_val];
if !v.1 && v.0 != (i+1) {
cycle_finder.insert(par_val, ((i+1) - v.0, true));
}
}
}
if cycle_finder.len() == 4 && cycle_finder.iter().all(|(_,(_,v))| *v) {
rx_cnt = cycle_finder.iter().map(|(_, (v, _))| *v).fold(1, |x, y| num::integer::lcm(x, y));
break 'outer;
}
continue;
}
let entry = modules.get_mut(&next).unwrap();
match entry.0 {
ModuleTypes::FlipFlop(ref mut ff_val) => {
if !val {
*ff_val = !(*ff_val);
entry
.1
.iter()
.map(|name| (next.clone(), name.clone(), *ff_val))
.for_each(|tpl| queue.push_back(tpl));
}
}
ModuleTypes::Conjunction(ref mut c_map) => {
c_map.insert(prev, val);
entry
.1
.iter()
.map(|name| (next.clone(), name.clone(), !c_map.iter().all(|(_, v)| *v)))
.for_each(|tpl| queue.push_back(tpl));
}
_ => {}
}
}
}
let result: usize = low_cnt * high_cnt;
println!("Result 1: {result}"); println!("Result 1: {result}");
let result: usize = 0; let result: usize = rx_cnt;
println!("Result 2: {result}"); println!("Result 2: {result}");
} }

View file

@ -5,8 +5,8 @@ extern crate scan_fmt;
use std::time::Instant; use std::time::Instant;
fn main() { fn main() {
//days::d19::solve() days::d20::solve()
_all_days() //_all_days()
} }
#[allow(unreachable_code, unused)] #[allow(unreachable_code, unused)]
@ -89,11 +89,11 @@ fn _all_days() {
days::d19::solve(); days::d19::solve();
time = _print_elapsed(time); time = _print_elapsed(time);
/*
println!("\nDay 20"); println!("\nDay 20");
days::d20::solve(); days::d20::solve();
time = _print_elapsed(time); time = _print_elapsed(time);
/*
println!("\nDay 21"); println!("\nDay 21");
days::d21::solve(); days::d21::solve();
time = _print_elapsed(time); time = _print_elapsed(time);