Lobby Layout


Fork me on GitHub
2020-12-24

Day 24: Lobby Layout

Description:
Your raft makes it to the tropical island; it turns out that the small crab was an excellent navigator. You make your way to the resort.

As you enter the lobby, you discover a small problem: the floor is being renovated. You can't even reach the check-in desk until they've finished installing the new tile floor.

The tiles are all hexagonal; they need to be arranged in a hex grid with a very specific color pattern. Not in the mood to wait, you offer to help figure out the pattern.

The tiles are all white on one side and black on the other. They start with the white side facing up. The lobby is large enough to fit whatever pattern might need to appear there.

A member of the renovation crew gives you a list of the tiles that need to be flipped over (your puzzle input). Each line in the list identifies a single tile that needs to be flipped by giving a series of steps starting from a reference tile in the very center of the room. (Every line starts from the same reference tile.)

Because the tiles are hexagonal, every tile has six neighbors: east, southeast, southwest, west, northwest, and northeast. These directions are given in your list, respectively, as e, se, sw, w, nw, and ne. A tile is identified by a series of these directions with no delimiters; for example, esenee identifies the tile you land on if you start at the reference tile and then move one tile east, one tile southeast, one tile northeast, and one tile east.

Each time a tile is identified, it flips from white to black or from black to white. Tiles might be flipped more than once. For example, a line like esew flips a tile immediately adjacent to the reference tile, and a line like nwwswee flips the reference tile itself.

Here is a larger example:

sesenwnenenewseeswwswswwnenewsewsw
neeenesenwnwwswnenewnwwsewnenwseswesw
seswneswswsenwwnwse
nwnwneseeswswnenewneswwnewseswneseene
swweswneswnenwsewnwneneseenw
eesenwseswswnenwswnwnwsewwnwsene
sewnenenenesenwsewnenwwwse
wenwwweseeeweswwwnwwe
wsweesenenewnwwnwsenewsenwwsesesenwne
neeswseenwwswnwswswnw
nenwswwsewswnenenewsenwsenwnesesenew
enewnwewneswsewnwswenweswnenwsenwsw
sweneswneswneneenwnewenewwneswswnese
swwesenesewenwneswnwwneseswwne
enesenwswwswneneswsenwnewswseenwsese
wnwnesenesenenwwnenwsewesewsesesew
nenewswnwewswnenesenwnesewesw
eneswnwswnwsenenwnwnwwseeswneewsenese
neswnwewnwnwseenwseesewsenwsweewe
wseweeenwnesenwwwswnew

In the above example, 10 tiles are flipped once (to black), and 5 more are flipped twice (to black, then back to white). After all of these instructions have been followed, a total of 10 tiles are black.

Go through the renovation crew's list and determine which tiles they need to flip. After all of the instructions have been followed, how many tiles are left with the black side up?

--- Part Two ---

The tile floor in the lobby is meant to be a living art exhibit. Every day, the tiles are all flipped according to the following rules:

Any black tile with zero or more than 2 black tiles immediately adjacent to it is flipped to white.
Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black.

Here, tiles immediately adjacent means the six tiles directly touching the tile in question.

The rules are applied simultaneously to every tile; put another way, it is first determined which tiles need to be flipped, then they are all flipped at the same time.

In the above example, the number of black tiles that are facing up after the given number of days has passed is as follows:

Day 1: 15
Day 2: 12
Day 3: 25
Day 4: 14
Day 5: 23
Day 6: 28
Day 7: 41
Day 8: 37
Day 9: 49
Day 10: 37

Day 20: 132
Day 30: 259
Day 40: 406
Day 50: 566
Day 60: 788
Day 70: 1106
Day 80: 1373
Day 90: 1844
Day 100: 2208

After executing this process a total of 100 times, there would be 2208 black tiles facing up.

How many tiles will be black after 100 days?

Input:
swsenenwneswnewseswwseswnwsweeswnw
esweeeeneeeneeeweeeenenenee
ewewsewswnewnwnewwwwsew
nwnwnwnwnenwwnwsenwnwnwnwnwnwnw
nwswseswneswseswswneswswseneseswswsenwswse
swswswneswswswswwneseswwswsw
newnwwnwnenenenenwsweenenwnenwnenese
senwsewseneneseneenenwwneneeswnewsw
eeeeneweeeseeeeeenewneswe
wnwswwewwwsewnwnwwnwnwwwnwnwnww
nenwnwnwnesenwwnwnwwneswnwnenesweneenwnw
nwwnwwwwenwwswnwwwwwewsesew
swnwswwswswewswseswnwne
wswnewswnwwwwenewsewwwwneswe
nwnwnenenewneneneneneenenesenwneswneswse
nwewsenwnwneseswwwwwwswwswwwwe
nesenwseneswseswnwneseseseseseswnwse
wnesweseswenwnenwnweseeseseeswnwse
swswnenenenenewneneeeneneeneneenenene
seseseseeweseeesee
wwwwwwwwwnewnwwwswww
sesenwesenwseeseseseewswneseseesesw
wnewwwsewnwwnwnwewnwswnwwwwnwe
nwnwnenwnwneneenewswnwnenwswnwnesenwsw
eeswwneeneneeneeneeeeesw
seneenesewneeneswwnenenweeenenewwe
seswseswsenwswswseswswswswenwswsesesw
nwnwnenwnenwnenwnwnwnenwswnenwwwnwese
wnwwwwwnwwwnwwnwnwseneenwnwnww
ewnwnwnwnwnwnenwnwnwnenenwsenenwnwnene
neneweeeeneeneesweseswswneseswse
seswseeneswswswseseewsewnwswswwnwne
swwneneneweseswnenwneeneneeeeeeee
swwwwwwwwwwwwswswwswswnesew
eewenwseeeeeweeeeneeese
neneneneneeneswneeenee
sewnwnwwswnwseenwwnenenwwnw
swsweswswswswsewseneseswswsesweswnwsw
nenewewwwwwwwwwnewwswsesewww
enwsweneseseeesese
swneseseseneeseesenwwseneswseseseseew
nwswswneeeewneseenwnwnesewwswnwesw
nenenwneenwneneneneneneneneneswenewne
nwneneseeenwnwnwneneneswneswwnenwnwnenw
neseenenwneeneneneeeeneene
sesesewseseseswneseesesesesenewseswsese
senwnewseneneeeneeeeeenesenwnene
eeweneneeenweeeseesweeeee
esesenwswnwseewseswseeeseswenenwse
neeneeeseswseeesweneeseeesweee
swweswnwneswswwswswneswswswswswsw
wwswwwnwnwnenewnwenwswnwsesenwnwe
neseneenwneeeeeneneeeewneeene
swsenwsesesweswsewswswswsenwneseswsesw
wewwwwwnwwwwwnwwwnw
swseweeenwswneseseesenese
senwsesesesesesesewseesewe
sewnwnwnweswnwnwsenwnwnwnwsenwnwnwnwnw
swswswswswswswswswseswswswswswswwswnesw
wswnwnwsewwnwewwewwnesewwne
enenenwnewnenwnenenwwneswneseswnenwsenwnw
seseseswswseswsewnwsewswswseeseeswse
nwseswnweswnwneseweswsesweseseswne
seseswwnwswneneseneneseeseesenwswnwww
wswswwwwswwneswseswnwswswsew
senwnwwnwnwesewswnewswwsenwwnwnwwnw
swsewneswswswswwswswwswswswsw
eneseeeswneswneeseesenwewsenwewnwnw
neneneeeneweneneeswe
neeeseeenwnweewswnewneseneenenee
senewesesenweseseeesewsesesesesesee
eseeeseseseenwseeneseseeewse
nwnwseseenwenwnenwwswnwnwnwwnwnwnwnwnw
senewweseeenwsesesenesewsesesesee
enenenwswnenewswenwnwneenwwnwswnenene
eswseseneswsenwswseseseswsesesewsenwsesee
wnwneswneseneneneneeneneswenenenenewne
seswneewsenesesewnwwswnesewswesenwne
eswwesenwwenwnwnweseseeeeeese
neeneswneeswnenesenwnwneswnenwneneswsene
swswneseseswswswswwewnwsenwesweneswnwe
nwenwwwnwnwnenwnenwnwnwnwnwsweneswe
seseneneeseseeeeswsenwwwesesenwe
sweswseswwnwsesesewseseseseswseneswnene
seswseseseseseswwseswsenesesesesesesese
sesesenwswswseswswsw
senwseeeeseseeseseseenwewswesee
wwsenwewwnewwswwwwwswwwwwne
nwnwnwneswnwnwnwsenwwwnwwnwnwnwenwse
swwwswswswwwsewnenwswwswwswseww
enweenesesesenewnwnwwswswswseseese
swnenenenenenenenwnenesenewnenwnenenwnene
enenesweeeeseneeneeeneeneeew
wnweseeswnwwenwnenwnwnwwenwnwsenwwnw
neswswswseswswswwswnesw
neswseeneseswsewseseswseseswswwswswse
seeneswsesenweeeseeseswsewenesee
wewewwnenesewsenwwnenwnwseswsww
nwnwsesewnwseeeswnwnwseewseenw
nwwwwwnwwnwnwwwwnwsenwwwwsew
eenwneseeeneeneenenwseeeeeee
nwenwnwnenwswnwneesenwwwnwnwnwsenwnw
swswswswseswswswswwseswswswswswswswswne
swwwwwwwwwwnwwewwwnwwww
esweeeeeeneeenwnwenesw
eeenweeeseese
wwwnewwsewewwwwwwwwww
seseseeseseesesenwesewseeseseseswnesese
senwnwwneswwswwnenwwwewnwnwwnww
swnwsesewneenwenwseenwneeseeseewsw
eneeneneneneneneswsewswsenenenwnenenenw
wneesweseswswwsewswnweswswewswswse
neseneneeewneneenewnenenenenenenenene
wswnesewwsenewswswswswneswswswsweesw
swswsesenwseswsewseswneseseseswsesw
seswwswwwseswswswswswweswneswswnewsww
neneesenewewnenwneneneswnwweswswnese
swswswwwswswswswswwneswswwwswseww
neenenenenenenenenenwsewneneneneswnenene
eneeeeseenenwwesenesweeseeesw
swswswswswswwswnwswswwswseswswswsw
eneseseseswsesesewsesesesesenwseseswenese
nenesweenenenewneneeeneswnweenene
eneswsenwseenwenwene
swsewnenwenwwwwseseseswnwwne
seeseseseseseseswsewsesesenwseseseewse
swenewswnenwswsweswneswswswse
wnwwnwwwswwwwnwsenenwnwwwnwwww
eswswwswswnwswswwwswswsewsweeswww
nwwnwenwnwnwwnwsewnwwwnwnenwnwnwnwnw
seswwseeswswseenwneseswnewwswseswsw
enewwwswesewwnenwseswseweenwnwnew
swseswseesenwseseseseseseseswseswwsee
neneneneneneneneneneneenwnewneswe
wnwswswnewnwnwwwsenewweeswnwnenww
swenweenweeneswneeeeneneee
nesweswswseeswswsenwswsewwseneneswse
nwneswewnwnenwnwnenesenenenwnwnwneswnene
wenwswnwnwnwnwnenwnwnwenenwnwnwnwnwnwnwne
seseneesewnwnwneenwseeswswsesewnese
swnewswnwswnwnwnwwenwnwseewnwnenenww
seesesewenwneeeenwnesenenwsweseswnwsw
swnenenwnwnwnenenwnwnwnwswnenenenenwnwse
ewewnwwswesewsweswnweswswnwnwwnesw
neseneewwswwwwnwwwewwwwwsww
enwnwnwwswnesewwnwnwsewswnw
sewwwwwsweswnwswswnwwwwewsesw
neneneseweneenenwesewnenenenenenese
eeeenweeeeswseewnweewneswnew
wnwnenwnweneneswnenwenenenwnesenwne
eseseseseswsenwseseswsesesesesesesesese
eseeseeseeesesenwwseene
nenwnwnwnewnwnesenwnwsenwnwneneseesw
ewwnwnewnwwnwnwnwnwnwswswswwwnwenw
senwwneeneeeneneneenewneswenwnene
nwnenwnenwewenwnenewseeeenwswswwswe
wwewwwwnwwnwwwnw
eeeeeeseseeeeeeeeeew
wnwneeeseeneeneeneeneweseeenesw
nwwnwsweswwwseww
swswwswneswseswswswseswswseswsesweswwsw
newneneeneseenenenenenenenenenenewwne
nesewwwwswwnwwwnwwwneewwwsee
enwseseseseeseseseeeseesese
seeseseseseseeseseswneseswseseesesesenwse
nwseeseeesesewswseswwsenwseswneseesw
wneseenwnenwenwneeneneneneneeseesee
nwneesenwsweeneneneeseeneesenwww
nenenwswnwswnwnwnwnwnwnenwnenenwnenwnwnwnw
nwnwnwenwnwnwnwnwnwnwnwnewnenwnwswnwnw
wwwwnwwnwwnwewnwnwnwwnwwwswnw
neewneenewseneneeneneneneneneneene
neneneneneneneneneneswnenwnenenwnesenwnene
eeeeeeeseeeeeeeneeweee
ewwsweswsweseswswswswnwnwewnwnesw
weswswseseenweneesenenwnwnwneswswse
nwswswseswwswswswswwwswsww
seswseswwseseswswswneseswseswswswneseswswsw
eneeneewnenwneeseeneneeneneneseeee
eenwnweswenwenenwswswneeeewese
nenenenesweneswneswnenwne
enweseeseeneesweswnwsee
swnesesenenwwswnwsesenweneenenweswwew
nenwnwnwnwnwnwnwnwnwwnwnesenwswnwenwnw
nwwnenwnwnwswnwswsenwnwenwnwswnwenwnwe
swweeenwneswnwnwwswsewwswswseneew
esewnwseenwseseenweseseseesesesenwse
enweseeeeseseeneeseeeseweee
eeseeeeseseseeeewneeeseeeswe
swswwwnewswwswwswwswwswsw
eewseeenwsweenweneesewnweew
wswswsenweswnwsenwnwswswwneseweneww
nenewswnenesenenenenenwnwnenewneenenene
nwnwnwnwnwenenwnwnwwnwnwnw
sweweesweseeeswnweenwseneeenwee
ewesesenweseenwseseseeseneseeeswe
eneenenewnenenenenesenenene
eeeesesweeewseseeeneesewenesew
wswwwswswswwswswnwsweswswwswnewseswsw
swswswseswswswswswswswswswseseseswswenw
neenenwenenweseweneenesenwswneswnwswne
seswwwwwwwwwwwwwwwwnesenewne
swswswswswsweswswseswswswswswswseenwnwswsw
eneeeseeseseeseeseewseseseseee
swneswswwnewewswswsewwswwswnewse
wnwnwwwswwnwwewwwwwseewnewsw
senweeneeseeewenwsew
nwnwnwnwseswnwnwnwnwenwnwenwnwnwnwwwwsw
eeseneeeswewenwneeseeeeeee
wnwenwwnwnwnwnwe
wswwswswwwwwwsewswwneswswswsww
nwnwnwnwnenwnwnenenesw
nenewwnwnwswnwesenwneseneenenwneewne
nwneneswnwnenenwnwwsenwnenwnenenwnenenw
swwwwswswnenwsweswenwswseneswwswnese
eeeeewneweeeeswsewesweenwene
seswsewnwwnenwwsesenesewnwweeswswnwse
senweeseseswnewseseswsenesese
nwsenwnwnwnwnwnwenwnwnwnwwnwwwnwww
wseseseseseswswswswneswse
nwneneswnenenenenwnenwne
esenwseeswseseseseseseswsesenesenwswse
seswswswswnenwswenewenwneswseswwswswswse
sweswwwnwswwswwnweswww
swwswsewswwswwswwswswwnewneww
swseneswwnwweswswseswseeswwneswswswew
eseseseesesesenweeseseseweeseswese
swswnwnwnweswswswswswswswee
swseneswsesenesweewwseneswseswswnwnw
sewseeseseseeeseseesesesenese
seswnesesesesesesewseseseswsesesesesese
seseseseswseswseseseseswsesewseswsenese
enwnenwenwnenwnwswsenwnwswne
enenewnenwneneneneneneneewnenenenene
nwwsweneswwswwsewswwswwswwenwswsw
swsewseseneswswswseseswseeswseswsesese
neneseewneseneneneeneneenwnenewe
wwnwwwewswewwwwwwwswwswww
eeswneneneneneneneeneneneswswnenenwnw
nwnwnenenwnwsenwnwnenenwnenw
eeseseseesenwseseeesesesewseseseseesw
wewwwswwwswwwwwwswnwsewwnw
nwwnwnwwwnwnwewnwnwwnwswswnwwnwe
nenwnenwnwnenwnwnwswnwnwwnwnesenwnweswnenw
wwneweenenwswnesesewnewswswwwse
seswswsesesesewswseseseseseseneseswsese
swswseswseseswseswseneeswswseswsesewse
eneneenweeewnwesenenwseswseewwe
swenenweeeneeeneewseeswenwee
enesenewwwswseseswsese
eswneseweneneeneneeenweneneeee
eseseeseseeweswswenwneeeeneewne
wnwwneenwwwwsenwwwwnwwwwww
nwnweseenweewneswesweeeeeneew
swswswwnewswwswseneswwwswwwswsww
nenwswnwnwnwenwnwnwnenenwnwnenwnwnwnene
nwnwwwwnwnwwnwnewnwnwnwnwsenwwww
wswnwwseswwswwswwnwwewswsewswew
wneeweneneneseneswnewnenesesenenwnee
sesesesenwseswseswsesesesenwsewseneesese
swseswsenwsweseswsewswsweswse
nesesesweewwsweswseseswnwnwnwswsee
nenwnenwnwnenenwneswseseenw
sesenwswsenenwseswnew
sewseseseseeseseseseseesesesesenwseseswse
sewwenwnwnwwnenwnewswnwwwwnwwwnww
nwnenesewnwnwnwnwnwnenwsenwnwnwnwnwnwnwnw
nenwseneswnweseseswneweswnesenweewne
sesenwseseseewseseewseneseesesesesw
wwnwwnwnwwseswwnwenwnwwwnwnwewww
seseswsenwseswswseswwneseswsese
sweeswnenenenwneneenweeeneeeeene
seseseseswneswseswseswsenwseseseswsese
enenenenenenwnwnwnwnenesenenwnwneswnwnene
swwsweswwswwwswswswsw
wwswwnwsewswwnenwwwwwnwenwnww
eenwnwseseseseeeeeeeeeweeswswe
nwsenwnwnwnwnwnwnwnwnenwnwnenwwne
swwswswsweswswswswwesweseswswswswsww
seseesenwseweseeeseseewseseswsese
nwseeeesweeeeeseeweeenweeee
seeswneseseseseseswsesesesesesesesenw
eswenewsenwwneeeneeneeneenenee
wswenwnwenwwnenwwswesewseneweewsw
sweswenwswnwswswnwnwwnweenenwnwe
nwenweeswswwww
nwneneneswnwnenenenwnwneneswnwnwnesenenene
swseeesweeewsesenwweseenweenee
nenwneswneswneneenesenesewnwnesenewnenene
sewsesesesesesesenwseseeseneseewwsese
seswswswswwswwneswwswswswswwswwwnw
eeesenweeewseweeeswweneswnenw
eeeeeneeeweseeweeeeeeee
seswnesesewwseseeenesenewseswwnesw
eeeeeeseeewseeeeeneseeee
nwwwnwenwwswwnwenwwsenesenwwnw
wwwwwwwwwsenwwnwwnwwnwwwsew
seswswswseswseseswswswseswnwesenwseswsesw
eneeneeneneeeeweneneneseweneee
swwwwewswnwswewnwswwswwswwwswsw
eswneseeneneewneswseeweeeneenwnenw
swswnwwwseswnwnesewseswwnwswsenwswe
swswswwsewnwwwewswwneswsewwwnw
nwnwwnwnwwnwnwsenwnwnwnwnwnwseenwnwnwnw
seseseewsesesesesesenenewsesesesesesesese
nesenenenenenwnwwnwnenwnenenewneneneene
wesesesenweseseseswseseswsenwswsesewse
eseeswseeeswenweeseseeeneeee
neswwnwwwwnwwwewwnwswwenwww
nwswnwnenwnwnwnwnwnwnweswne
nwwwsenwnwnwwnwsenenwswnenwwnwnewwse
seenwseeenwweseeeweesweeeese
swswsweswswswneswswseswswwwswswswswneswne
ewwwswwwwswwwwnwwwwwswww
seswsenwseseseswsesesese
neneeswewnenwswneneseswenwseewenene
swnwnwenenenwnwnwnwseenwnwsenenwnwwnw
nwneswneneneneneneseneneswnenenwnenw
nwnwnwnwnwnwsewnwnwseenwnwnwnenwnwswnww
seswseseswseseswneswneswswseswswseswswsese
wnwnwnwnwnwnwnwnenwnwnwnwnwnwsesenwnwnwnw
seseseeesesewsenenwseweeseesesee
nwnenwwweseswnwwwnewwswseneseww
swnwseseseesesesesesewseneseseseseswsesw
seseseseesewneseseseneseeeseseeswsese
nwnwwnwnenwewwnwneseswwwwnwww
esesesesewseseseseseeseesenwsesesese
eswswnwswswneswswswseweseseswswswswne
swneenenenenenwnenenenenenwnenwnesenene
nwwswnwswswnwnenweeenenesenwwsenesw
eeeeeeeeeenweeeeenwswswee
nwnenenenwswnenenwnenenenw
nwwwnwnwenwnwnwsenwwwnwwnwwnwnwnwnw
ewneweseeseseseseese
nwnenwnwnwnewsesenwnw
nenenwnewnwnwnenwsenwswneenese
wnwwwwwnwwwwnewsewwwnwwswwnenw
enweseeeeseseeeee
wesweseneswsewnewwneewenenenwnwse
eseeswseeseeseseseseeseenweeee
wnwnweweswsesenweseseseseseswewsese
eeeneeseeenwseeeneenwseweeee
esenwseswseswswseswseseseswseseseswswse
wwseswnewwwswewwwswnewwwew
eeeneeeeeeenweeseenweeswee
sesenwneewswweneswnewsenenwenwswnw
nwnwneseenenewewnenewswneesenenene
swweswswwswswwnwwwswswwwswnwwesww
swnenenenwneneenwnwnwnenesweswnwnenenwnw
nenwnwwewwnwnwnwsewswneenwswswnwnw
nwwwsewwnwnewnesewwwwnwnwnwnww
wswwnwsenwswnweswweswswwwwenenw
neswswswneseswwswwwsewswwswnwnwneesw
newewwswwswwewwwwwwwwseswne
neenenweesweneneeneneneneneneneenese
eseseseeswseweenweseseeesesesesee
swseswseswswswseswseswswswnwsw
nenenenenenesewneewsenenenenenenenenene
eeswneseenweseeeeeeseewsewseee
nwewswswwswswwswswwswswswswswswnwse
nwnwnwnwnwnenwnwnwnenwswnwnwnw
eeeseeeeeeweenweseseseeese
swswwwswnewsewswwwnwswswsenwswsesw
seseswsesewsenesenesenw
seseswswseneswswswneswseswswnwsesesesesese
nwnwwnwnwnwenwnwnwnwnwnwnwnwnwnwnwnw
neeneseeneneneneeneenewneneneswnenew
nwsenwnwnwnwwnwsenwnwnwnwnwenwnwnw
swswswnwswswswswneswneswswswswewseswnwsw
seswneswswswswswswswseswswswswswswenwsw
wwwwnewnewnewswwswwswwwseswww
swenweswseswseneseswswsesewsese
ewswseswwsewsweswwswwswsenenenesene
swwnwnwnwseneseenenenwneswwwwwseswse
nesweneneeseneneneneneenenenenenwnwnenee
enwnwwwnwnwnwnwnwnwnwnenwsenwnwwwnwnw
wwwwwswwwwwnwwwewwnew
nenenesenenwnwswenwnwnenenwneneneneeswne
eeneeneneesweeneneneneeeeewene
eeseseenwnwsesesenwesenwesesesewese
neeeeswswneeeeeeenweeene
seseesewnesewseseeseseswseneseswnwsene
sesesewseeeneeseeseseseseeseeese
wswwnwwnewsewnwnwnwesewwnwnesene
eseeneenenewnenenwseesenwnwnesewnene
eseeneeswnwneesesewwneswewwneesw
neneswseneenwnenenenewneneneneneneseneene
sesesweseswsesesewseswsesewsesweswse
sewsesesesesewseseseneseeseneesesese
swwwenwwnwswnwnwneswwwnenwsewnwww
swwswswseseswswnwseswswswswsweseswsesw
senwenwnewweneneswswnwswwsenwenwenwnw
nenwnenenenenenenenenwneneneneneneenwwsw
wwnwwsewsewswnewsenwneesw
nenwnwseswnwnwenwesewnwneeswswnwnwswnw
nenwswnenenenenweneseneewseeneewswene
esenwwsenenenewnwnwswnwnwnwwwwnwnwnww
sesenweeeseseeeseseeseeeseswese
neneneneneenenenewsenenenenenenenenene
eeeseeeesweneneneeeeeenenwe
eswwwwnwneewwswwnwwneswwseswswwsw
wseseeeesesesesenweeneseseseseeee
esesesenweeeeeweeeswenwne
wwwwswneenwsww
seseswseneswswswseswseswswsewswswswseese
weseswseeeneseseewnweseesesesee
swswswswswswswswneswswsw
swwswswswswswswswwswswenwwswww
nweneneneeeneneeneeseneneneneene
swwswwwneneswswwswwswwseswnewswsw
eeeewenwweeeesweeeee
wnwseeewswswwwswsewwswnewnenew
ewseneeswswneswenweswnwwwwneswwe
eswseswnenwswseswwseseesesesenesesesw
senweeseseesesesesesw
nwsesesewsewnweweseseeseswsesesw
sewwwseseswswneenewenenwsenwseww
nwnenwnwneswswsenweswneneneenenenenene
eswnweeeeneeseneeeswenweneenw
wsenwnwwnwnwnwnwnwnwnwnwwnw
nwnwenesewenwnwnwwwnwwnwnwwnwew
nwsenwnenwnesenwnwnwnww
wnewneswnwwsesenwwweweseneneww
swseseseneeseswsewse
nenwsenwnwsenenwwnwwnwnenwnesenwnwnwnw
neswswswswnweewnenwswswswswswswseswswne
nwseseseseseeeseseseeeeseeeswsese
wnwnwnwwwenwsewnwnwwnwnwwnwnwnenw
wwwwwnwwewnwww
nwswswswswswswswswswswswswswneswseswneswsw
nenesweneneeneneneneneeneneenenee
swswswswswswwseswwswwswsweswswswnwwsw
nwwewswwnwwwwnewwnw
eeewenweeeseneeeseeeeeeeswe
swswenweswseseswneswswswsewsesesenenww
eeseeeeeeneswseseseeeweeeee
eeeseseeeeeeeeseenwenenweswesw
neswseswswseseseswsesw
sesenwwseneesewseneseseewneswswneswne
senenwswswwwsewwsenenwwenwewnew
neeseeweeeneeenenweeseeeee
nwswwswswswseswwswswswnewswswwswsesw
swneeneneeneswnwsesesesewnwesewsesesw
swswenwneneewneswwswswesesewsesw
nwnwsenenwnenwsenwnwnenwneneeswwnenewnwnw
swsenenewswswsewwnewwwnwsewswwsw
swenenenwseseneweenene
wswwswneswsewswswswswswswsw
wsenwsenwwwsewwnwswwnenwwnwnwnwew
nesweweeswwseseseseeeeneenwew
wseseneswnwswseseswseswswsenwwswswswesw
wwnwnwnewswenweswenwnwenwnwswnww
seswneswswseswwseswswseneswswnweswswswsesw
swwwnewswwswswwwwwsww
enwswswneeneneeneneneeneee
swswwswswswswswswswneswswswswswsw
sweseneswwseeeneeenwnenweswnenwne
eseeeeweneeseesewseswnewe
enwesweseenwseseeeesweeeenese
eswsweesenwenweeeeseeeeeenwee
eeeesenweseeeeeesweeseeee
wwseenenwnwwnwnwwwwnwswsenwwnwenw
sesenwseseseeseseswseswseswseswnwsenwsese
eeeeneeneswnenwee
seswneseswseswnwswswesesewseswswswswsenwse
nwnwwnwwenwnwnwnw
eenenenwneneeswneeneneseneneenenene
seeseseseswseseesesene
seseseswseseswnwswswwseswsweseswsesesenw
nenenenenenesenenwnenenenenenesenenenewnenw
nwenwnenenwnwenwswnwnwnwnwnwnwneneswsw
nwneswswnenenwnwnenwnenwnenwnwswnenwnwnw
eneneneeeeneeeweneeneenene
enenenenwnenenesenenenenewneenenenene
seseseseseswsesesesesesesesesesewnenesese
nwnwenwwnwenwwwenwnwnwnwwwnwwsw
eeseeesweeeseeeseeeeewnwenee
sweneneeneeeeneeewneneeneneenw
nenewnwneseseneneenwwswneneenenwwse
nwswwwwneswsewwswwneweweswnwsew
swswnwswswsweswsesw
nwwnwnwnenwnwnwswnwnwwnwnwnwnwwnwwew
swwwwwswswwwwneswwswsewwwwsw
seswsenenenewewnenenwnenewenenenenesee
wwnwwewnwnwenwwnwnwwnwswwwsww
wswswswswswswneswswseswswswswswswwswsw
sweseeeeeeeeenwneneeeenweee
eneneneeneneneswnenenenewenenenenwnesw
swseeesewsenwswsesesw
eeneneenenwneeneweswsweneneeene
swseseseseseseseseseeeenwswseesesesenese
eneweeneeneneseenenenewseeeneenew
eeswswseenenwnewe
ewenwwsesesesenwnwwesenenwnesesew
wwwwnwwwwnwenwwwnwwwwsenww
swnwsesewnenwsesesesene
sewnenenenwneenewsenwnenewneeesesw
swswswswswswswswseswnwswsww
seswswsenwwswseswnesweseseswswseseesenwse
eswswwswswnwseswswswswswsweswswswswsw
nwnweswwnesenwnwnwnweswnwnwnw
eswnewwswesewwwnwewwesenwnwwsww
eswnwneneneeeeswnesewnesweeeee
ewswwnwnwnwwwnwnw
eeneneeeneneneeenweneesweswnese
seswseseseswseneseseswweseseswswswseswsw
nwnwnwnwnenwwwenwenwnwnwesenwwnwnw
sewwnwwenwswnwnww
wseneseswseseswswenwseseswswswswswwse
seseeneseweneneswnwseenwswnenenenwnene
nenewswnwseseneeneneneseneneneewnenw
eneeeneeneeeeneeneweese
wwewwswwwwwwswswwww
seswseseseseseswseseneseswnesesesesese
neneswseswnwwseswswswwswswsweswnwwswe
newwswswswswwswswneeswnewswsewese
eseeeseeseeeeeseewe
enenewnenesesenewnwswsenesenenwneneneesw
neeseeeeesesweseseseeseseenweese
nweswswswswswseeneswwsewswswswswswe
wwwwwwsenwwwnwwenewwwnwwsww
swsesewnwswswswneweswswseeswswneswsew
swseswswswswswswswnesweeswswswsenwswswnw
eeeneseeneweneeeweeeneeneenee
nwnwnwnwnwenwnwnwnwswnwenwnwnwnewnwswswnw
nwwnenwwenwnwwwsenwnwnwswnwwneww
senewswswnenenenwneeneneneneneeenenenene
eeseseeseesesenweseeseeseewse
neswnesenenwswnenwswnenwswnwneswswnewseee
senwnwnenenwnwnwnenenwnwnenwnwnenene
wwnwwwwwwwwsenewnwww
nwnwnwnwwnwnenwnenwnwneneenwswenwnwse
wwwwnwsewswswwswenwswwswswwwww
nwwwwnwwswenwwwnwenwnwnwnwswnww
nenwesenwewneneseeseenwenewnenee

use crate::common::AdventOfCodeDay;

use std::collections::HashMap;
use std::cmp;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;

#[derive(Debug, PartialEq, Clone, EnumIter)]
enum HexDir {
    EAST,
    SOUTHEAST,
    SOUTHWEST,
    WEST,
    NORTHWEST,
    NORTHEAST,
}

#[derive(Debug)]
pub struct Day24 {
    input: Vec<Vec<HexDir>>,
}

impl Day24 {
    pub fn new() -> Self {
        let input_bytes = include_bytes!("../res/24_input.txt");
        let input_str = String::from_utf8_lossy(input_bytes);
        
        let data = input_str
                        .lines()
                        .map(|p| String::from(p))
                        .map(|p| Self::parse_line(p))
                        .collect::<Vec<_>>();

        Self {
            input: data
        }
    }

    fn parse_line(line: String) -> Vec<HexDir> {
        let mut r = Vec::new();

        let mut skip = false;
        for u in 0..line.len() {
            if skip { skip = false; continue; }

            let chr = line.chars().nth(u+0).unwrap();
            let nxt = line.chars().nth(u+1).unwrap_or(' ');

            r.push(match (chr,nxt) {
                ('e', _)   => { skip=false; HexDir::EAST },
                ('s', 'e') => { skip=true;  HexDir::SOUTHEAST },
                ('s', 'w') => { skip=true;  HexDir::SOUTHWEST },
                ('w', _)   => { skip=false; HexDir::WEST },
                ('n', 'w') => { skip=true;  HexDir::NORTHWEST },
                ('n', 'e') => { skip=true;  HexDir::NORTHEAST },

                _ => panic!(),
            });
        }

        return r;
    }
}

#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)]
struct HexCoordOddR {
    q: i32,
    r: i32,
}

impl HexCoordOddR {
    pub fn zero() -> Self {
        return Self {
            q: 0,
            r: 0,
        }
    }

    pub fn move_by(&self, d: &HexDir) -> Self {
        return match d {
            HexDir::EAST      => Self{ q: self.q+1,                   r: self.r   },
            HexDir::SOUTHEAST => Self{ q: self.q+realmod(self.r,2),   r: self.r+1 },
            HexDir::SOUTHWEST => Self{ q: self.q+realmod(self.r,2)-1, r: self.r+1 },
            HexDir::WEST      => Self{ q: self.q-1,                   r: self.r   },
            HexDir::NORTHWEST => Self{ q: self.q+realmod(self.r,2)-1, r: self.r-1 },
            HexDir::NORTHEAST => Self{ q: self.q+realmod(self.r,2),   r: self.r-1 },
        }
    }
}

fn realmod(v: i32, m: i32) -> i32 {
    return ((v % m) + m) % m
}

#[derive(Clone)]
struct HexGrid {
    data: HashMap<HexCoordOddR, bool>,
    min_r: i32,
    min_q: i32,
    max_r: i32,
    max_q: i32,
}

impl HexGrid {
    pub fn new() -> Self {
        return Self {
            data: HashMap::new(),
            min_r: 0,
            min_q: 0,
            max_r: 1,
            max_q: 1,
        }
    }

    fn update_coords(&mut self, c: HexCoordOddR) {
        self.min_r = cmp::min(self.min_r, c.r);
        self.max_r = cmp::max(self.max_r, c.r+1);
        self.min_q = cmp::min(self.min_q, c.q);
        self.max_q = cmp::max(self.max_q, c.q+1);
    }

    fn get(&self, c: HexCoordOddR) -> bool {
        return *self.data.get(&c).unwrap_or(&false);
    }

    fn set(&mut self, c: HexCoordOddR, v: bool) {
        self.update_coords(c);
        self.data.insert(c, v);
    }

    fn flip(&mut self, c: HexCoordOddR) {
        self.update_coords(c);
        self.data.insert(c, !*self.data.get(&c).unwrap_or(&false));
    }

    fn neighbours(&self, c: HexCoordOddR) -> usize {
        return HexDir::iter().filter(|d| self.get(c.move_by(d))).count();
    }

    fn step_automata(self) -> Self {
        let mut a = Self {
            data: HashMap::with_capacity(self.data.len()),
            min_r: 0,
            min_q: 0,
            max_r: 1,
            max_q: 1,
        };

        for r in (self.min_r-2)..(self.max_r+3) {
            for q in (self.min_q-2)..(self.max_q+3) {
                let coord = HexCoordOddR{r:r, q:q};
                let old = self.get(coord);
                let nc = self.neighbours(coord);

                if old && (nc == 0 || nc > 2) {
                    a.set(coord, false);
                } else if !old && (nc == 2) {
                    a.set(coord, true);
                } else {
                    a.set(coord, old);
                }
            }
        }

        return a;
    }
}

impl AdventOfCodeDay for Day24 {

    fn task_1(&self) -> String {

        let mut grid = HexGrid::new();

        for path in &self.input {
            
            let mut coord = HexCoordOddR::zero();
            for step in path { 
                let coord2 = coord.move_by(step); 
                verboseln!("  Move [{},{}] --[{:?}]--> [{},{}]", coord.q, coord.r, step, coord2.q, coord2.r);
                coord = coord2;
            }

            let state = !grid.get(coord);

            verboseln!("Set [{},{}] -> {}", coord.q, coord.r, state);

            grid.set(coord, state);
        }

        return grid.data.iter().filter(|(_, v)| **v).count().to_string();
    }

    fn task_2(&self) -> String  {
        let mut grid = HexGrid::new();

        for path in &self.input {
            grid.flip(path.iter().fold(HexCoordOddR::zero(), |a,b|a.move_by(b)))
        }

        for _ in 0..100 {
            verboseln!("Black: {} (Size: {}..{} | {}..{})", grid.data.iter().filter(|(_, v)| **v).count(), grid.min_r, grid.max_r, grid.min_q, grid.max_q);
            grid = grid.step_automata();
        }

        return grid.data.iter().filter(|(_, v)| **v).count().to_string();
    }
}
Result Part 1: 459
Result Part 2: 4150


made with vanilla PHP and MySQL, no frameworks, no bootstrap, no unnecessary* javascript