day20
This commit is contained in:
parent
049a2181ad
commit
867a987508
92
day20/Cargo.lock
generated
Normal file
92
day20/Cargo.lock
generated
Normal file
@ -0,0 +1,92 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "day20"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
18
day20/Cargo.toml
Normal file
18
day20/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "day20"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "sane"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.1"
|
||||
|
||||
[[bin]]
|
||||
name = "oop"
|
||||
path= "src/main_oop.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "sane"
|
||||
path= "src/main_sane.rs"
|
58
day20/input.txt
Normal file
58
day20/input.txt
Normal file
@ -0,0 +1,58 @@
|
||||
%vb -> ck
|
||||
%pb -> xv
|
||||
> -> jq
|
||||
%hj -> lk, hh
|
||||
%zd -> fm
|
||||
%hr -> hh
|
||||
%rg -> tp
|
||||
%tf -> ck, tx
|
||||
%pp -> vs, hh
|
||||
%vx -> df
|
||||
%tx -> mr, ck
|
||||
%nh -> vx
|
||||
%sc -> ck, vb
|
||||
%cc -> ck, rj
|
||||
%tn -> kz, lt
|
||||
%fp -> rb
|
||||
%hc -> kz
|
||||
%rb -> ns, mf
|
||||
%pc -> vh
|
||||
broadcaster -> tf, br, zn, nc
|
||||
%zn -> kz, fv
|
||||
&ns -> pb, lr, br, fp, gp, gv, jl
|
||||
%nc -> hh, hj
|
||||
%mf -> ns, gp
|
||||
%xv -> ns, kh
|
||||
%rj -> ck, sc
|
||||
%tg -> cc
|
||||
%gp -> pb
|
||||
%jz -> lj, ns
|
||||
%jl -> fp
|
||||
&vr -> jq
|
||||
&jq -> rx
|
||||
&kz -> zf, nl, df, zn, vx, nh
|
||||
%gv -> jl
|
||||
%gf -> zf, kz
|
||||
%df -> gf
|
||||
%kq -> pp
|
||||
%lk -> hh, zd
|
||||
%vs -> bp
|
||||
%lt -> ls, kz
|
||||
&nl -> jq
|
||||
%mr -> rg
|
||||
%zf -> qf
|
||||
%br -> gv, ns
|
||||
%rk -> hh, hr
|
||||
%qf -> kz, tn
|
||||
%rv -> rk, hh
|
||||
%ls -> hc, kz
|
||||
%fm -> kq
|
||||
&ck -> tp, vr, pc, tg, mr, tf, rg
|
||||
%fv -> nh, kz
|
||||
%tp -> pc
|
||||
%vh -> ck, tg
|
||||
&hh -> vs, kq, gt, nc, zd, fm
|
||||
&lr -> jq
|
||||
%kh -> ns, jz
|
||||
%bp -> hh, rv
|
||||
%lj -> ns
|
92
day20/input_part2_analysis.txt
Normal file
92
day20/input_part2_analysis.txt
Normal file
@ -0,0 +1,92 @@
|
||||
The input of rx is conjunction of hh, ck, kz, ns (truth = low pulse)
|
||||
&jq -> rx
|
||||
|
||||
> -> jq
|
||||
&vr -> jq
|
||||
&nl -> jq
|
||||
&lr -> jq
|
||||
|
||||
|
||||
Counter 1
|
||||
&hh -> nc, zd, vs, kq, fm | -> gt
|
||||
|
||||
%nc -> hj, hh | <- hh, broadcast
|
||||
%hj -> lk, hh
|
||||
%lk -> zd, hh
|
||||
%zd -> fm | <- hh
|
||||
%fm -> kq | <- hh
|
||||
%kq -> pp | <- hh
|
||||
%pp -> vs, hh
|
||||
%vs -> bp | <- hh
|
||||
%bp -> rv, hh
|
||||
%rv -> rk, hh
|
||||
%rk -> hr, hh
|
||||
%hr -> hh
|
||||
|
||||
111101000111(2) = 3911
|
||||
|
||||
|
||||
Counter 2
|
||||
&ck -> tf, mr, rg, tp, pc, tg | -> vr
|
||||
|
||||
%tf -> tx, ck | <- broadcast, ck
|
||||
%tx -> mr, ck
|
||||
%mr -> rg | <- ck
|
||||
%rg -> tp | <- ck
|
||||
%tp -> pc | <- ck
|
||||
%pc -> vh | <- ck
|
||||
%vh -> tg, ck
|
||||
%tg -> cc | <- ck
|
||||
%cc -> rj, ck
|
||||
%rj -> sc, ck
|
||||
%sc -> vb, ck
|
||||
%vb -> ck
|
||||
|
||||
111101000011(2) = 3907
|
||||
|
||||
|
||||
Counter 3
|
||||
&kz -> zn, nh, vx, df, zf | -> nl
|
||||
|
||||
%zn -> fv, kz | <- broadcast, kz
|
||||
%fv -> nh, kz
|
||||
%nh -> vx | <- kz
|
||||
%vx -> df | <- kz
|
||||
%df -> gf | <- kz
|
||||
%gf -> zf, kz
|
||||
%zf -> qf | <- kz
|
||||
%qf -> tn, kz
|
||||
%tn -> lt, kz
|
||||
%lt -> ls, kz
|
||||
%ls -> hc, kz
|
||||
%hc -> kz
|
||||
|
||||
111110100011(2) = 4003
|
||||
|
||||
|
||||
Counter 4
|
||||
&ns -> pb, br, fp, gp, gv, jl | -> lr
|
||||
|
||||
%br -> gv, ns | <- broadcast
|
||||
%gv -> jl
|
||||
%jl -> fp
|
||||
%fp -> rb
|
||||
%rb -> mf, ns
|
||||
%mf -> gp, ns
|
||||
%gp -> pb
|
||||
%pb -> xv
|
||||
%xv -> kh, ns
|
||||
%kh -> jz, ns
|
||||
%jz -> lj, ns
|
||||
%lj -> ns
|
||||
|
||||
111100110001(2) = 3889
|
||||
|
||||
The broadcast node drives all the counters
|
||||
broadcaster -> nc, tf, zn, br
|
||||
|
||||
Period of rx (same as first activation) is LCM of periods of all counters
|
||||
LCM = 237878264003759
|
||||
|
||||
|
||||
|
214
day20/src/main_oop.rs
Normal file
214
day20/src/main_oop.rs
Normal file
@ -0,0 +1,214 @@
|
||||
use std::any::Any;
|
||||
use std::cmp;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
// Object-oriented, polymorphic way of implementing it,
|
||||
// does less than main_sane.rs (only part 1) with more lines of code
|
||||
|
||||
struct Pulse {
|
||||
src: u16,
|
||||
dest: u16,
|
||||
high: bool,
|
||||
}
|
||||
|
||||
trait Module: Any {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>);
|
||||
fn add_input(&mut self, id: u16);
|
||||
fn add_output(&mut self, id: u16);
|
||||
}
|
||||
|
||||
struct ModuleBase {
|
||||
inputs: Vec<u16>,
|
||||
outputs: Vec<u16>,
|
||||
id: u16,
|
||||
}
|
||||
|
||||
impl ModuleBase {
|
||||
fn new(id: u16) -> ModuleBase {
|
||||
ModuleBase {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.inputs.push(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.outputs.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct BroadcastModule {
|
||||
base: ModuleBase,
|
||||
}
|
||||
|
||||
impl BroadcastModule {
|
||||
fn new(id: u16) -> BroadcastModule {
|
||||
BroadcastModule {
|
||||
base: ModuleBase::new(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for BroadcastModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: pulse.high }));
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct FlipFlopModule {
|
||||
base: ModuleBase,
|
||||
on: bool,
|
||||
}
|
||||
|
||||
impl FlipFlopModule {
|
||||
fn new(id: u16) -> FlipFlopModule {
|
||||
FlipFlopModule {
|
||||
base: ModuleBase::new(id),
|
||||
on: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for FlipFlopModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
if !pulse.high {
|
||||
self.on = !self.on;
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: self.on }));
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct ConjunctionModule {
|
||||
base: ModuleBase,
|
||||
memory: Vec<bool>,
|
||||
}
|
||||
|
||||
impl ConjunctionModule {
|
||||
fn new(id: u16) -> ConjunctionModule {
|
||||
ConjunctionModule {
|
||||
base: ModuleBase::new(id),
|
||||
memory: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for ConjunctionModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
if let Some(pos) = self.base.inputs.iter().position(|&id| id == pulse.src) {
|
||||
self.memory[pos] = pulse.high;
|
||||
let out_high = !self.memory.iter().all(|&v| v);
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: out_high }));
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
self.memory.push(false);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_module_name(name: &str) -> u16 {
|
||||
let bytes = &name.as_bytes()[0..cmp::min(name.as_bytes().len(), 3)];
|
||||
let mut acc = 0u16;
|
||||
for &c in bytes {
|
||||
acc = acc * 26 + (c - b'a') as u16;
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut modules: HashMap<u16, Box<dyn Module>> = HashMap::new();
|
||||
// let rx_id = encode_module_name("rx");
|
||||
// modules.insert(rx_id, Box::new(FlipFlopModule::new(rx_id)));
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let name = split_whitespace.next().unwrap();
|
||||
let new_module: Box<dyn Module>;
|
||||
let id = encode_module_name(&name[1..]);
|
||||
match name.as_bytes()[0] {
|
||||
b'%' => new_module = Box::new(FlipFlopModule::new(id)),
|
||||
b'&' => new_module = Box::new(ConjunctionModule::new(id)),
|
||||
_ => new_module = Box::new(BroadcastModule::new(id))
|
||||
}
|
||||
modules.insert(id, new_module);
|
||||
}
|
||||
for line in input_str.lines() {
|
||||
let mut split = line.split([' ', ',']).
|
||||
filter(|&v| !v.is_empty());
|
||||
let name = split.next().unwrap();
|
||||
let in_id = encode_module_name(&name[1..]);
|
||||
split.next();
|
||||
while let Some(name) = split.next() {
|
||||
let id = encode_module_name(name);
|
||||
modules.get_mut(&in_id).unwrap().add_output(id);
|
||||
match modules.get_mut(&id) {
|
||||
None => {}
|
||||
Some(in_module) => {
|
||||
in_module.add_input(in_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let broadcast_id = encode_module_name("roadcast");
|
||||
let mut low_pulses = 0u64;
|
||||
let mut high_pulses = 0u64;
|
||||
let mut queue: VecDeque<Pulse> = VecDeque::new();
|
||||
for _ in 0..1000 {
|
||||
let mut low_pulses_step = 0;
|
||||
let mut high_pulses_step = 0;
|
||||
queue.push_back(Pulse {src: u16::MAX, dest: broadcast_id, high: false});
|
||||
while !queue.is_empty() {
|
||||
let pulse = queue.pop_front().unwrap();
|
||||
match pulse.high {
|
||||
true => high_pulses_step += 1,
|
||||
false => low_pulses_step += 1
|
||||
}
|
||||
match modules.get_mut(&pulse.dest) {
|
||||
None => {}
|
||||
Some(module) => {
|
||||
module.handle_pulse(pulse, &mut queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
low_pulses += low_pulses_step;
|
||||
high_pulses += high_pulses_step;
|
||||
}
|
||||
let result1 = low_pulses * high_pulses;
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Result1: {}", result1);
|
||||
}
|
192
day20/src/main_sane.rs
Normal file
192
day20/src/main_sane.rs
Normal file
@ -0,0 +1,192 @@
|
||||
use std::cmp;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
use num::integer::lcm;
|
||||
|
||||
struct Pulse {
|
||||
src: u16,
|
||||
dest: u16,
|
||||
high: bool,
|
||||
}
|
||||
|
||||
enum ModuleKind {
|
||||
Broadcast,
|
||||
FlipFlop(bool),
|
||||
Conjunction(Vec<bool>),
|
||||
}
|
||||
|
||||
struct Module {
|
||||
inputs: Vec<u16>,
|
||||
outputs: Vec<u16>,
|
||||
id: u16,
|
||||
kind: ModuleKind,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
fn new(id: u16, kind: ModuleKind) -> Module {
|
||||
Module {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
id,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_broadcast(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::Broadcast)
|
||||
}
|
||||
|
||||
fn new_flipflop(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::FlipFlop(false))
|
||||
}
|
||||
|
||||
fn new_conjunction(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::Conjunction(vec![]))
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.inputs.push(id);
|
||||
match self.kind {
|
||||
ModuleKind::Conjunction(ref mut memory) => {
|
||||
memory.push(false);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.outputs.push(id);
|
||||
}
|
||||
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
match self.kind {
|
||||
ModuleKind::Broadcast => {
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: pulse.high }));
|
||||
}
|
||||
ModuleKind::FlipFlop(ref mut on) => {
|
||||
if !pulse.high {
|
||||
*on = !*on;
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: *on }));
|
||||
}
|
||||
}
|
||||
ModuleKind::Conjunction(ref mut memory) => {
|
||||
if let Some(pos) = self.inputs.iter().position(|&id| id == pulse.src) {
|
||||
memory[pos] = pulse.high;
|
||||
let out_high = !memory.iter().all(|&v| v);
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: out_high }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_module_name(name: &str) -> u16 {
|
||||
let bytes = &name.as_bytes()[0..cmp::min(name.as_bytes().len(), 3)];
|
||||
let mut acc = 0u16;
|
||||
for &c in bytes {
|
||||
acc = acc * 26 + (c - b'a') as u16;
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut modules: HashMap<u16, Module> = HashMap::new();
|
||||
// let rx_id = encode_module_name("rx");
|
||||
// modules.insert(rx_id, Module::new_flipflop(rx_id));
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let name = split_whitespace.next().unwrap();
|
||||
let new_module: Module;
|
||||
let id = encode_module_name(&name[1..]);
|
||||
match name.as_bytes()[0] {
|
||||
b'%' => new_module = Module::new_flipflop(id),
|
||||
b'&' => new_module = Module::new_conjunction(id),
|
||||
_ => new_module = Module::new_broadcast(id)
|
||||
}
|
||||
modules.insert(id, new_module);
|
||||
}
|
||||
for line in input_str.lines() {
|
||||
let mut split = line.split([' ', ',']).
|
||||
filter(|&v| !v.is_empty());
|
||||
let name = split.next().unwrap();
|
||||
let in_id = encode_module_name(&name[1..]);
|
||||
split.next();
|
||||
while let Some(name) = split.next() {
|
||||
let id = encode_module_name(name);
|
||||
modules.get_mut(&in_id).unwrap().add_output(id);
|
||||
match modules.get_mut(&id) {
|
||||
None => {}
|
||||
Some(in_module) => {
|
||||
in_module.add_input(in_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Part 1
|
||||
let broadcast_id = encode_module_name("roadcast");
|
||||
let mut low_pulses = 0u64;
|
||||
let mut high_pulses = 0u64;
|
||||
let mut queue: VecDeque<Pulse> = VecDeque::new();
|
||||
for _ in 0..1000 {
|
||||
let mut low_pulses_step = 0;
|
||||
let mut high_pulses_step = 0;
|
||||
queue.push_back(Pulse { src: u16::MAX, dest: broadcast_id, high: false });
|
||||
while !queue.is_empty() {
|
||||
let pulse = queue.pop_front().unwrap();
|
||||
match pulse.high {
|
||||
true => high_pulses_step += 1,
|
||||
false => low_pulses_step += 1
|
||||
}
|
||||
match modules.get_mut(&pulse.dest) {
|
||||
None => {}
|
||||
Some(module) => {
|
||||
module.handle_pulse(pulse, &mut queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
low_pulses += low_pulses_step;
|
||||
high_pulses += high_pulses_step;
|
||||
}
|
||||
let result1 = low_pulses * high_pulses;
|
||||
// Part 2
|
||||
// Use the knowledge of the network, that it is that broadcast drives a series of counters
|
||||
let mut counter_periods: Vec<u64> = vec![];
|
||||
for &node in &modules.get(&broadcast_id).unwrap().outputs {
|
||||
let mut period = 0u16;
|
||||
let mut current_node = node;
|
||||
let mut bits = 0;
|
||||
loop {
|
||||
bits += 1;
|
||||
let mut next_id = current_node;
|
||||
period >>= 1;
|
||||
let outputs = &modules.get(¤t_node).unwrap().outputs;
|
||||
for &output_id in outputs {
|
||||
match modules.get(&output_id).unwrap().kind {
|
||||
ModuleKind::Conjunction(_) => period |= 0x8000,
|
||||
_ => next_id = output_id
|
||||
}
|
||||
}
|
||||
if next_id == current_node {
|
||||
break;
|
||||
} else {
|
||||
current_node = next_id;
|
||||
}
|
||||
}
|
||||
period >>= 16 - bits;
|
||||
counter_periods.push(period as u64);
|
||||
}
|
||||
let result2 = counter_periods.iter().fold(1u64, |acc, &v| lcm(acc, v));
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Result1: {}", result1);
|
||||
println!("Result2: {}", result2);
|
||||
}
|
Loading…
Reference in New Issue
Block a user