// use itertools::Itertools; use std::fs; pub fn run() { println!("Day 1:"); let input = fs::read_to_string("./inputs/day1.txt").expect("Could not read file"); println!("\tPart 1: {}", part1(&input)); println!("\tPart 2: {}", part2(&input)); } fn part1(calibration_input: &str) -> usize { calibration_input .split("\n") .map(|line| { let digits = line.chars().filter(|c| c.is_digit(10)).collect::(); if digits.len() == 1 { digits.parse::().unwrap() * 11 } else { let tens = digits.chars().nth(0).unwrap().to_digit(10).unwrap(); let ones = digits.chars().last().unwrap().to_digit(10).unwrap(); (tens * 10 + ones) as usize } }) .into_iter() .sum() } fn part2(calibration_input: &str) -> usize { let word_to_digit_map: [(&str, usize); 9] = [ ("one", 1), ("two", 2), ("three", 3), ("four", 4), ("five", 5), ("six", 6), ("seven", 7), ("eight", 8), ("nine", 9), ]; calibration_input .split("\n") .map(|line| { let mut index_and_digit: Vec<(usize, usize)> = vec![]; for (word, digit) in word_to_digit_map { for (index, _) in line.match_indices(word).collect::>() { index_and_digit.push((index, digit)); } } for (index, c) in line.chars().enumerate() { match c.to_digit(10) { Some(digit) => index_and_digit.push((index, digit as usize)), None => continue, } } if index_and_digit.len() == 1 { index_and_digit[0].1 * 11 } else { index_and_digit.sort_by(|a, b| a.0.cmp(&b.0)); println!( "{} {}", &line, index_and_digit[0].1 * 10 + index_and_digit.last().unwrap().1 ); index_and_digit[0].1 * 10 + index_and_digit.last().unwrap().1 } }) .into_iter() .sum() } #[cfg(test)] mod tests { use super::*; #[test] fn test_1() { let input = "1abc2 pqr3stu8vwx a1b2c3d4e5f treb7uchet"; assert_eq!(part1(input), 142); } #[test] fn test_2() { let input = "two1nine eightwothree abcone2threexyz xtwone3four 4nineeightseven2 zoneight234 7pqrstsixteen"; assert_eq!(part2(input), 281); } }