82 lines
2.6 KiB
Rust
82 lines
2.6 KiB
Rust
use regex::Regex;
|
|
use std::collections::HashMap;
|
|
use std::fs::File;
|
|
use std::io::{self, BufRead};
|
|
use std::path::Path;
|
|
|
|
fn main() -> io::Result<()> {
|
|
// File must exist in the current path
|
|
let mut result = 0;
|
|
if let Ok(lines) = read_lines("./src/input") {
|
|
for line in lines.flatten() {
|
|
print!("{} -> ", line);
|
|
|
|
// No need for .as_str(), just pass &line
|
|
let mut replaced_line = replace_written_digits(&line);
|
|
replaced_line = replace_written_digits(&replaced_line);
|
|
println!("{}", replaced_line);
|
|
if let Some(value) = extract_digit_pair_sum(&replaced_line) {
|
|
println!("Current result: {} + {} = {}", result, value, result + value);
|
|
result += value;
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("Final result: {}", result);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn replace_written_digits<T: AsRef<str>>(input: T) -> String {
|
|
// Create a map of written digits to their numeric counterparts
|
|
let digit_map = HashMap::from([
|
|
("one", "1ne"),
|
|
("two", "2wo"),
|
|
("three", "3hree"),
|
|
("four", "4our"),
|
|
("five", "5ive"),
|
|
("six", "6ix"),
|
|
("seven", "7even"),
|
|
("eight", "8ight"),
|
|
("nine", "9ine"),
|
|
]);
|
|
|
|
// Create a regex that matches the written digits
|
|
let re = Regex::new(r"(?:one|two|three|four|five|six|seven|eight|nine)").unwrap();
|
|
|
|
// Replace all occurrences of written digits with their numeric counterparts
|
|
re.replace_all(input.as_ref(), |caps: ®ex::Captures| {
|
|
// Access the full match (use caps.get(0) instead of caps[1])
|
|
let matched_word = caps.get(0).unwrap().as_str();
|
|
digit_map.get(matched_word).unwrap().to_string()
|
|
}).to_string()
|
|
}
|
|
|
|
// Extracts first and last digits from a line, forms a number, and returns the sum
|
|
fn extract_digit_pair_sum(line: &str) -> Option<i32> {
|
|
let first_digit = get_first_digit(line)?;
|
|
let last_digit = get_last_digit(line)?;
|
|
|
|
let digit_str = format!("{}{}", first_digit, last_digit);
|
|
digit_str.parse::<i32>().ok()
|
|
}
|
|
|
|
// Helper function to get the first digit in the string
|
|
fn get_first_digit(s: &str) -> Option<char> {
|
|
s.chars().find(|&c| c.is_digit(10))
|
|
}
|
|
|
|
// Helper function to get the last digit in the string
|
|
fn get_last_digit(s: &str) -> Option<char> {
|
|
s.chars().rev().find(|&c| c.is_digit(10))
|
|
}
|
|
|
|
// Returns an Iterator over the lines in the file
|
|
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
|
where
|
|
P: AsRef<Path>,
|
|
{
|
|
let file = File::open(filename)?;
|
|
Ok(io::BufReader::new(file).lines())
|
|
}
|