Make things ~40% faster by using explicit 1/2 valued objects instead of vectors.
This commit is contained in:
@@ -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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user