Day 24
Feelings
Part 1 ➟ Yay, let's 2d grid again! Except this time it has 6 neighbors instead of 4.
I thought that this is a good opportunity to build really nice classes. While at the same time I was really REALLY hoping part 2 didn't turn into some 4D hex tiled mess.
Part 2 ➟ Phew! Got lucky and this is just cellular automaton. Just with twist of having that 6 neighbors.
So this is the "whole code", except everything is hidden behind HexMap (and even more hidden behind HexPath):
#[allow(clippy::unnecessary_wraps)]
pub fn parse_input(input: &str) -> AnyhowResult<Input> {
Ok(input
.lines()
.map(|l| l.parse().unwrap())
.collect())
}
pub fn part1(_input: &Input) -> usize {
let mut map: HexMap = HexMap::new();
_input.into_iter()
.for_each(|path| map.flip(path.into()));
map.count_black()
}
pub fn part2(_input: &Input) -> usize {
let mut map: HexMap = HexMap::new();
_input.into_iter()
.for_each(|path| map.flip(path.into()));
(1 ..= 100).for_each(|_| {
map.next().unwrap();
});
map.count_black()
}
Learnings
as _
Instead of this:
let mut cups: VecDeque<u32> = _input.into_iter().map(|n|*n as u32).collect();
You can just do this:
let mut cups: VecDeque<u32> = _input.into_iter().map(|n|*n as _).collect();
Only works when the type is known naturally. But it's awesome for those times when you need to use as.
lazy_static! macro
I haven't used it much so I wanted to build static HashMap with it. NEIGHBOR_DIRECTIONS was a perfect candidate. (Though it could be made simpler and without HashMap and without static and without lazy_static!.. But I wanted to make it like this today. =D)
Laying out the classes
This was kinda fun. It's nice to see quite clear code when you set it up like this.
HexMap
The main game processor. The iterator of HexMap advances game of hex one step.
HexTile
A structure representing an address in the map in absolute coordinates.
This can be used as an iterator to get all the neighbors. HexTileIter is returned by HexTile.iter().
There are quite many ways to convert from other types to HexTile.
You can also add two hextiles together. Since coordinates can be negative, there can be a "relative" HexTile that represents a neighbor tile. Adding those two together will get you absolute position of a neighbor tile.
HexPath
Can be converted from a line in the input. Results in a Vec of HexDirection (which is a enum of directions).
HexPath can be converted always to HexTile which represents the end of the HexPath.
Improvements
Likely could be faster
Currently part2 takes about 77ms. Maybe it could be improved.
Replace HashMap with HashSet
Currently HashMap contains information about the color of the tile. It just only contains black tiles though.
Should be converted to HashSet, but I assume not much improvement will be made by that change.