3 use itertools
::Itertools
;
5 pub fn parse(s
: &str) -> Lines
{
9 fn calibration_value(line
: &str) -> u32 {
10 let first
= line
.chars().find(|c
| c
.is_digit(10)).unwrap();
11 let last
= line
.chars().rev().find(|c
| c
.is_digit(10)).unwrap();
12 format!("{}{}", first
, last
).parse().unwrap()
15 pub fn calibration_sum(lines
: &Lines
) -> u32 {
16 lines
.clone().map(calibration_value
).sum()
19 fn calibration_value_corrected(line
: &str) -> u32 {
20 let line_chars
= line
.chars().collect_vec();
21 let mut first
: i32 = -1;
22 let mut last
: i32 = -1;
23 let spelled_digits
= [
24 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
27 while i
< line
.len() {
28 if let Some(d
) = line_chars
[i
].to_digit(10) {
34 for j
in 0..spelled_digits
.len() {
35 let d
= spelled_digits
[j
];
36 if line
[i
..].starts_with(d
) {
42 // We can't skip an entire word because of cases like
43 // "twone", "nineight", etc.
51 format!("{}{}", first
, last
).parse().unwrap()
54 pub fn calibration_sum_corrected(lines
: &Lines
) -> u32 {
55 lines
.clone().map(calibration_value_corrected
).sum()
62 static CALIBRATION_LINES
: &str = "1abc2
69 let lines
= parse(CALIBRATION_LINES
);
70 assert_eq!(calibration_sum(&lines
), 142);
73 static CALIBRATION_LINES_2
: &str = "two1nine
83 let lines
= parse(CALIBRATION_LINES_2
);
84 assert_eq!(calibration_sum_corrected(&lines
), 281);