day20: trade memory for perf
This commit is contained in:
parent
433d29d079
commit
85cc09aecc
|
@ -2,7 +2,7 @@
|
||||||
#![feature(byte_slice_trim_ascii)]
|
#![feature(byte_slice_trim_ascii)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::VecDeque;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&str; 1] = [include_str!("./input.txt")];
|
const INPUTS: [&str; 1] = [include_str!("./input.txt")];
|
||||||
|
@ -27,8 +27,8 @@ fn compress(mut c: &[u8]) -> usize {
|
||||||
fn process(data: &str) -> usize {
|
fn process(data: &str) -> usize {
|
||||||
let data = data.as_bytes();
|
let data = data.as_bytes();
|
||||||
|
|
||||||
let mut map: HashMap<usize, (u8, Vec<usize>)> = HashMap::new();
|
let mut map = vec![];
|
||||||
let mut inverted_map: HashMap<usize, Vec<usize>> = HashMap::new();
|
let mut inverted_map = vec![];
|
||||||
|
|
||||||
for line in data.split(|&x| x == b'\n') {
|
for line in data.split(|&x| x == b'\n') {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
|
@ -52,23 +52,27 @@ fn process(data: &str) -> usize {
|
||||||
.map(compress)
|
.map(compress)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
map.insert(label, (stype, dst));
|
if map.len() <= label {
|
||||||
|
map.extend(std::iter::repeat((0, vec![])).take(label - map.len() + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k, (_, dst)) in map.iter() {
|
map[label] = (stype, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
inverted_map.extend(std::iter::repeat(vec![]).take(map.len() - inverted_map.len()));
|
||||||
|
|
||||||
|
for (k, (_, dst)) in map.iter().enumerate() {
|
||||||
for &dst in dst {
|
for &dst in dst {
|
||||||
inverted_map.entry(dst).or_default().push(*k);
|
inverted_map[dst].push(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut button_state = vec![false; map.keys().max().unwrap() + 1];
|
let mut button_state = vec![false; map.len() + 1];
|
||||||
|
|
||||||
let mut button_presses = vec![];
|
let mut button_presses = vec![];
|
||||||
let mut button_press = 0;
|
let mut button_press = 0;
|
||||||
|
|
||||||
let rx_input = *inverted_map
|
let rx_input = *inverted_map[compress("rx".as_bytes())]
|
||||||
.get(&compress("rx".as_bytes()))
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
.iter()
|
||||||
.next()
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -84,7 +88,7 @@ fn process(data: &str) -> usize {
|
||||||
rx_input,
|
rx_input,
|
||||||
);
|
);
|
||||||
|
|
||||||
if button_presses.len() == inverted_map.get(&rx_input).map_or(0, |x| x.len()) {
|
if button_presses.len() == inverted_map[rx_input].len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,14 +117,14 @@ const fn gcd(a: usize, b: usize) -> usize {
|
||||||
fn cycle(
|
fn cycle(
|
||||||
button_press: usize,
|
button_press: usize,
|
||||||
state: &mut [bool],
|
state: &mut [bool],
|
||||||
map: &HashMap<usize, (u8, Vec<usize>)>,
|
map: &[(u8, Vec<usize>)],
|
||||||
inverted_map: &HashMap<usize, Vec<usize>>,
|
inverted_map: &[Vec<usize>],
|
||||||
button_presses: &mut Vec<usize>,
|
button_presses: &mut Vec<usize>,
|
||||||
rx_input: usize,
|
rx_input: usize,
|
||||||
) {
|
) {
|
||||||
let mut q = VecDeque::new();
|
let mut q = VecDeque::new();
|
||||||
|
|
||||||
let (_, broadcast_dst) = map.get(&compress("broadcaster".as_bytes())).unwrap();
|
let (_, broadcast_dst) = &map[compress("broadcaster".as_bytes())];
|
||||||
for &dst in broadcast_dst {
|
for &dst in broadcast_dst {
|
||||||
q.push_back((dst, false));
|
q.push_back((dst, false));
|
||||||
}
|
}
|
||||||
|
@ -130,11 +134,11 @@ fn cycle(
|
||||||
button_presses.push(button_press);
|
button_presses.push(button_press);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let (dtype, dnext) = match map.get(&dst) {
|
|
||||||
Some(v) => v,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let (dtype, dnext) = &map[dst];
|
||||||
|
if *dtype == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
match dtype {
|
match dtype {
|
||||||
b'%' => {
|
b'%' => {
|
||||||
if pulse {
|
if pulse {
|
||||||
|
@ -148,7 +152,7 @@ fn cycle(
|
||||||
}
|
}
|
||||||
|
|
||||||
b'&' => {
|
b'&' => {
|
||||||
let new_state = inverted_map.get(&dst).unwrap().iter().all(|&x| state[x]);
|
let new_state = inverted_map[dst].iter().all(|&x| state[x]);
|
||||||
|
|
||||||
for &next in dnext {
|
for &next in dnext {
|
||||||
q.push_back((next, !new_state));
|
q.push_back((next, !new_state));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user