Day 11 (ugly)
This commit is contained in:
parent
cbedbccd57
commit
1b09653fcc
73
2020/day11.py
Normal file
73
2020/day11.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
import sys
|
||||
|
||||
from grid import Grid, near8
|
||||
|
||||
|
||||
def main():
|
||||
lines = [line.rstrip() for line in sys.stdin]
|
||||
|
||||
# Part 1
|
||||
g = Grid(value_factory=lambda: ".", lines=lines)
|
||||
while update(g):
|
||||
pass
|
||||
print("Occupied:", sum(v == "#" for _, _, v in g.values_gen()))
|
||||
|
||||
# Part 2
|
||||
g = Grid(value_factory=lambda: ".", lines=lines)
|
||||
while update2(g):
|
||||
pass
|
||||
print("Occupied part 2:", sum(v == "#" for _, _, v in g.values_gen()))
|
||||
|
||||
|
||||
def update(g):
|
||||
changes = {}
|
||||
for x, y, v in g.values_gen():
|
||||
if v == ".":
|
||||
continue
|
||||
p = (x, y)
|
||||
n = list(g.near_objects(p, near_f=near8).values())
|
||||
if v == "L" and n.count("#") == 0:
|
||||
changes[p] = "#"
|
||||
elif v == "#" and n.count("#") >= 4:
|
||||
changes[p] = "L"
|
||||
for (x, y), v in changes.items():
|
||||
g.setv(x, y, v)
|
||||
return bool(changes)
|
||||
|
||||
|
||||
RAYS_OFS = [
|
||||
(-1, -1), ( 0, -1), ( 1, -1),
|
||||
(-1, 0), ( 1, 0),
|
||||
(-1, 1), ( 0, 1), ( 1, 1),
|
||||
]
|
||||
|
||||
|
||||
def update2(g):
|
||||
changes = {}
|
||||
for x, y, v in g.values_gen():
|
||||
if v == ".":
|
||||
continue
|
||||
occ = 0
|
||||
for ox, oy in RAYS_OFS:
|
||||
n = 1
|
||||
while True:
|
||||
qx, qy = x + ox * n, y + oy * n
|
||||
if not g.hasv(qx, qy):
|
||||
break
|
||||
if (rv := g.getv(qx, qy)) == "#":
|
||||
occ += 1
|
||||
break
|
||||
elif rv == "L":
|
||||
break
|
||||
n += 1
|
||||
if v == "L" and occ == 0:
|
||||
changes[(x, y)] = "#"
|
||||
elif v == "#" and occ >= 5:
|
||||
changes[(x, y)] = "L"
|
||||
for (x, y), v in changes.items():
|
||||
g.setv(x, y, v)
|
||||
return bool(changes)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
47
2020/grid.py
47
2020/grid.py
|
@ -3,6 +3,30 @@
|
|||
from collections import defaultdict
|
||||
|
||||
|
||||
def near(p):
|
||||
"""Return a tuple of neighbor positions (up, left, down, right)."""
|
||||
return (
|
||||
(p[0] , p[1] - 1),
|
||||
(p[0] + 1, p[1] ),
|
||||
(p[0] , p[1] + 1),
|
||||
(p[0] - 1, p[1] ),
|
||||
)
|
||||
|
||||
|
||||
def near8(p):
|
||||
"""Return a tuple of neighbor positions, including diagonals."""
|
||||
return (
|
||||
(p[0] - 1, p[1] - 1),
|
||||
(p[0] , p[1] - 1),
|
||||
(p[0] + 1, p[1] - 1),
|
||||
(p[0] - 1, p[1] ),
|
||||
(p[0] + 1, p[1] ),
|
||||
(p[0] - 1, p[1] + 1),
|
||||
(p[0] , p[1] + 1),
|
||||
(p[0] + 1, p[1] + 1),
|
||||
)
|
||||
|
||||
|
||||
class Grid:
|
||||
|
||||
def __init__(self, value_factory=int, lines=None):
|
||||
|
@ -10,6 +34,9 @@ class Grid:
|
|||
if lines:
|
||||
self.load(lines)
|
||||
|
||||
def hasv(self, x, y):
|
||||
return y in self.g and x in self.g[y]
|
||||
|
||||
def getv(self, x, y):
|
||||
return self.g[y][x]
|
||||
|
||||
|
@ -26,9 +53,12 @@ class Grid:
|
|||
for x, v in row.items():
|
||||
yield (x, y, v)
|
||||
|
||||
def near_objects(self, p):
|
||||
"""Return a dict of neighbor positions to values (U, L, D, R)."""
|
||||
return {q: self.g[q[1]][q[0]] for q in Grid.near(p)}
|
||||
def near_objects(self, p, near_f=near):
|
||||
return {
|
||||
q: self.getv(q[0], q[1])
|
||||
for q in near_f(p)
|
||||
if self.hasv(q[0], q[1]) # do not create entries.
|
||||
}
|
||||
|
||||
def dumb_print(self, f=lambda v: v):
|
||||
for row in self.g.values():
|
||||
|
@ -37,19 +67,8 @@ class Grid:
|
|||
print()
|
||||
|
||||
def print_near(self, p, view_size=2):
|
||||
"""Print near values in an area of view_size. Works iff keys support addition."""
|
||||
for dy in range(-view_size, view_size + 1):
|
||||
print("".join([
|
||||
self.g[p[1] + dy][p[0] + dx]
|
||||
for dx in range(-view_size, view_size + 1)
|
||||
]))
|
||||
|
||||
@staticmethod
|
||||
def near(p):
|
||||
"""Return a tuple of neighbor positions (up, left, down, right)."""
|
||||
return (
|
||||
(p[0] , p[1] - 1),
|
||||
(p[0] + 1, p[1] ),
|
||||
(p[0] , p[1] + 1),
|
||||
(p[0] - 1, p[1] ),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue