aboutsummaryrefslogtreecommitdiff
path: root/2022/src/day06.rs
blob: 8bbfe6d3107996df85e3a7ec3ed431b723302c27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
mod utils;
use utils::read_input;

fn main() {
    let input = read_input();

    println!("Part 1: {}", find_chunk_nodup::<4>(&input));
    println!("Part 2: {}", find_chunk_nodup::<14>(&input));
}

fn find_chunk_nodup<const N: usize>(input: &str) -> usize {
    let mut window = ['a'; N];
    let mut chars = input.chars();

    // Fill up initial window
    for item in window.iter_mut() {
        *item = chars.next().unwrap();
    }

    for i in 0..input.len() {
        // Shuffle everything in window down
        for j in 0..N - 1 {
            window[j] = window[j + 1];
        }
        window[N - 1] = chars.next().unwrap();

        if window
            .iter()
            .fold(Some(0), |acc, chr| add_char(acc?, *chr))
            .is_some()
        {
            return i + N + 1;
        }
    }

    panic!("no solution!")
}

#[inline]
fn add_char(bits: u32, chr: char) -> Option<u32> {
    let add = 1 << (chr.to_ascii_lowercase() as u32 - 97);
    if (bits | add) != bits {
        Some(bits | add)
    } else {
        None
    }
}