#![allow(dead_code)] use std::collections::VecDeque; use std::fs::File; use std::io; use std::io::BufRead; use std::path::Path; use std::time::Instant; fn main() { let now = Instant::now(); part_one(); let part_one_duration = now.elapsed(); part_two(); let part_two_duration = now.elapsed(); println!( "p1: {}ms, p2: {}ms", part_one_duration.as_millis(), (part_two_duration - part_one_duration).as_millis() ); } fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { // note that this discards a final newline let file = File::open(filename)?; Ok(io::BufReader::new(file).lines()) } fn part_one() { if let Ok(mut lines) = read_lines("./inputs/input") { if let Some(Ok(signal)) = lines.next() { let mut buf = VecDeque::::new(); for (i, c) in signal.chars().enumerate() { if buf.len() < 3 { // start of stream buf.push_back(c); continue; } else if buf.contains(&c) || buf[0] == buf[1] || buf[1] == buf[2] || buf[2] == buf[0] { // repeated character buf.pop_front(); buf.push_back(c); } else { // found it; offset to the next character println!("{}", i + 1); return; } } } } } fn part_two() { if let Ok(mut lines) = read_lines("./inputs/input") { if let Some(Ok(signal)) = lines.next() { let mut buf = VecDeque::::new(); for (i, c) in signal.chars().enumerate() { if buf.len() < 13 { // start of stream buf.push_back(c); continue; } else if buf.contains(&c) || (1..buf.len()).any(|i| { buf.range(i..) .collect::>() .contains(&&buf[i - 1]) // neat trick }) { // repeated character buf.pop_front(); buf.push_back(c); } else { // found it; offset to the next character println!("{}", i + 1); return; } } } } }