From 2af5f34f1ec4a01f1d08b2278330f422b00f4b5e Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Fri, 1 Dec 2023 12:34:19 +0100 Subject: day1 solution 2 --- src/bin/day1.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/bin/day1.rs b/src/bin/day1.rs index 4784496..ec4c2bc 100644 --- a/src/bin/day1.rs +++ b/src/bin/day1.rs @@ -2,20 +2,43 @@ static DAY: u8 = 1; fn main() { let input = advent::read_lines(DAY); - println!("{DAY}a: {}", sum_digits(&input)); - println!("{DAY}b: {}", 0); + println!("{DAY}a: {}", sum_digits(&input, false)); + println!("{DAY}b: {}", sum_digits(&input, true)); } -fn sum_digits(input: &[String]) -> u32 { +fn starts_with_number(word: &str, consider_words: bool) -> Option { + if let Some(digit) = word.chars().next().unwrap().to_digit(10) { + return Some(digit); + } + if !consider_words { + return None + } + let digits = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]; + for (pos, digit) in digits.iter().enumerate() { + if word.starts_with(digit) { + return Some(pos as u32 + 1); + } + } + None +} + +fn sum_digits(input: &[String], consider_words: bool) -> u32 { let mut sum = 0; for line in input { - let left_pos = line.find(|c: char| c.is_digit(10)).expect("line contains digit"); - let right_pos = line.rfind(|c: char| c.is_digit(10)).expect("line contains digit"); - - let line = line.as_bytes(); - let left_digit = (line[left_pos] as char).to_digit(10).unwrap(); - let right_digit = (line[right_pos] as char).to_digit(10).unwrap(); - sum += (left_digit * 10 + right_digit) as u32; + let mut line_number = 0; + for pos in 0 .. line.len() { + if let Some(number) = starts_with_number(&line[pos..], consider_words) { + line_number += 10 * number; + break; + } + } + for pos in (0 .. line.len()).rev() { + if let Some(number) = starts_with_number(&line[pos..], consider_words) { + line_number += number; + break; + } + } + sum += line_number; } sum } @@ -32,6 +55,17 @@ mod tests { "a1b2c3d4e5f", "treb7uchet", ].iter().map(|&x| String::from(x)).collect::>(); - assert_eq!(sum_digits(&input), 142); + assert_eq!(sum_digits(&input, false), 142); + + let input = [ + "two1nine", + "eightwothree", + "abcone2threexyz", + "xtwone3four", + "4nineeightseven2", + "zoneight234", + "7pqrstsixteen", + ].iter().map(|&x| String::from(x)).collect::>(); + assert_eq!(sum_digits(&input, true), 281); } } -- cgit v1.2.3