Day 01 - Trebuchet?!

parsingstring-search

Language: Rust

Problem https://adventofcode.com/2023/day/1


Part 1: Each line has letters mixed in with digits. Find the first and last digit on each line, combine them into a two-digit number, and sum everything up.

I filter each line down to just digit characters and grab first and last:

let digits: Vec<char> = line.chars()
    .filter(|c| c.is_ascii_digit())
    .collect();

match (digits.first(), digits.last()) {
    (Some(first), Some(last)) => {
        format!("{}{}", first, last).parse::<u32>().unwrap()
    },
    _ => 0,
}

Part 2: Now spelled-out words like one, two, three also count as digits. The tricky part is that words can overlap, like twone should yield both two and one.

The solution is to scan every character index and check both whether it’s a digit and whether the remaining string starts with any word name. A HashMap maps each word to its digit character:

let word_to_digit: HashMap<&str, char> = [
    ("one", '1'), ("two", '2'), ("three", '3'), ("four", '4'),
    ("five", '5'), ("six", '6'), ("seven", '7'), ("eight", '8'), ("nine", '9')
].iter().cloned().collect();

for (i, c) in line.char_indices() {
    if c.is_ascii_digit() {
        digits.push(c);
    } else {
        for (word, &digit) in &word_to_digit {
            if line[i..].starts_with(word) {
                digits.push(digit);
                break;
            }
        }
    }
}

Checking every position rather than consuming the string means overlaps handle themselves.


Solution: https://github.com/Elyrial/AdventOfCode/blob/main/src/solutions/year2023/day01.rs

No C writeup yet.