-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-2.rs
84 lines (75 loc) · 2.26 KB
/
day-2.rs
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
74
75
76
77
78
79
80
81
82
83
84
use std::{str::FromStr, ops::RangeInclusive};
const INPUT: &str = include_str!("day-2.input");
trait FindFrom<T> {
fn find_from(&self, index: usize, pat: T) -> Option<usize>;
}
impl FindFrom<char> for &str {
fn find_from(&self, index: usize, pat: char) -> Option<usize> {
self[index..].find(pat).map(|i| i + index)
}
}
struct Password {
text: String,
range: RangeInclusive<usize>,
ch: char,
}
impl FromStr for Password {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let range_sep = s.find('-').ok_or("missing '-'")?;
let range_end = s.find_from(range_sep, ' ').ok_or("missing ' '")?;
let colon = s.find_from(range_end, ':').ok_or("missing ':'")?;
let min = s[..range_sep].parse().map_err(|_| "min range parse error")?;
let max = s[(range_sep+1)..range_end].parse().map_err(|_| "max range parse error")?;
let ch = s[(range_end+1)..].chars().next().ok_or("missing char")?;
let text = s[(colon+1)..].trim().to_string();
Ok(Self {
text,
range: min..=max,
ch
})
}
}
fn main() -> Result<(), &'static str> {
part_1()?;
part_2()?;
Ok(())
}
fn part_1() -> Result<(), &'static str> {
println!("=[ part 1 ]=");
let mut valid = 0;
for line in INPUT.lines() {
let pw = line.parse::<Password>()?;
let mut ch_count = 0;
for ch in pw.text.chars() {
if ch == pw.ch {
ch_count += 1;
}
}
if pw.range.contains(&ch_count) {
valid += 1;
}
}
println!("valid passwords: {}", valid);
Ok(())
}
fn part_2() -> Result<(), &'static str> {
println!("\n=[ part 2 ]=");
let mut valid = 0;
for line in INPUT.lines() {
let pw = line.parse::<Password>()?;
let chars: Vec<char> = pw.text.chars().collect();
let mut count = 0;
if chars.len() >= *pw.range.start() && chars[*pw.range.start() - 1] == pw.ch {
count += 1;
}
if chars.len() >= *pw.range.end() && chars[*pw.range.end() - 1] == pw.ch {
count += 1;
}
if count == 1 {
valid += 1;
}
}
println!("valid passwords: {}", valid);
Ok(())
}