add day 11

This commit is contained in:
timeshifter
2026-06-22 20:46:22 +02:00
parent 5d7caa5a84
commit c2dd0d1f56
3 changed files with 160 additions and 0 deletions
+128
View File
@@ -0,0 +1,128 @@
use itertools::Itertools;
// const INPUT: &str = "ghijklmn";
// const INPUT: &str = "vzbxkghb";
const INPUT: &str = "vzbxxyzz";
fn main() {
part1(INPUT);
}
fn part1(input: &str) {
let mut input = increment(input);
loop {
if is_valid(&input) {
break;
}
input = increment(&input);
}
println!("{}", input);
}
fn increment(input: &str) -> String {
let chars = input.chars().collect_vec();
let mut carry = false;
let mut iter = chars.iter().rev();
let mut result = String::new();
let c = iter.next().unwrap();
let ret = handle_char(*c, true, carry);
result.push(ret.0);
carry = ret.1;
for c in iter {
let ret = handle_char(*c, false, carry);
result.push(ret.0);
carry = ret.1;
}
result.chars().rev().collect()
}
fn handle_char(c: char, increase: bool, carry: bool) -> (char, bool) {
let increase_input = if increase { 1 } else { 0 };
let carry_input = if carry { 1 } else { 0 };
let result = c as u8 + increase_input + carry_input;
let carry_result = result >= 123;
let result = (((result - 97) % 26) + 97) as char;
(result, carry_result)
}
fn is_valid(p: &str) -> bool {
for letter in ['i', 'o', 'l'] {
if p.contains(letter) {
return false;
}
}
let non_overlapping_double_letter_count = p
.chars()
.enumerate()
.tuple_windows()
.filter(|(a, b)| a.1 == b.1)
.map(|(a, _)| a.0)
.collect_vec();
let max = non_overlapping_double_letter_count.last().unwrap_or(&0);
let min = non_overlapping_double_letter_count.first().unwrap_or(&0);
if max - min < 2 {
return false;
}
let input = p.chars().collect_vec();
for i in 0..p.len() - 2 {
let s = i;
let e = s + 2;
if is_straight(&input[s..=e]) {
return true;
}
}
false
}
fn is_straight(s: &[char]) -> bool {
if s.len() != 3 {
panic!("must check exactly 3 letters");
}
let mut chars = s.iter();
let a = *chars.next().unwrap() as u8;
let b = *chars.next().unwrap() as u8;
let c = *chars.next().unwrap() as u8;
b == a + 1 && c == b + 1
}
#[cfg(test)]
mod test {
use crate::{handle_char, is_valid};
#[test]
fn test_increase_char() {
assert_eq!(handle_char('a', true, false), ('b', false));
assert_eq!(handle_char('a', true, true), ('c', false));
assert_eq!(handle_char('i', true, false), ('j', false));
assert_eq!(handle_char('z', true, false), ('a', true));
assert_eq!(handle_char('z', true, true), ('b', true));
}
#[test]
fn test_is_valid() {
assert!(is_valid("abcdffaa"));
assert!(is_valid("ghjaabcc"));
assert!(!is_valid("hijklmmn"));
assert!(!is_valid("abbceffg"));
assert!(!is_valid("abbcegjk"));
}
}