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

@@ -7,4 +7,7 @@ edition = "2018"
[dependencies]
nom = "6.0.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 std::collections::HashMap;
struct Game {
history: HashMap<usize, Vec<usize>>,
history: HashMap<usize, History>,
on_turn: 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 {
fn new(starting_values: &[usize]) -> Result<Game, TopLevelError> {
if starting_values.is_empty() {
@@ -19,9 +33,9 @@ impl Game {
for value in starting_values {
match history.get_mut(value) {
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;
last_value = *value;
@@ -37,13 +51,9 @@ impl Game {
fn add_to_history(&mut self, value: usize) {
match self.history.get_mut(&value) {
None => {
let _ = self.history.insert(value, vec![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;
let _ = self.history.insert(value, History::New(self.on_turn));
}
Some(v) => v.add_timestamp(self.on_turn),
}
}
@@ -53,12 +63,10 @@ impl Game {
.get(&self.last_value)
.expect("The world broke :(");
if insert_history.len() < 2 {
self.last_value = 0;
} else {
self.last_value = insert_history[1] - insert_history[0];
}
self.last_value = match insert_history {
History::New(_) => 0,
History::Old(earlier, later) => later - earlier,
};
self.add_to_history(self.last_value);
self.on_turn += 1;
}