105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
|
import lib
|
||
|
|
||
|
EXAMPLE = """
|
||
|
498,4 -> 498,6 -> 496,6
|
||
|
503,4 -> 502,4 -> 502,9 -> 494,9
|
||
|
"""
|
||
|
|
||
|
def solve(lines: list[str]):
|
||
|
c = set()
|
||
|
for (i, line) in enumerate(lines):
|
||
|
coords = [list(map(int, c.split(","))) for c in line.split(" -> ")]
|
||
|
for i in range(len(coords) - 1):
|
||
|
a, b = coords[i:i + 2]
|
||
|
a_x, a_y = a
|
||
|
b_x, b_y = b
|
||
|
if a_x == b_x and a_y < b_y:
|
||
|
for y in range(a_y, b_y + 1):
|
||
|
c.add((a_x, y))
|
||
|
elif a_x == b_x and a_y > b_y:
|
||
|
for y in range(b_y, a_y + 1):
|
||
|
c.add((a_x, y))
|
||
|
elif a_y == b_y and a_x < b_x:
|
||
|
for x in range(a_x, b_x + 1):
|
||
|
c.add((x, a_y))
|
||
|
elif a_y == b_y and a_x > b_x:
|
||
|
for x in range(b_x, a_x + 1):
|
||
|
c.add((x, a_y))
|
||
|
else:
|
||
|
raise Exception(f"unexpected {a=} {b=}")
|
||
|
|
||
|
largest_y = max(c, key=lambda c: c[1])[1]
|
||
|
s = (500, 0)
|
||
|
s_count = 0
|
||
|
while s[1] < largest_y:
|
||
|
if not (ns := (s[0], s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
elif not (ns := (s[0] - 1, s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
elif not (ns := (s[0] + 1, s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
else:
|
||
|
c.add(s)
|
||
|
s = (500, 0)
|
||
|
s_count += 1
|
||
|
return s_count
|
||
|
|
||
|
def solve2(lines: list[str]):
|
||
|
c = set()
|
||
|
for (i, line) in enumerate(lines):
|
||
|
coords = [list(map(int, c.split(","))) for c in line.split(" -> ")]
|
||
|
for i in range(len(coords) - 1):
|
||
|
a, b = coords[i:i + 2]
|
||
|
a_x, a_y = a
|
||
|
b_x, b_y = b
|
||
|
if a_x == b_x and a_y < b_y:
|
||
|
for y in range(a_y, b_y + 1):
|
||
|
c.add((a_x, y))
|
||
|
elif a_x == b_x and a_y > b_y:
|
||
|
for y in range(b_y, a_y + 1):
|
||
|
c.add((a_x, y))
|
||
|
elif a_y == b_y and a_x < b_x:
|
||
|
for x in range(a_x, b_x + 1):
|
||
|
c.add((x, a_y))
|
||
|
elif a_y == b_y and a_x > b_x:
|
||
|
for x in range(b_x, a_x + 1):
|
||
|
c.add((x, a_y))
|
||
|
else:
|
||
|
raise Exception(f"unexpected {a=} {b=}")
|
||
|
|
||
|
largest_y = max(c, key=lambda c: c[1])[1]
|
||
|
for x in range(-10000, 10000):
|
||
|
c.add((x, largest_y + 2))
|
||
|
|
||
|
s = (500, 0)
|
||
|
s_count = 1
|
||
|
while True:
|
||
|
if not (ns := (s[0], s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
elif not (ns := (s[0] - 1, s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
elif not (ns := (s[0] + 1, s[1] + 1)) in c:
|
||
|
s = ns
|
||
|
elif s[1] == 0:
|
||
|
return s_count
|
||
|
else:
|
||
|
c.add(s)
|
||
|
s_count += 1
|
||
|
s = (500, 0)
|
||
|
|
||
|
def main():
|
||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||
|
print("Example 1:", solve(lines))
|
||
|
|
||
|
lines = lib.str_to_lines_no_empty(open("i14.txt").read())
|
||
|
print("Solution 1:", solve(lines))
|
||
|
|
||
|
lines = lib.str_to_lines_no_empty(EXAMPLE)
|
||
|
print("Example 2:", solve2(lines))
|
||
|
|
||
|
lines = lib.str_to_lines_no_empty(open("i14.txt").read())
|
||
|
print("Solution 2:", solve2(lines))
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|