d20
This commit is contained in:
parent
b6bdd16242
commit
526f9a0dc9
6 changed files with 211 additions and 8 deletions
5
res/20/example1
Normal file
5
res/20/example1
Normal file
|
@ -0,0 +1,5 @@
|
|||
broadcaster -> a, b, c
|
||||
%a -> b
|
||||
%b -> c
|
||||
%c -> inv
|
||||
&inv -> a
|
5
res/20/example2
Normal file
5
res/20/example2
Normal file
|
@ -0,0 +1,5 @@
|
|||
broadcaster -> a
|
||||
%a -> inv, con
|
||||
&inv -> b
|
||||
%b -> con
|
||||
&con -> output
|
58
res/20/input
Normal file
58
res/20/input
Normal 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
|
145
src/days/d20.rs
145
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<String, bool>),
|
||||
}
|
||||
|
||||
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<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}");
|
||||
|
||||
let result: usize = 0;
|
||||
let result: usize = rx_cnt;
|
||||
|
||||
println!("Result 2: {result}");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue