adventofcode2023/day01/part2.rs

80 lines
2.3 KiB
Rust

// Copyright 2023 Christian Ulrich
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// usage: ./part2 < input
use std::io;
pub struct CalibrationValues {
inner: Vec<u32>,
}
impl CalibrationValues {
pub fn from_stdin(tokens: &[(&str, u32)]) -> Result<Self, &'static str> {
let mut values = vec![];
for line in io::stdin().lines() {
let line = line.unwrap();
let mut matches = Vec::new();
for (token, value) in tokens.iter() {
match line.find(token) {
Some(pos) => matches.push((pos, value)),
None => (),
}
match line.rfind(token) {
Some(pos) => matches.push((pos, value)),
None => (),
}
}
if matches.len() > 0 {
matches.sort_by_key(|(pos, _)| *pos);
let first = matches.first().unwrap().1;
let last = matches.last().unwrap().1;
values.push(first * 10 + last);
}
}
Ok(Self { inner: values })
}
pub fn iter(&mut self) -> std::slice::Iter<'_, u32> {
self.inner.iter()
}
}
fn main() -> Result<(), &'static str> {
let tokens = [
("1", 1),
("2", 2),
("3", 3),
("4", 4),
("5", 5),
("6", 6),
("7", 7),
("8", 8),
("9", 9),
("one", 1),
("two", 2),
("three", 3),
("four", 4),
("five", 5),
("six", 6),
("seven", 7),
("eight", 8),
("nine", 9),
];
let mut values = CalibrationValues::from_stdin(&tokens[..])?;
println!("{}", values.iter().sum::<u32>());
Ok(())
}