Improve performance day 15

Using 32 bit integers is significantly faster due to better memory
locality, although it requires a bit of casting to move between indices
and values as needed.
This commit is contained in:
2020-12-15 09:10:33 +01:00
parent 3ab0f9711d
commit 859034b09d

View File

@@ -3,22 +3,22 @@ use std::io::Read;
use crate::common::numbers_and_stuff; use crate::common::numbers_and_stuff;
use crate::Solution; use crate::Solution;
fn nth_number(start: &[usize], n: usize) -> usize { fn nth_number(start: &[u32], n: u32) -> u32 {
// Don't want to special case this // Don't want to special case this
assert!(n >= start.len()); assert!(n as usize >= start.len());
let mut history = vec![0; n]; let mut history = vec![0; n as usize];
let mut prev = 0; let mut prev = 0;
for (i, &n) in start.iter().enumerate() { for (i, &n) in start.iter().enumerate() {
history[prev] = i; history[prev as usize] = i as u32;
prev = n; prev = n;
} }
for i in start.len()..n { for i in (start.len() as u32)..n {
let last_seen = history[prev]; let last_seen = history[prev as usize];
history[prev] = i; history[prev as usize] = i;
prev = if last_seen == 0 { 0 } else { i - last_seen }; prev = if last_seen == 0 { 0 } else { i - last_seen };
} }
@@ -31,13 +31,13 @@ pub struct Day15;
impl Solution for Day15 { impl Solution for Day15 {
fn part1(&mut self, input: &mut dyn Read) -> String { fn part1(&mut self, input: &mut dyn Read) -> String {
let numbers: Vec<usize> = numbers_and_stuff(input); let numbers: Vec<u32> = numbers_and_stuff(input);
nth_number(&numbers, 2020).to_string() nth_number(&numbers, 2020).to_string()
} }
fn part2(&mut self, input: &mut dyn Read) -> String { fn part2(&mut self, input: &mut dyn Read) -> String {
let numbers: Vec<usize> = numbers_and_stuff(input); let numbers: Vec<u32> = numbers_and_stuff(input);
nth_number(&numbers, 30000000).to_string() nth_number(&numbers, 30000000).to_string()
} }