mebeim / aoc

πŸŽ„ My solutions and walkthroughs for Advent of Code and more related stuff.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

optimize iterations in day24 part 2

edelans opened this issue Β· comments

hello @mebeim πŸ‘‹ ,

In today's puzzle part2, I noticed that for the rule

Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black.

you iterate over much more tiles than you could :

def bounds(grid):

you could restrict your iteration over the neighbors of the neighbors of your black tiles, cf my implem here :

https://github.com/edelans/aoc2020/blob/933ae61307ad48b38b3aacdbc1e211d4f33b1937/day24.py#L73,L79

thanks again for your clean walkthrough, and buon Natale !

You make a great point, indeed I do not need to check all those tiles since most of them will probably be surrounded by white tiles. That's something I was initially thinking about, but I didn't come up with a clean implementation right away and I forgot about it. I guess this also applies to day 17. Thank you very much! I'll optimize that for sure soon.

Buon Natale anche a te! πŸŽ„

Done @edelans! This is quite faster and also a lot smoother. I've also updated the walkthrough. Thanks again! πŸ˜„

def all_neighbors(grid):
deltas = ((1, 0), (1, 1), (0, 1), (-1, 0), (-1, -1), (0, -1))
return set((x + dx, y + dy) for x, y in grid for dx, dy in deltas)
def evolve(grid):
new = set()
for p in all_neighbors(grid):
n = black_adjacent(grid, *p)
if n == 2 or (n == 1 and p in grid):
new.add(p)
return new

@mebeim sweet !

To be honest at first I thought your new version was overlooking tiles already in the grid by only iterating over the neighbors. So I wondered if there would be a case where this could go wrong :

  1. a tile could be in the grid at the start of an iteration
  2. but not in the neighbors you iterate over
  3. and which should stay in the grid at the end of an iteration

1 + 2 is equivalent to having a black tile with zero neighbor, the rules states they should be flipped to white, so fortunately, it's incompatible with 3. So in the end, it's ok to iterate only over neighbors.

But then you might want to change the following formulation in your walkthrough :

For this reason, when evolving the grid, we need to also check all tiles surrounding the ones we already have, even if they are not in our grid set.

as after reading this (especially the "also"), you expect to see code iterating over grid + neighbors.

you could update it for something like :

For this reason, when evolving the grid, we need to check grid tiles and all their surrounding tiles, even if they are not in our grid set. And actually, all the grid tiles will be included in the surrounding tiles except the tiles that have 0 surrounding black tile. Those black tiles are flipped to white, so in the end we can restrict our iteration on the surrounding tiles alone.

@edelans nice catch. Indeed, not including the tile itself was an oversight, but as you explained it ends up working anyway because of the evolution rules. I have updated the relevant parts of the walkthrough in 7a60dd4 to reflect this, opting for a little bit longer (but hopefully clearer) explanation.