summaryrefslogtreecommitdiff
path: root/06/src/part-2.rs
diff options
context:
space:
mode:
Diffstat (limited to '06/src/part-2.rs')
-rw-r--r--06/src/part-2.rs47
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;
+ }
+ }
+ }
+
+}