diff options
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/day11.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/bin/day11.rs b/src/bin/day11.rs new file mode 100644 index 0000000..b945c73 --- /dev/null +++ b/src/bin/day11.rs @@ -0,0 +1,80 @@ +use std::collections::HashSet; + +fn main() { + let input = "hxbxwxba"; + println!("11a: {}", next_password(input)); + println!("11b: {}", next_password(&next_password(input))); +} + +fn has_straight(password: &str) -> bool { + let mut prevprev = password.chars().next().unwrap().to_digit(36).unwrap(); + let mut prev = password.chars().nth(1).unwrap().to_digit(36).unwrap(); + + for c in password.chars().skip(2) { + let digit = c.to_digit(36).unwrap(); + if prevprev + 1 == prev && prev + 1 == digit { + return true; + } + prevprev = prev; + prev = digit; + } + false +} + +fn has_forbidden_letters(password: &str) -> bool { + password.contains('i') || password.contains('o') || password.contains('l') +} + +fn has_two_pairs(password: &str) -> bool { + let mut pairs = HashSet::new(); + let mut prev = password.chars().next().unwrap(); + + for c in password.chars().skip(1) { + if prev == c { + pairs.insert(c); + } + prev = c; + } + pairs.len() > 1 +} + +fn valid_password(password: &str) -> bool { + has_straight(password) && !has_forbidden_letters(password) && has_two_pairs(password) +} + +fn inc_password_at_position(password: &str, pos: usize) -> String { + let mut bytes = password.to_string().into_bytes(); + bytes.reverse(); + bytes[pos] += 1; + if bytes[pos] > b'z' { + bytes[pos] = b'a'; + bytes.reverse(); + let new_password = String::from_utf8(bytes.to_vec()).unwrap(); + inc_password_at_position(&new_password, pos + 1) + } else { + bytes.reverse(); + String::from_utf8(bytes.to_vec()).unwrap() + } +} + +fn next_password(password: &str) -> String { + let mut password = inc_password_at_position(password, 0); + while !valid_password(&password) { + password = inc_password_at_position(&password, 0) + } + password +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + assert!(!valid_password("hijklmmn")); + assert!(!valid_password("abbceffg")); + assert!(!valid_password("abbcegjk")); + assert_eq!(next_password("abcdefgh"), "abcdffaa"); + assert_eq!(next_password("ghijklmn"), "ghjaabcc"); + } +} |
