From 526f9a0dc9a1c7e4da7319eb2a9e00fbbd632de0 Mon Sep 17 00:00:00 2001 From: JonOfUs Date: Wed, 20 Dec 2023 14:13:43 +0100 Subject: [PATCH] d20 --- res/20/example | 0 res/20/example1 | 5 ++ res/20/example2 | 5 ++ res/20/input | 58 +++++++++++++++++++ src/days/d20.rs | 145 ++++++++++++++++++++++++++++++++++++++++++++++-- src/main.rs | 6 +- 6 files changed, 211 insertions(+), 8 deletions(-) delete mode 100644 res/20/example create mode 100644 res/20/example1 create mode 100644 res/20/example2 create mode 100644 res/20/input diff --git a/res/20/example b/res/20/example deleted file mode 100644 index e69de29..0000000 diff --git a/res/20/example1 b/res/20/example1 new file mode 100644 index 0000000..9ed10dd --- /dev/null +++ b/res/20/example1 @@ -0,0 +1,5 @@ +broadcaster -> a, b, c +%a -> b +%b -> c +%c -> inv +&inv -> a \ No newline at end of file diff --git a/res/20/example2 b/res/20/example2 new file mode 100644 index 0000000..4da4379 --- /dev/null +++ b/res/20/example2 @@ -0,0 +1,5 @@ +broadcaster -> a +%a -> inv, con +&inv -> b +%b -> con +&con -> output \ No newline at end of file diff --git a/res/20/input b/res/20/input new file mode 100644 index 0000000..53b694f --- /dev/null +++ b/res/20/input @@ -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 diff --git a/src/days/d20.rs b/src/days/d20.rs index 9e20186..ba6370e 100644 --- a/src/days/d20.rs +++ b/src/days/d20.rs @@ -1,16 +1,151 @@ -use std::fs; +use std::{ + collections::{HashMap, VecDeque}, + fs, +}; + +#[derive(Debug, Clone)] +enum ModuleTypes { + Broadcast, + FlipFlop(bool), + Conjunction(HashMap), +} 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 result: usize = 0; + let mut modules: HashMap)> = contents + .lines() + .map(|line| { + let (t, outputs) = line.split_once(" -> ").unwrap(); + let outputs: Vec = 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> = 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 = 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}"); - let result: usize = 0; + let result: usize = rx_cnt; println!("Result 2: {result}"); } diff --git a/src/main.rs b/src/main.rs index ad48b01..b7882ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ extern crate scan_fmt; use std::time::Instant; fn main() { - //days::d19::solve() - _all_days() + days::d20::solve() + //_all_days() } #[allow(unreachable_code, unused)] @@ -89,11 +89,11 @@ fn _all_days() { days::d19::solve(); time = _print_elapsed(time); - /* println!("\nDay 20"); days::d20::solve(); time = _print_elapsed(time); + /* println!("\nDay 21"); days::d21::solve(); time = _print_elapsed(time);