Reduce complexity of day 15. Runtime 4s -> 0.01s
This commit is contained in:
parent
9df32a9067
commit
c3262996fa
48
src/day15.rs
48
src/day15.rs
|
@ -1,4 +1,4 @@
|
||||||
use itertools::Itertools;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
fn hash(s: &str) -> u64 {
|
fn hash(s: &str) -> u64 {
|
||||||
|
@ -19,20 +19,11 @@ pub fn hash_sequence() -> u64 {
|
||||||
buffer.trim().split(',').map(hash).sum()
|
buffer.trim().split(',').map(hash).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Hash)]
|
|
||||||
enum Op<'a> {
|
enum Op<'a> {
|
||||||
Add(&'a str, u64),
|
Add(&'a str, u64),
|
||||||
Rem(&'a str),
|
Rem(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn same_operand(a: &Op, b: &Op) -> bool {
|
|
||||||
match a {
|
|
||||||
Op::Add(s, _) | Op::Rem(s) => match b {
|
|
||||||
Op::Add(t, _) | Op::Rem(t) => s == t,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parseop<'a>(op: &'a str) -> Op<'a> {
|
fn parseop<'a>(op: &'a str) -> Op<'a> {
|
||||||
if op.ends_with('-') {
|
if op.ends_with('-') {
|
||||||
Op::Rem(&op[0..op.len() - 1])
|
Op::Rem(&op[0..op.len() - 1])
|
||||||
|
@ -47,24 +38,35 @@ fn parse<'a>(ops: &Vec<&'a str>) -> Vec<Op<'a>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn condense<'a>(ops: &Vec<Op<'a>>) -> Vec<Op<'a>> {
|
fn condense<'a>(ops: &Vec<Op<'a>>) -> Vec<Op<'a>> {
|
||||||
|
let mut last_delete_map = HashMap::new();
|
||||||
|
ops.iter().enumerate().for_each(|(i, op)| {
|
||||||
|
if let Op::Rem(opstr) = op {
|
||||||
|
last_delete_map.insert(opstr, i);
|
||||||
|
}
|
||||||
|
});
|
||||||
let remove_deletes = ops.iter().enumerate().filter(|(i, op)| match op {
|
let remove_deletes = ops.iter().enumerate().filter(|(i, op)| match op {
|
||||||
Op::Rem(_) => false,
|
Op::Rem(_) => false,
|
||||||
Op::Add(_, _) => !ops
|
Op::Add(opstr, _) => !last_delete_map.get(opstr).is_some_and(|j| j > i),
|
||||||
.iter()
|
|
||||||
.rposition(|lop| same_operand(op, lop) && matches!(*lop, Op::Rem(_)))
|
|
||||||
.is_some_and(|j| j > *i),
|
|
||||||
});
|
});
|
||||||
let remove_deletes_clone = remove_deletes.clone();
|
|
||||||
|
|
||||||
let map_to_last = remove_deletes.map(|(_, op)| {
|
let mut last_value_map = HashMap::new();
|
||||||
*remove_deletes_clone
|
remove_deletes.clone().for_each(|(_, op)| {
|
||||||
.clone()
|
if let Op::Add(s, v) = op {
|
||||||
.rfind(|(_, rop)| same_operand(op, rop))
|
last_value_map.insert(s, v);
|
||||||
.unwrap()
|
}
|
||||||
.1
|
|
||||||
});
|
});
|
||||||
let map_unique = map_to_last.into_iter().unique();
|
|
||||||
map_unique.collect()
|
let map_to_last = remove_deletes.filter_map(|(_, op)| {
|
||||||
|
if let Op::Add(opstr, _) = op {
|
||||||
|
match last_value_map.remove(opstr) {
|
||||||
|
Some(v) => Some(Op::Add(opstr, *v)),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
map_to_last.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_ops(ops: &Vec<&str>) -> u64 {
|
fn perform_ops(ops: &Vec<&str>) -> u64 {
|
||||||
|
|
Loading…
Reference in New Issue