Make things ~40% faster by using explicit 1/2 valued objects instead of vectors.

This commit is contained in:
2020-12-15 16:03:45 -08:00
parent cb0c6fa861
commit 5161a22967
2 changed files with 27 additions and 16 deletions

View File

@@ -8,3 +8,6 @@ edition = "2018"
nom = "6.0.1" nom = "6.0.1"
petgraph = "0.5.1" petgraph = "0.5.1"
thiserror = "1.0.22" thiserror = "1.0.22"
[profile.release]
debug = 1

View File

@@ -1,11 +1,25 @@
use advent2020::errors::TopLevelError; use advent2020::errors::TopLevelError;
use std::collections::HashMap; use std::collections::HashMap;
struct Game { struct Game {
history: HashMap<usize, Vec<usize>>, history: HashMap<usize, History>,
on_turn: usize, on_turn: usize,
last_value: usize, last_value: usize,
} }
pub enum History {
New(usize),
Old(usize, usize),
}
impl History {
fn add_timestamp(&mut self, now: usize) {
match self {
History::New(first) => *self = History::Old(*first, now),
History::Old(_, earlier) => *self = History::Old(*earlier, now),
}
}
}
impl Game { impl Game {
fn new(starting_values: &[usize]) -> Result<Game, TopLevelError> { fn new(starting_values: &[usize]) -> Result<Game, TopLevelError> {
if starting_values.is_empty() { if starting_values.is_empty() {
@@ -19,9 +33,9 @@ impl Game {
for value in starting_values { for value in starting_values {
match history.get_mut(value) { match history.get_mut(value) {
None => { None => {
let _ = history.insert(*value, vec![on_turn]); let _ = history.insert(*value, History::New(on_turn));
} }
Some(v) => v.push(on_turn), Some(v) => v.add_timestamp(on_turn),
} }
on_turn += 1; on_turn += 1;
last_value = *value; last_value = *value;
@@ -37,13 +51,9 @@ impl Game {
fn add_to_history(&mut self, value: usize) { fn add_to_history(&mut self, value: usize) {
match self.history.get_mut(&value) { match self.history.get_mut(&value) {
None => { None => {
let _ = self.history.insert(value, vec![self.on_turn]); let _ = self.history.insert(value, History::New(self.on_turn));
}
Some(v) if v.len() == 1 => v.push(self.on_turn),
Some(v) => {
v[0] = v[1];
v[1] = self.on_turn;
} }
Some(v) => v.add_timestamp(self.on_turn),
} }
} }
@@ -53,12 +63,10 @@ impl Game {
.get(&self.last_value) .get(&self.last_value)
.expect("The world broke :("); .expect("The world broke :(");
if insert_history.len() < 2 { self.last_value = match insert_history {
self.last_value = 0; History::New(_) => 0,
} else { History::Old(earlier, later) => later - earlier,
self.last_value = insert_history[1] - insert_history[0]; };
}
self.add_to_history(self.last_value); self.add_to_history(self.last_value);
self.on_turn += 1; self.on_turn += 1;
} }