use std::fs::File; use std::io::{BufRead, BufReader, Lines}; // BOILERPLATE type InputIter = Lines>; fn get_input() -> InputIter { let f = File::open("input").unwrap(); let br = BufReader::new(f); br.lines() } fn main() { println!("Problem 1 solution: {}", problem1(get_input())); println!("Problem 2 solution: {}", problem2(get_input())); } // PROBLEM1 solution fn problem1_lineval(line: &String) -> u64 { // forward iterate to find the first numeric value let first = line.chars().find(|c| c.is_digit(10)).unwrap(); let last = line.chars().rev().find(|c| c.is_digit(10)).unwrap(); (first.to_digit(10).unwrap() * 10 + last.to_digit(10).unwrap()).into() } fn problem1(input: InputIter) -> u64 { input.map(|line| problem1_lineval(&line.unwrap())).sum() } // PROBLEM2 solution const DIGITS: &[(&str, u64)] = &[ ("one", 1), ("two", 2), ("three", 3), ("four", 4), ("five", 5), ("six", 6), ("seven", 7), ("eight", 8), ("nine", 9), ]; fn problem2_numeric(start: &str) -> Option { let char = start.chars().nth(0).unwrap(); if char.is_numeric() { Some(char.to_digit(10).unwrap().into()) } else { for (s, n) in DIGITS { if start.starts_with(s) { return Some(*n); } } None } } fn problem2_lineval(line: &String) -> u64 { let mut first = None; for pos in 0..line.len() { let (_, sub) = line.split_at(pos); if let Some(n) = problem2_numeric(sub) { first = Some(n); break; } else { continue; } } let mut second = None; for pos in (0..line.len()).rev() { let (_, sub) = line.split_at(pos); if let Some(n) = problem2_numeric(sub) { second = Some(n); break; } else { continue; } } first.unwrap() * 10 + second.unwrap() } fn problem2(input: InputIter) -> u64 { input.map(|line| problem2_lineval(&line.unwrap())).sum() }