summaryrefslogtreecommitdiff
path: root/2019/rust/day04/src/main.rs
blob: c4cadef58e520268718524017f67645705b413f9 (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
72
73
use itertools::Itertools;
use std::env;

fn is_increasing(n:u32) -> bool {
    for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10)
        .zip((1..6).rev().map(|e| n/10u32.pow(e)%10))
    {
        if l < r { return false; }
    }

    true
}

fn has_repeated(n:u32) -> bool {
    for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10)
        .zip((1..6).rev().map(|e| n/10u32.pow(e)%10))
    {
        if l == r { return true; }
    }

    false
}
fn has_double(n:u32) -> bool {
    #[derive(Debug, PartialEq)]
    enum State { NoMatch, Matching, TooLong, Verified };
    let mut state = State::NoMatch;

    for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10)
        .zip((1..6).rev().map(|e| n/10u32.pow(e)%10))
    {
        state = match state {
            State::NoMatch  => if l == r { State::Matching } else { State::NoMatch },
            State::Matching => if l == r { State::TooLong  } else { State::Verified },
            State::TooLong  => if l == r { State::TooLong  } else { State::NoMatch },
            State::Verified => State::Verified,
        };
        if state == State::Verified { break; }
    }

    state == State::Verified || state == State::Matching
}

fn first_puzzle(input:String) -> usize {
    let ( start, end ) = input.split("-")
        .map(|s| s.parse::<u32>().unwrap())
        .next_tuple().unwrap();

    (start..=end)
        .filter(|n| is_increasing(*n))
        .filter(|n| has_repeated(*n))
        .count()
}

fn second_puzzle(input:String) -> usize {
    let ( start, end ) = input.split("-")
        .map(|s| s.parse::<u32>().unwrap())
        .next_tuple().unwrap();

    (start..=end)
        .filter(|n| is_increasing(*n))
        .filter(|n| has_double(*n))
        .count()
}

fn main() {
    let input = env::args().nth(1).expect("Please provide a valid range as first argument.");

    let first = first_puzzle(input.clone());
    println!("Solution to first part: {}.", first);

    let second = second_puzzle(input);
    println!("Solution to second part: {}.", second);
}