| @@ -0,0 +1,55 @@ | |||
| import sys | |||
| from functools import lru_cache | |||
| from toolkit import read_image | |||
| def simple_adjace(level, pos): | |||
| inbound = {pos + ori for ori in [1, -1, 1j, -1j]} & domain | |||
| return [(level, p) for p in inbound] | |||
| @lru_cache(maxsize=None) | |||
| def recursive_adjace(level, pos, center=complex(2, 2)): | |||
| neis = [] | |||
| for ori in [1, -1, 1j, -1j]: | |||
| adj = pos + ori | |||
| if adj == center: | |||
| neis += [(level + 1, p) for p in domain if p - ori not in domain] | |||
| elif adj not in domain: | |||
| neis += [(level - 1, center + ori)] | |||
| else: | |||
| neis += [(level, adj)] | |||
| return neis | |||
| def evolve(bugs, adjacency, lim=None): | |||
| seen_states = set() | |||
| while lim is None or len(seen_states) < lim: | |||
| affected = {nei for tile in bugs for nei in adjacency(*tile)} | bugs | |||
| infested = set() | |||
| dead = set() | |||
| for tile in affected: | |||
| count = sum(nei in bugs for nei in adjacency(*tile)) | |||
| if tile in bugs and count != 1: | |||
| dead.add(tile) | |||
| elif tile not in bugs and count in [1, 2]: | |||
| infested.add(tile) | |||
| bugs = bugs - dead | infested | |||
| if bugs in seen_states: | |||
| break | |||
| seen_states.add(bugs) | |||
| return bugs | |||
| text = sys.stdin.read() | |||
| domain = set(read_image(text)) | |||
| bugs = frozenset((0, pos) for pos, c in read_image(text).items() if c == '#') | |||
| final = evolve(bugs, simple_adjace) | |||
| print(int(sum(2 ** (p.real + p.imag * 5) for _, p in final))) | |||
| final = evolve(bugs, recursive_adjace, 200) | |||
| print(len(final)) | |||