Advent of Code 2022, Day 6 -- Tuning Trouble
Day 6 of Advent of Code was suspiciously easy...
Full code for Day 6 can be found on Github.
The Day 6 problem can be found at adventofcode.com/2022/day/6.
Jump to:
My final full code:
use std::fs;
use std::collections::HashSet;
fn main() {
let input: Vec<char> = fs::read_to_string("input.txt").unwrap().trim().chars().collect();
let start_marker = find_starts(input.clone(), 4);
println!("The end of the packet sequence is at {}.", start_marker);
let message_marker = find_starts(input, 14);
println!("The end of the message sequence is at {}.", message_marker);
}
fn find_starts(input: Vec<char>, size: usize) -> usize {
for (i, window) in input.windows(size).enumerate() {
let set: HashSet<&char> = HashSet::from_iter(window.iter());
if set.len() == size {
return i + size;
}
}
0
}
That is it!!!
Part 1
Now, this puzzle would've been a lot harder without windows. I've used the sliding window technique in Python before, but Rust has a very nifty method for when you need windows that are of a fixed size.
(The link for the sliding window technique above uses two pointers to find a window of an ambiguous size, but the concept is the same here. We're just sliding a window of a fixed size across a vector.)
I'm enumerating over the vector of windows with an index because I need the position of the last character in the string that satisfies the requirements of all characters being equal. To get that number, all I need is the index of the winning window + the size of the window.
To check if all the characters in the window are unique, I'm adding the window to a HashSet, which will automatically remove any duplicates. I could have also used .dedup()
like I did in day 3.
Then, I check if the length of the set is equal to the size of the window, and if it is, I return the index of the window plus the size.
Part 2
For part 2 I was able to repurpose the same function, but instead of passing in 4 as the size of the window/unique string, I passed in 14.
What I learned
- .windows() - Iterator that returns a series of smaller overlapping chunks of a fixed size.
- ::from_iter() - I shoud use this more often. It collects into a data structure from an iterator. I knew that
HashSet::from()
used an array, butHashSet::from_iter()
is much more convenient when working with vectors.