76 lines
1.6 KiB
Rust
76 lines
1.6 KiB
Rust
use aoc_runner_derive::aoc;
|
|
|
|
#[aoc(day11, part1)]
|
|
fn part1(input: &str) -> String {
|
|
PasswordCounter::from(input.to_owned()).find(|p| {
|
|
let r1 = rule1(&p);
|
|
let r2 = rule2(&p);
|
|
let r3 = rule3(&p);
|
|
r1 && r2 && r3
|
|
}).unwrap()
|
|
}
|
|
|
|
fn rule1(pw: &str) -> bool {
|
|
let pw = pw.as_bytes();
|
|
for i in 0..pw.len() - 2 {
|
|
if pw[i + 1] == pw[i] + 1 && pw[i + 2] == pw[i] + 2 {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
fn rule2(pw: &str) -> bool {
|
|
!pw.contains(['i', 'o', 'l'])
|
|
}
|
|
|
|
fn rule3(pw: &str) -> bool {
|
|
let mut pair_one = None;
|
|
let pw = pw.as_bytes();
|
|
for i in 0..pw.len() - 1 {
|
|
if pw[i] == pw[i + 1] {
|
|
if let Some(b) = pair_one {
|
|
if b != pw[i] {
|
|
return true;
|
|
}
|
|
} else {
|
|
pair_one = Some(pw[i]);
|
|
}
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
struct PasswordCounter {
|
|
current: [u8; 8],
|
|
}
|
|
|
|
impl PasswordCounter {
|
|
fn from(seed: String) -> Self {
|
|
let mut current = [0u8; 8];
|
|
for i in 0..8 {
|
|
current[i] = seed.as_bytes()[i];
|
|
}
|
|
PasswordCounter { current }
|
|
}
|
|
}
|
|
|
|
impl Iterator for PasswordCounter {
|
|
type Item = String;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let pw = &mut self.current;
|
|
for i in (0..pw.len()).rev() {
|
|
pw[i] += 1;
|
|
if pw[i] != b'z' + 1 {
|
|
break;
|
|
}
|
|
pw[i] = b'a';
|
|
}
|
|
|
|
Some(String::from_iter(self.current.iter().map(|b| *b as char)))
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {} |