--- title: "Advent of Code: Day Six" date: 2022-12-06T00:00:00 slug: advent-of-code-day-six tags: [advent-of-code-2022] --- **Spoilers for Advent of Code below** * [Day five](/post/advent-of-code-day-five) * [All Advent of Code posts](/blog/category/advent-of-code) * [Source](https://github.com/lewisdaleuk/advent-of-code-2022) Day six was a nice, welcome break from the struggle I had yesterday. ## Part one Given a set of characters relaying a message, find the index of packet start signal, which comes after the first four unique characters. So if my input is: ```txt mjqjpqmgbljsphdztnvjfqwrcgsmlb ``` then my output should be `5`, because that is the index of the first set of unique characters - `qjpq`. My first attempt was also my last attempt, as I used a `HashSet` of characters from a moving 5-char block. If the length was 5, that meant I'd found the index of my packet marker. ```rust pub fn find_marker_index(input: &str) -> Option { let mut set: HashSet = HashSet::new(); for idx in 0..input.len() { set = HashSet::from_iter(input[idx..=idx+4].chars()); if set.len() == 5 { return Some(idx+4); } } None } ``` ## Part two Much the same, except now we need to also find a message start signal, which comes after `14` unique characters. I updated my `find_marker_index` function to take an offset, and updated the logic to use it. I also reversed my range, because I realised that I would quite easily hit string overflow issues - it was simply luck that I hadn't yet: ```rust pub fn find_marker_index(input: &str, marker_offset: usize) -> Option { let mut set: HashSet; for idx in marker_offset..input.len() { set = HashSet::from_iter(input[idx-marker_offset..idx].chars()); if set.len() == marker_offset { return Some(idx); } } None } ``` As a final pass, I moved my function to a `trait` implemented on `str`, because I'm trying to learn how to properly work with them: ```rust pub trait FindUnique { fn find_unique(&self, offset: usize) -> Option; } impl FindUnique for str { fn find_unique(&self, offset: usize) -> Option { for idx in offset..self.len() { let len = HashSet::::from_iter(self[idx - offset..idx].chars()).len(); if len == offset { return Some(idx); } } None } } ``` Which means I can now just call my function straight from reading the file: ```rust if let Some(idx) = read_file(...).unwrap().find_unique(14) { // Output } ``` And that worked! Day six checked off, with a nice tidy solution that I'm very happy with.