year2017/
day04.rs

1use std::collections::HashSet;
2use utils::prelude::*;
3
4/// Checking passphrase validity.
5#[derive(Clone, Debug)]
6pub struct Day04<'a> {
7    input: &'a str,
8}
9
10impl<'a> Day04<'a> {
11    pub fn new(input: &'a str, _: InputType) -> Result<Self, InputError> {
12        if let Some(w) = input.find(|c: char| !c.is_ascii_lowercase() && !c.is_ascii_whitespace()) {
13            Err(InputError::new(input, w, "expected lowercase letters"))
14        } else {
15            Ok(Self { input })
16        }
17    }
18
19    #[must_use]
20    pub fn part1(&self) -> usize {
21        let mut seen = HashSet::new();
22        self.input
23            .lines()
24            .filter(|line| {
25                seen.clear();
26                line.split_ascii_whitespace().all(|word| seen.insert(word))
27            })
28            .count()
29    }
30
31    #[must_use]
32    pub fn part2(&self) -> usize {
33        let mut seen = HashSet::new();
34        self.input
35            .lines()
36            .filter(|line| {
37                seen.clear();
38                line.split_ascii_whitespace().all(|word| {
39                    let mut letters = [0u8; 26];
40                    for b in word.bytes() {
41                        letters[b as usize - b'a' as usize] += 1;
42                    }
43                    seen.insert(letters)
44                })
45            })
46            .count()
47    }
48}
49
50examples!(Day04<'_> -> (usize, usize) [
51    {input: "aa bb cc dd ee", part1: 1},
52    {input: "aa bb cc dd aa", part1: 0},
53    {input: "aa bb cc dd aaa", part1: 1},
54    {input: "abcde fghij", part2: 1},
55    {input: "abcde xyz ecdab", part2: 0},
56    {input: "a ab abc abd abf abj", part2: 1},
57    {input: "iiii oiii ooii oooi oooo", part2: 1},
58    {input: "oiii ioii iioi iiio", part2: 0},
59]);