diff options
Diffstat (limited to '06/src/part-2.rs')
-rw-r--r-- | 06/src/part-2.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/06/src/part-2.rs b/06/src/part-2.rs new file mode 100644 index 0000000..8f004b0 --- /dev/null +++ b/06/src/part-2.rs @@ -0,0 +1,47 @@ +/* +Just for fun, we'll try to pry out efficiency everywhere here: + - Don't do the convenient line iteration (causing allocations). + - Don't do UTF-8 allocation. + - Store seen characters in bitmap. + - TODO: There are probably some non-elided indexing safety checks. +*/ + +use std::io::{BufRead}; + +const MARKER_LEN: usize = 14; + +fn count_ones<const N: usize>(xs: & [usize; N]) -> usize { + let mut ret: usize = 0; + for x in xs { + if *x == 1 { ret += 1; } + } + ret +} + +fn main() { + let stdin = std::io::stdin(); + let mut handle = stdin.lock(); + + let mut buf: Vec<u8> = Vec::new(); + + loop { + buf.clear(); + let num_bytes = handle.read_until(b'\n', &mut buf).expect("IO error"); + if num_bytes == 0 { break; } + if buf.len() < MARKER_LEN { panic!("Malformed input"); } + + let mut counts: [usize; 26] = [0; 26]; + + for i in 0..buf.len() { + if i >= MARKER_LEN { + counts[(buf[i-MARKER_LEN] - b'a') as usize] -= 1; + } + counts[(buf[i] - b'a') as usize] += 1; + if count_ones(& counts) == MARKER_LEN { + println!("{}", i + 1); + break; + } + } + } + +} |