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);
}
|