add day 11
This commit is contained in:
Generated
+25
@@ -0,0 +1,25 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day11"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "day11"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
itertools = "0.15.0"
|
||||||
@@ -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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user