Day 01 - Trebuchet?!
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.