summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2022-09-01 01:18:51 +0200
committerReiner Herrmann <reiner@reiner-h.de>2022-09-01 01:18:51 +0200
commit5cb048c542c7610530b66696736a932f62037994 (patch)
tree4ee4eef05778d82cdba300386c1f32b9aa1e2d4d
parentb5e1c27db8c7d330ac13e43927b791b21d95de18 (diff)
day11
-rw-r--r--src/bin/day11.rs80
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");
+ }
+}