Implement 2023 day 1 part 2

This commit is contained in:
2023-12-01 11:21:05 +01:00
parent 28178c8a73
commit 1541b82c11
5 changed files with 70 additions and 4 deletions

View File

@@ -9,6 +9,15 @@ edition = "2021"
anyhow = "1.0.75"
clap = { version = "4.4.8", features = ["derive"] }
nom = "7.1.3"
regex = "1.10.2"
[dev-dependencies]
criterion = "0.5.1"
[profile.release]
# Keep debug information in release for better flamegraphs
debug = true
[[bench]]
name = "days"
harness = false

View File

@@ -9,7 +9,7 @@ use criterion::Criterion;
use aoc_2023::get_implementation;
/// Number of days we have an implementation to benchmark
const DAYS_IMPLEMENTED: u8 = 0;
const DAYS_IMPLEMENTED: u8 = 1;
fn read_input(day: u8) -> std::io::Result<Vec<u8>> {
let input_path = format!("inputs/{day:02}.txt");

View File

@@ -1,4 +1,5 @@
use anyhow::Result;
use regex::bytes::Regex;
pub fn part1(input: &[u8]) -> Result<String> {
let mut it = input.iter();
@@ -30,18 +31,63 @@ pub fn part1(input: &[u8]) -> Result<String> {
Ok(sum.to_string())
}
pub fn part2(_input: &[u8]) -> Result<String> {
anyhow::bail!("Not implemented")
fn parse_string_digit(digit: &[u8]) -> Result<u32> {
Ok(match digit {
b"one" => 1,
b"two" => 2,
b"three" => 3,
b"four" => 4,
b"five" => 5,
b"six" => 6,
b"seven" => 7,
b"eight" => 8,
b"nine" => 9,
&[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;
for line in input.split(|&c| c == b'\n') {
let mut first = None;
let mut last = &b""[..];
let mut start = 0;
// Cannot use find_iter because it doesn't find overlapping matches.
while let Some(needle) = parser.find_at(line, start) {
start = needle.start() + 1;
let digit = needle.as_bytes();
first.get_or_insert(digit);
last = digit;
}
if let Some(first) = first {
sum += 10 * parse_string_digit(first)? + parse_string_digit(last)?;
}
}
Ok(sum.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/01.txt");
const SAMPLE: &[u8] = include_bytes!("samples/01.1.txt");
const SAMPLE2: &[u8] = include_bytes!("samples/01.2.txt");
#[test]
fn sample_part1() {
assert_eq!("142", part1(SAMPLE).unwrap());
}
#[test]
fn sample_part2() {
assert_eq!("281", part2(SAMPLE2).unwrap());
}
}

View File

@@ -0,0 +1,4 @@
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet

View File

@@ -0,0 +1,7 @@
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen