diff --git a/src/day11.rs b/src/day11.rs new file mode 100644 index 0000000..455eec4 --- /dev/null +++ b/src/day11.rs @@ -0,0 +1,76 @@ +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 { + 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 {} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a434274..2ceb10c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,5 +3,6 @@ extern crate aoc_runner; extern crate aoc_runner_derive; mod day10; +mod day11; aoc_lib! { year = 2015 }