day8: optimized
This commit is contained in:
parent
10a38b6f3b
commit
dc2b3c56e9
|
@ -1,8 +1,6 @@
|
||||||
#![feature(slice_split_once)]
|
#![feature(slice_split_once)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&[u8]; 2] = [
|
const INPUTS: [&[u8]; 2] = [
|
||||||
|
@ -29,8 +27,7 @@ const INPUTS: [&[u8]; 2] = [
|
||||||
fn process(data: &[u8]) -> usize {
|
fn process(data: &[u8]) -> usize {
|
||||||
let (seq, remain) = data.split_once(|&x| x == b'\n').unwrap();
|
let (seq, remain) = data.split_once(|&x| x == b'\n').unwrap();
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = vec![];
|
||||||
|
|
||||||
for line in remain.split(|&x| x == b'\n').skip(1) {
|
for line in remain.split(|&x| x == b'\n').skip(1) {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -38,17 +35,29 @@ fn process(data: &[u8]) -> usize {
|
||||||
let (start, remain) = line.split_at(3);
|
let (start, remain) = line.split_at(3);
|
||||||
let (l, r) = (&remain[4..7], &remain[9..12]);
|
let (l, r) = (&remain[4..7], &remain[9..12]);
|
||||||
|
|
||||||
map.insert(start, (l, r));
|
// Pack data into 6 bytes each
|
||||||
|
let start = lut(start[0]) << 10 | lut(start[1]) << 5 | lut(start[2]);
|
||||||
|
let l = lut(l[0]) << 10 | lut(l[1]) << 5 | lut(l[2]);
|
||||||
|
let r = lut(r[0]) << 10 | lut(r[1]) << 5 | lut(r[2]);
|
||||||
|
|
||||||
|
if start >= map.len() {
|
||||||
|
map.extend(std::iter::repeat(None).take(start - map.len() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
map[start] = Some((l, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pos: &[u8] = &[b'A', b'A', b'A'];
|
const AAA: usize = lut(b'A') << 10 | lut(b'A') << 5 | lut(b'A');
|
||||||
|
const ZZZ: usize = lut(b'Z') << 10 | lut(b'Z') << 5 | lut(b'Z');
|
||||||
|
|
||||||
|
let mut pos = AAA;
|
||||||
|
|
||||||
for (i, ins) in seq.iter().cycle().enumerate() {
|
for (i, ins) in seq.iter().cycle().enumerate() {
|
||||||
if pos == [b'Z', b'Z', b'Z'] {
|
if pos == ZZZ {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (l, r) = map.get(&pos).unwrap();
|
let (l, r) = map[pos].unwrap();
|
||||||
|
|
||||||
match ins {
|
match ins {
|
||||||
b'L' => pos = l,
|
b'L' => pos = l,
|
||||||
|
@ -61,6 +70,16 @@ fn process(data: &[u8]) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn lut(c: u8) -> usize {
|
||||||
|
match c {
|
||||||
|
(b'0'..=b'9') => (c - b'0') as usize + 27,
|
||||||
|
(b'A'..=b'Z') => (c - b'A') as usize,
|
||||||
|
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
for input in INPUTS.iter() {
|
for input in INPUTS.iter() {
|
||||||
println!("total = {}", process(input));
|
println!("total = {}", process(input));
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#![feature(slice_split_once)]
|
#![feature(slice_split_once)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&[u8]; 2] = [
|
const INPUTS: [&[u8]; 2] = [
|
||||||
|
@ -13,8 +11,7 @@ const INPUTS: [&[u8]; 2] = [
|
||||||
fn process(data: &[u8]) -> usize {
|
fn process(data: &[u8]) -> usize {
|
||||||
let (seq, remain) = data.split_once(|&x| x == b'\n').unwrap();
|
let (seq, remain) = data.split_once(|&x| x == b'\n').unwrap();
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = vec![];
|
||||||
|
|
||||||
for line in remain.split(|&x| x == b'\n').skip(1) {
|
for line in remain.split(|&x| x == b'\n').skip(1) {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -22,28 +19,41 @@ fn process(data: &[u8]) -> usize {
|
||||||
let (start, remain) = line.split_at(3);
|
let (start, remain) = line.split_at(3);
|
||||||
let (l, r) = (&remain[4..7], &remain[9..12]);
|
let (l, r) = (&remain[4..7], &remain[9..12]);
|
||||||
|
|
||||||
map.insert(start, (l, r));
|
// Pack data into 6 bytes each
|
||||||
|
let start = lut(start[0]) << 10 | lut(start[1]) << 5 | lut(start[2]);
|
||||||
|
let l = lut(l[0]) << 10 | lut(l[1]) << 5 | lut(l[2]);
|
||||||
|
let r = lut(r[0]) << 10 | lut(r[1]) << 5 | lut(r[2]);
|
||||||
|
|
||||||
|
if start >= map.len() {
|
||||||
|
map.extend(std::iter::repeat(None).take(start - map.len() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
map[start] = Some((l, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut a_set = vec![];
|
let mut set = vec![];
|
||||||
|
|
||||||
for &k in map
|
const A: usize = lut(b'A');
|
||||||
.keys()
|
const Z: usize = lut(b'Z');
|
||||||
.filter(|x| x.last().map_or(false, |&b| b == b'A'))
|
|
||||||
{
|
for (i, _) in map.iter().enumerate().filter(|(_, v)| v.is_some()) {
|
||||||
a_set.push(k);
|
let last = i & 0b11_111;
|
||||||
|
if last == A {
|
||||||
|
set.push(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tmp = Vec::with_capacity(a_set.len());
|
let mut tmp = Vec::with_capacity(set.len());
|
||||||
|
|
||||||
'outer: for mut node in a_set {
|
'outer: for mut node in set {
|
||||||
for (i, ins) in seq.iter().cycle().enumerate() {
|
for (i, ins) in seq.iter().cycle().enumerate() {
|
||||||
if node.last().map_or(false, |&b| b == b'Z') {
|
let last = node & 0b11_111;
|
||||||
|
if last == Z {
|
||||||
tmp.push(i);
|
tmp.push(i);
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (l, r) = map.get(node).unwrap();
|
let (l, r) = map[node].unwrap();
|
||||||
|
|
||||||
match ins {
|
match ins {
|
||||||
b'L' => node = l,
|
b'L' => node = l,
|
||||||
|
@ -56,6 +66,16 @@ fn process(data: &[u8]) -> usize {
|
||||||
lcm(&tmp)
|
lcm(&tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn lut(c: u8) -> usize {
|
||||||
|
match c {
|
||||||
|
(b'0'..=b'9') => (c - b'0') as usize + 27,
|
||||||
|
(b'A'..=b'Z') => (c - b'A') as usize,
|
||||||
|
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lcm(a: &[usize]) -> usize {
|
fn lcm(a: &[usize]) -> usize {
|
||||||
let mut answer = a[0];
|
let mut answer = a[0];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user