Solve day 21 and 22 2017.

This commit is contained in:
2024-06-03 12:06:02 -04:00
parent 8042b7f5e2
commit 869a22a310
3 changed files with 184 additions and 1 deletions

110
2017/d21.py Normal file
View File

@@ -0,0 +1,110 @@
IMAGE = """.#.
..#
###"""
def flipv(pattern):
return tuple(map(lambda row: tuple(reversed(row)), pattern))
def fliph(pattern):
return tuple(reversed(pattern))
def rot90(pattern):
return tuple(map(tuple, map(reversed, tuple(zip(*pattern)))))
def parse_rule(line: str) -> dict:
lhs, rhs = line.split(" => ")
rules = {}
lhs = tuple(map(tuple, lhs.split("/")))
rhs = list(map(list, rhs.split("/")))
rules[lhs] = rhs
rules[rot90(lhs)] = rhs
rules[rot90(rot90((lhs)))] = rhs
rules[rot90(rot90(rot90((lhs))))] = rhs
rules[flipv(lhs)] = rhs
rules[fliph(lhs)] = rhs
rules[rot90(flipv(lhs))] = rhs
rules[rot90(rot90(flipv(lhs)))] = rhs
rules[rot90(rot90(rot90(flipv(lhs))))] = rhs
rules[rot90(fliph(lhs))] = rhs
rules[rot90(rot90(fliph(lhs)))] = rhs
rules[rot90(rot90(rot90(fliph(lhs))))] = rhs
return rules
def print_image(image):
for row in image:
print("".join(row))
def slice_get(matrix, row, col, size):
r = []
for ri in range(row, row + size):
r.append(matrix[ri][col:col+size])
return r
def slice_set(matrix, row, col, new):
for ri, r in enumerate(new):
matrix[ri + row][col:col + len(r)] = r
def slice_append(matrix, slice):
for ri, row in enumerate(slice):
for c in row:
matrix[-len(slice) + ri].append(c)
def part_1(data, iterations=5):
rules = {}
image = list(map(list, IMAGE.splitlines()))
for line in data.splitlines():
line = line.strip()
for k, v in parse_rule(line).items():
assert (k not in rules) or rules[k] == v
rules[k] = v
for _ in range(iterations):
len_image = len(image)
new_image = []
if len_image % 2 == 0:
for row in range(0, len(image), 2):
for _ in range(3):
new_image.append([])
for col in range(0, len(image[0]), 2):
slice = tuple(map(tuple, slice_get(image, row, col, 2)))
new_slice = rules[slice]
slice_append(new_image, new_slice)
else:
for row in range(0, len(image), 3):
for _ in range(4):
new_image.append([])
for col in range(0, len(image[0]), 3):
slice = tuple(map(tuple, slice_get(image, row, col, 3)))
new_slice = rules[slice]
slice_append(new_image, new_slice)
image = new_image
count = 0
for row in image:
count += row.count("#")
print(count)
def main():
data = open(0).read()
part_1(data)
part_1(data, 18)
if __name__ == "__main__":
main()

71
2017/d22.py Normal file
View File

@@ -0,0 +1,71 @@
from lib import Grid2D, add2
def part_1(data):
steps = 10_000
g = Grid2D(data)
# g.print()
dirs = [g.N, g.E, g.S, g.W]
pos = (g.n_rows // 2, g.n_cols // 2)
dir = g.N
inf = set(g.find("#"))
burst_inf = 0
for _ in range(steps):
if pos in inf:
# turn right
dir = dirs[(dirs.index(dir) + 1) % len(dirs)]
inf.remove(pos)
else:
# turn left
dir = dirs[(dirs.index(dir) - 1) % len(dirs)]
inf.add(pos)
burst_inf += 1
pos = add2(pos, dir)
print(burst_inf)
def part_2(data):
steps = 10000000
g = Grid2D(data)
dirs = [g.N, g.E, g.S, g.W]
pos = (g.n_rows // 2, g.n_cols // 2)
dir = g.N
weak = set()
inf = set(g.find("#"))
flagged = set()
burst_inf = 0
for _ in range(steps):
if pos in weak:
weak.remove(pos)
inf.add(pos)
burst_inf += 1
elif pos in inf:
dir = dirs[(dirs.index(dir) + 1) % len(dirs)]
inf.remove(pos)
flagged.add(pos)
elif pos in flagged:
dir = dirs[(dirs.index(dir) + 2) % len(dirs)]
flagged.remove(pos)
else:
dir = dirs[(dirs.index(dir) - 1) % len(dirs)]
weak.add(pos)
pos = add2(pos, dir)
print(burst_inf)
def main():
data = open(0).read()
part_1(data)
part_2(data)
if __name__ == "__main__":
main()