mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-27 22:00:31 +01:00
Replace regex with aho-corasick
This commit is contained in:
@@ -6,10 +6,10 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
aho-corasick = "1.1.2"
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
clap = { version = "4.4.8", features = ["derive"] }
|
clap = { version = "4.4.8", features = ["derive"] }
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
regex = "1.10.2"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.5.1"
|
criterion = "0.5.1"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use aho_corasick::AhoCorasick;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use regex::bytes::Regex;
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
pub fn part1(input: &[u8]) -> Result<String> {
|
||||||
let mut it = input.iter();
|
let mut it = input.iter();
|
||||||
@@ -22,43 +22,35 @@ pub fn part1(input: &[u8]) -> Result<String> {
|
|||||||
Ok(sum.to_string())
|
Ok(sum.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_digit(digit: &[u8]) -> Result<u32> {
|
pub fn part2(input: &[u8]) -> Result<String> {
|
||||||
Ok(match digit {
|
let parser = AhoCorasick::new([
|
||||||
b"one" => 1,
|
"1", "2", "3", "4", "5", "6", "7", "8", "9", "one", "two", "three", "four", "five", "six",
|
||||||
b"two" => 2,
|
"seven", "eight", "nine",
|
||||||
b"three" => 3,
|
])?;
|
||||||
b"four" => 4,
|
|
||||||
b"five" => 5,
|
fn convert_id(id: u32) -> Result<u32> {
|
||||||
b"six" => 6,
|
Ok(match id {
|
||||||
b"seven" => 7,
|
0..=8 => id + 1,
|
||||||
b"eight" => 8,
|
9..=17 => id - 8,
|
||||||
b"nine" => 9,
|
_ => anyhow::bail!("unreachable"),
|
||||||
&[d] => u32::from(d - b'0'),
|
|
||||||
other => anyhow::bail!("invalid digit: {}", String::from_utf8_lossy(other)),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 53255: too low
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let parser = Regex::new(r"[1-9]|one|two|three|four|five|six|seven|eight|nine")?;
|
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
for line in input.split(|&c| c == b'\n') {
|
for line in input.split(|&c| c == b'\n') {
|
||||||
let mut first = None;
|
let mut first = None;
|
||||||
let mut last = &b""[..];
|
let mut last = 0;
|
||||||
|
|
||||||
let mut start = 0;
|
|
||||||
|
|
||||||
// Cannot use find_iter because it doesn't find overlapping matches.
|
// Cannot use find_iter because it doesn't find overlapping matches.
|
||||||
while let Some(needle) = parser.find_at(line, start) {
|
for needle in parser.find_overlapping_iter(line) {
|
||||||
start = needle.start() + 1;
|
let digit = convert_id(needle.pattern().as_u32())?;
|
||||||
let digit = needle.as_bytes();
|
|
||||||
first.get_or_insert(digit);
|
first.get_or_insert(digit);
|
||||||
last = digit;
|
last = digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(first) = first {
|
if let Some(first) = first {
|
||||||
sum += 10 * parse_string_digit(first)? + parse_string_digit(last)?;
|
sum += 10 * first + last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user