## --- Day 5: Doesn't He Have Intern-Elves For This? ---

Santa needs help figuring out which strings in his text file are naughty or nice.

A nice string is one with all of the following properties:

• It contains at least three vowels (`aeiou` only), like `aei`, `xazegov`, or `aeiouaeiouaeiou`.
• It contains at least one letter that appears twice in a row, like `xx`, `abcdde` (`dd`), or `aabbccdd` (`aa`, `bb`, `cc`, or `dd`).
• It does not contain the strings `ab`, `cd`, `pq`, or `xy`, even if they are part of one of the other requirements.

For example:

• `ugknbfddgicrmopn` is nice because it has at least three vowels (`u...i...o...`), a double letter (`...dd...`), and none of the disallowed substrings.
• `aaa` is nice because it has at least three vowels and a double letter, even though the letters used by different rules overlap.
• `jchzalrnumimnmhp` is naughty because it has no double letter.
• `haegwjzuvuyypxyu` is naughty because it contains the string `xy`.
• `dvszwmarrgswjxmb` is naughty because it contains only one vowel.

How many strings are nice?

## Rust Solution

``````use rustgym_util::*;
use std::collections::HashMap;
use std::fmt::Write;
use std::io::*;

let mut res1 = 0;
let mut res2 = 0;
for line in it {
if nice1(&line) {
res1 += 1;
}
if nice2(&line) {
res2 += 1;
}
}
writeln!(writer, "{}", res1).unwrap();
writeln!(writer, "{}", res2).unwrap();
}

fn nice1(s: &str) -> bool {
let s: Vec<char> = s.chars().collect();
let vowels = s
.iter()
.filter(|c| matches!(c, 'a' | 'e' | 'i' | 'o' | 'u'))
.count();
let double = s.windows(2).any(|w| w == w);
let blacklist = s
.windows(2)
.any(|w| matches!(w, ['a', 'b'] | ['c', 'd'] | ['p', 'q'] | ['x', 'y']));

vowels >= 3 && double && !blacklist
}

fn nice2(s: &str) -> bool {
let mut hm: HashMap<String, Vec<usize>> = HashMap::new();
let n = s.len();
for i in 1..n {
hm.entry(s[i - 1..=i].to_string()).or_default().push(i);
}
let s: Vec<char> = s.chars().collect();
let rule1 = hm
.values()
.any(|v| v.len() >= 2 && v + 1 < v[v.len() - 1]);
let rule2 = s.windows(3).any(|w| w == w);
rule1 && rule2
}