Rewrite day 2 with fewer allocations

This commit is contained in:
2020-12-02 18:38:47 +01:00
parent 777cac6346
commit 2d58f0eb23

View File

@@ -6,35 +6,29 @@ use regex::Regex;
use crate::Solution; use crate::Solution;
struct Rule { fn matches1(min: usize, max: usize, c: char, sample: &str) -> bool {
c: char, let occurrences = sample.matches(c).count();
min: usize,
max: usize, occurrences >= min && occurrences <= max
sample: String,
} }
impl Rule { fn matches2(first: usize, second: usize, c: char, sample: &str) -> bool {
fn matches1(&self) -> bool { let c = c as u8;
let occurrences = self.sample.matches(self.c).count(); let s = sample.as_bytes();
occurrences >= self.min && occurrences <= self.max (s[first - 1] == c) ^ (s[second - 1] == c)
}
fn matches2(&self) -> bool {
let c = self.c as u8;
let s = self.sample.as_bytes();
(s[self.min - 1] == c) ^ (s[self.max - 1] == c)
}
} }
fn read_rules(input: &mut dyn Read) -> Vec<Rule> { fn read_rules<M>(input: &mut dyn Read, matcher: M) -> usize
where
M: for<'r> Fn(usize, usize, char, &'r str) -> bool,
{
let parser = Regex::new(r"^(\d+)-(\d+) ([a-z]): ([a-z]+)$").unwrap(); let parser = Regex::new(r"^(\d+)-(\d+) ([a-z]): ([a-z]+)$").unwrap();
let mut reader = BufReader::new(input); let mut reader = BufReader::new(input);
let mut buffer = String::new(); let mut buffer = String::new();
let mut rules = Vec::new(); let mut matching = 0;
while let Ok(read) = reader.read_line(&mut buffer) { while let Ok(read) = reader.read_line(&mut buffer) {
if read == 0 { if read == 0 {
@@ -43,17 +37,19 @@ fn read_rules(input: &mut dyn Read) -> Vec<Rule> {
let cap = parser.captures(buffer.trim()).unwrap(); let cap = parser.captures(buffer.trim()).unwrap();
rules.push(Rule { let first = cap[1].parse().unwrap();
c: cap[3].chars().next().unwrap(), let second = cap[2].parse().unwrap();
min: cap[1].parse().unwrap(), let c = cap[3].chars().next().unwrap();
max: cap[2].parse().unwrap(), let sample = &cap[4];
sample: cap[4].to_owned(),
});
buffer.clear(); if matcher(first, second, c, sample) {
matching += 1
}
buffer.clear()
} }
rules matching
} }
#[derive(Default)] #[derive(Default)]
@@ -61,19 +57,11 @@ pub struct Day02;
impl Solution for Day02 { impl Solution for Day02 {
fn part1(&mut self, input: &mut dyn Read) -> String { fn part1(&mut self, input: &mut dyn Read) -> String {
read_rules(input) read_rules(input, matches1).to_string()
.into_iter()
.filter(Rule::matches1)
.count()
.to_string()
} }
fn part2(&mut self, input: &mut dyn Read) -> String { fn part2(&mut self, input: &mut dyn Read) -> String {
read_rules(input) read_rules(input, matches2).to_string()
.into_iter()
.filter(Rule::matches2)
.count()
.to_string()
} }
} }