diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2022-09-01 01:18:51 +0200 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2022-09-01 01:18:51 +0200 |
| commit | 5cb048c542c7610530b66696736a932f62037994 (patch) | |
| tree | 4ee4eef05778d82cdba300386c1f32b9aa1e2d4d | |
| parent | b5e1c27db8c7d330ac13e43927b791b21d95de18 (diff) | |
day11
| -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"); + } +} |
