summaryrefslogtreecommitdiff
path: root/src/bin/day1.rs
blob: ec4c2bc253329914c1472188a5e38a69605a3e60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
static DAY: u8 = 1;

fn main() {
    let input = advent::read_lines(DAY);
    println!("{DAY}a: {}", sum_digits(&input, false));
    println!("{DAY}b: {}", sum_digits(&input, true));
}

fn starts_with_number(word: &str, consider_words: bool) -> Option<u32> {
    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 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
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test() {
        let input = [
            "1abc2",
            "pqr3stu8vwx",
            "a1b2c3d4e5f",
            "treb7uchet",
        ].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
        assert_eq!(sum_digits(&input, false), 142);

        let input = [
            "two1nine",
            "eightwothree",
            "abcone2threexyz",
            "xtwone3four",
            "4nineeightseven2",
            "zoneight234",
            "7pqrstsixteen",
        ].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
        assert_eq!(sum_digits(&input, true), 281);
    }
}