Compare commits

..

2 Commits

Author SHA1 Message Date
fb1e2183cc Solve 2019 day 11 2024-08-10 16:49:20 -04:00
e46636b9b0 Solve 2019 day 10 2024-08-10 14:22:19 -04:00
4 changed files with 207 additions and 13 deletions

102
2019/d10.py Normal file
View File

@ -0,0 +1,102 @@
from lib import get_data, Grid2D
from math import gcd, atan2, pi
def angle(a1, a2):
dy = a1[0] - a2[0]
dx = a2[1] - a1[1]
a = (atan2(dx, dy) + 2 * pi) % (2 * pi)
return a
def dist(a1, a2):
return abs(a1[0] - a2[0]) + abs(a1[1] - a2[1])
def part_1(data):
g = Grid2D(data)
asts = g.find("#")
asts_set = set(asts)
best_ast = None
visible_max = 0
for a in asts:
visible = 0
for other in asts:
if a == other:
continue
x1, x2 = a[0], other[0]
y1, y2 = a[1], other[1]
if y1 == y2:
for x in range(min(x1, x2) + 1, max(x1, x2)):
if (x, y1) in asts_set:
break
else:
visible += 1
elif x1 == x2:
for y in range(min(y1, y2) + 1, max(y1, y2)):
if (x1, y) in asts_set:
break
else:
visible += 1
else:
dx = abs(x1 - x2)
dy = abs(y1 - y2)
g = gcd(dx, dy)
dx //= g
dy //= g
x, y = x1, y1
if x2 < x1:
dx = -dx
if y2 < y1:
dy = -dy
blocked = False
while True:
x += dx
y += dy
if (x, y) == (x2, y2):
break
if (x, y) in asts_set:
blocked = True
break
if not blocked:
visible += 1
if visible > visible_max:
visible_max = visible
best_ast = a
assert best_ast is not None
print(visible_max)
other_asts = [a for a in asts if a != best_ast]
removed_count = 0
while True:
removed = set()
other_asts = sorted(
other_asts, key=lambda a: (angle(best_ast, a), dist(best_ast, a))
)
lowest_angle = -1
for a in other_asts:
current_angle = angle(best_ast, a)
if current_angle > lowest_angle:
removed.add(a)
lowest_angle = current_angle
removed_count += 1
if removed_count == 200:
print(a[1] * 100 + a[0])
return
other_asts = [a for a in other_asts if a not in removed]
def main():
data = get_data(__file__)
part_1(data)
if __name__ == "__main__":
main()

93
2019/d11.py Normal file
View File

@ -0,0 +1,93 @@
from lib import get_data, str_to_ints, add2
from d9 import Amp
DIRS = [(-1, 0), (0, 1), (1, 0), (0, -1)]
BLACK = 0
WHITE = 1
def part_1(data):
xs = str_to_ints(data)
a = Amp(xs)
current_dir_idx = 0
pos = (0, 0)
white_panels = set()
got_painted = set()
while not a.done:
if pos in white_panels:
a.feed(WHITE)
else:
a.feed(BLACK)
a.go()
a.go()
while a.outputs:
paint_color = a.pop()
if paint_color == BLACK:
white_panels.remove(pos)
elif paint_color == WHITE:
white_panels.add(pos)
else:
assert False
got_painted.add(pos)
turn_dir_code = a.pop()
turn_dir = -1 if turn_dir_code == 0 else 1
current_dir_idx = (current_dir_idx + turn_dir) % len(DIRS)
pos = add2(pos, DIRS[current_dir_idx])
print(len(got_painted))
def part_2(data):
xs = str_to_ints(data)
a = Amp(xs)
current_dir_idx = 0
pos = (0, 0)
white_panels = set([pos])
got_painted = set()
while not a.done:
if pos in white_panels:
a.feed(WHITE)
else:
a.feed(BLACK)
a.go()
a.go()
while a.outputs:
paint_color = a.pop()
if paint_color == BLACK:
if pos in white_panels:
white_panels.remove(pos)
elif paint_color == WHITE:
white_panels.add(pos)
else:
assert False
got_painted.add(pos)
turn_dir_code = a.pop()
turn_dir = -1 if turn_dir_code == 0 else 1
current_dir_idx = (current_dir_idx + turn_dir) % len(DIRS)
pos = add2(pos, DIRS[current_dir_idx])
white_panels = [(p[1], p[0]) for p in white_panels]
xs = [p[0] for p in white_panels]
ys = [p[1] for p in white_panels]
white_panels_set = set(white_panels)
x_min, x_max = min(xs), max(xs)
y_min, y_max = min(ys), max(ys)
for y in range(y_min, y_max + 1):
s = ""
for x in range(x_min, x_max + 1):
if (x, y) in white_panels_set:
s += "X"
else:
s += " "
print(s)
def main():
data = get_data(__file__)
part_1(data)
part_2(data)
if __name__ == "__main__":
main()

View File

@ -1,9 +1,5 @@
from lib import get_data, str_to_ints
data = "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99"
# data = "104,1125899906842624,99"
# data = "1102,34915192,34915192,7,4,7,99,0"
class Amp:
def __init__(self, xs):

View File

@ -110,15 +110,18 @@ Solutions and utility script for Advent of Code challenges in Python.
## AoC 2019
- Day 1: 4:25 (copy and paste error, no leaderboard)
- Day 2: 7:07 (19th)
- Day 3: 10:46 (37th)
- Day 4: 8:48 (just too slow, no leaderboard)
- Day 5: 34:24 (that wasn't hard at all)
- Day 6: 23:17 (so slow, no leaderboard)
- Day 7: 72:17 (I found that one challenging, 30:33 would have been required for leaderboard)
- Day 8: 08:55 (54th)
- Day 9:
- Day 1: 4:25 (copy and paste error, no leaderboard)
- Day 2: 7:07 (19th)
- Day 3: 10:46 (37th)
- Day 4: 8:48 (just too slow, no leaderboard)
- Day 5: 34:24 (that wasn't hard at all)
- Day 6: 23:17 (so slow, no leaderboard)
- Day 7: 72:17 (I found that one challenging, 30:33 would have been required for leaderboard)
- Day 8: 08:55 (54th)
- Day 9: 115:00 (Try to read next time.)
- Day 10: 76:00 (This wasn't easy for me. Fun, though.)
- Day 11: 21:04 (Too slow, but fun.)
- Day 12:
## AoC 2022