[TWEAK] Performance improvement by dropping the need for a hashmap and using the stack indices directly
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -7,6 +7,7 @@ name = "advent-of-code-2022-rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"nohash-hasher",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
]
|
||||
@@ -32,6 +33,12 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "nohash-hasher"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
|
||||
@@ -9,4 +9,5 @@ edition = "2021"
|
||||
[dependencies]
|
||||
regex = "1"
|
||||
lazy_static = "1.4.0"
|
||||
rustc-hash = "1.1.0"
|
||||
rustc-hash = "1.1.0"
|
||||
nohash-hasher = "0.2.0"
|
||||
24
src/day5.rs
24
src/day5.rs
@@ -1,3 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use nohash_hasher::{BuildNoHashHasher, NoHashHasher};
|
||||
use rustc_hash::FxHashMap;
|
||||
use crate::day_solver::DaySolver;
|
||||
|
||||
@@ -25,15 +27,14 @@ impl StackInstruction {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Day5 {
|
||||
stacks: Vec<Vec<char>>,
|
||||
stack_ids_rev: FxHashMap<u8, usize>,
|
||||
instructions: Vec<StackInstruction>
|
||||
}
|
||||
|
||||
impl Day5 {
|
||||
fn execute_instruction_part1(&mut self, instr: &StackInstruction) {
|
||||
for _ in 0..instr.amount {
|
||||
let moving_crate = self.stacks[self.stack_ids_rev[&instr.from]].pop().unwrap();
|
||||
self.stacks[self.stack_ids_rev[&instr.to]].push(moving_crate);
|
||||
let moving_crate = self.stacks[instr.from as usize].pop().unwrap();
|
||||
self.stacks[instr.to as usize].push(moving_crate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +49,12 @@ impl Day5 {
|
||||
|
||||
fn execute_instruction_part2(&mut self, instr: &StackInstruction) {
|
||||
|
||||
let from_stack = &self.stacks[self.stack_ids_rev[&instr.from]];
|
||||
// TODO prevent copying into a Vec here (we don't need a stack allocation...)
|
||||
let from_stack = &self.stacks[instr.from as usize];
|
||||
let from_stack_remaining = from_stack.len() - instr.amount as usize;
|
||||
let to_move: Vec<char> = from_stack.iter().skip(from_stack_remaining).cloned().collect();
|
||||
self.stacks[self.stack_ids_rev[&instr.to]].extend(to_move);
|
||||
self.stacks[self.stack_ids_rev[&instr.from]].truncate(from_stack_remaining);
|
||||
self.stacks[instr.to as usize].extend(to_move);
|
||||
self.stacks[instr.from as usize].truncate(from_stack_remaining);
|
||||
}
|
||||
|
||||
fn execute_instructions_part2(&self) -> Day5 {
|
||||
@@ -87,15 +89,19 @@ impl Day5 {
|
||||
}
|
||||
let stack_ids: Vec<u8> = stack_id_strs.iter().map(|s| s.parse::<u8>().unwrap()).collect();
|
||||
|
||||
let mut stacks: Vec<Vec<char>> = vec![Vec::with_capacity(stack_lines.len() - 1); stack_id_idxs.len()];
|
||||
let mut stacks: Vec<Vec<char>> = vec![Vec::with_capacity(stack_lines.len() - 1);
|
||||
stack_ids.iter().max().unwrap().to_owned() as usize + 1];
|
||||
for stack_line in stack_lines.iter().rev().skip(1) {
|
||||
stack_id_idxs.iter().enumerate()
|
||||
.for_each(|(i, stack_id_idx)| if let Some(c) = stack_line.chars().nth(stack_id_idx.to_owned()).filter(|c| !c.is_whitespace()) { stacks[i].push(c) })
|
||||
.for_each(|(i, stack_id_idx)| if let Some(c) = stack_line.chars()
|
||||
.nth(stack_id_idx.to_owned())
|
||||
.filter(|c| !c.is_whitespace()) {
|
||||
stacks[stack_ids[i] as usize].push(c)
|
||||
})
|
||||
}
|
||||
|
||||
return Day5 {
|
||||
stacks,
|
||||
stack_ids_rev: FxHashMap::from_iter(stack_ids.iter().enumerate().map(|(k, v)| (v.clone(), k))),
|
||||
instructions: instruction_lines.iter().map(|s| StackInstruction::parse(s)).collect()
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user