AdventOfCode/y2015/src/days/d11.rs
2024-10-29 14:36:36 +01:00

71 lines
1.9 KiB
Rust

pub fn process_part1(input: &str) -> String {
let mut password = input.to_string();
loop {
password = increment(&password);
if password.contains("i") || password.contains("o") || password.contains("l") {
continue;
}
if !has_straight(&password) {
continue;
}
if num_pairs(&password) < 2 {
continue;
}
return password;
}
}
fn has_straight(password: &str) -> bool {
for window in password.as_bytes().windows(3) {
let (a, b, c) = (window[0], window[1], window[2]);
let (inc_b, inc_c) = (increment_letter(a), increment_letter(b));
if b == inc_b.0 && c == inc_c.0 && !(inc_b.1 || inc_c.1) {
return true;
}
}
false
}
fn num_pairs(password: &str) -> u32 {
let mut num_pairs = 0;
let mut was_last_pair = false;
password.as_bytes().windows(2).for_each(|window| {
if window[0] == window[1] && !was_last_pair {
num_pairs += 1;
was_last_pair = true;
} else {
was_last_pair = false;
}
});
num_pairs
}
fn increment(password: &str) -> String {
let mut password_bytes = password.as_bytes().to_vec();
password_bytes.reverse();
let mut new_password_bytes = vec![];
let mut increment_next = true;
for letter in password_bytes {
if increment_next {
let (new_letter, overflow) = increment_letter(letter);
new_password_bytes.push(new_letter);
increment_next = overflow;
} else {
new_password_bytes.push(letter);
}
}
if increment_next {
new_password_bytes.push(b'a');
}
new_password_bytes.reverse();
String::from_utf8(new_password_bytes).unwrap()
}
fn increment_letter(letter: u8) -> (u8, bool) {
if letter == b'z' {
(b'a', true)
} else {
(letter + 1, false)
}
}