129 lines
2.7 KiB
Python
129 lines
2.7 KiB
Python
import os
|
|
debug_draw = False
|
|
|
|
with open("09.txt") as f:
|
|
data = f.read()
|
|
ex_data = """R 4
|
|
U 4
|
|
L 3
|
|
D 1
|
|
R 4
|
|
D 1
|
|
L 5
|
|
R 2"""
|
|
ex2_data = """R 5
|
|
U 8
|
|
L 8
|
|
D 3
|
|
R 17
|
|
D 10
|
|
L 25
|
|
U 20"""
|
|
|
|
def is_adj(a, b):
|
|
return abs(a[0] - b[0]) <= 1 and abs(a[1] - b[1]) <= 1
|
|
|
|
dirs = {"NIL": (0, 0), "R": (1, 0), "U": (0, 1), "L": (-1, 0), "D": (0, -1),
|
|
"UR": (1, 1), "UL": (-1, 1), "DR": (1, -1), "DL": (-1, -1)}
|
|
dir_inv = dict()
|
|
for k, v in dirs.items():
|
|
dir_inv[v] = k
|
|
|
|
def move(dir, head, tail):
|
|
|
|
dx, dy = dirs[dir]
|
|
hx, hy = head
|
|
tx, ty = tail
|
|
nhx, nhy = hx + dx, hy + dy
|
|
|
|
if is_adj((nhx, nhy), (tx, ty)): ntx, nty = tx, ty
|
|
elif nhx != tx and nhy != ty:
|
|
# import pdb; pdb.set_trace()
|
|
# Move diagonally
|
|
ax, ay = nhx - tx, nhy - ty
|
|
if ax != 0 and ay != 0:
|
|
ax, ay = abs(ax) // ax, abs(ay) // ay
|
|
ntx, nty = tx + ax, ty + ay
|
|
elif nhx == tx:
|
|
if dir == "L" or dir == "R": ntx, nty = tx, ty
|
|
elif abs(nhy - ty) == 2: ntx, nty = tx, ty + dy
|
|
else: ntx, nty = tx, ty
|
|
elif nhy == ty:
|
|
if dir == "U" or dir == "D": ntx, nty = tx, ty
|
|
elif abs(nhx - tx) == 2: ntx, nty = tx + dx, ty
|
|
else: ntx, nty = tx, ty
|
|
else: ntx, nty = hx, hy
|
|
|
|
return (nhx, nhy), (ntx, nty)
|
|
|
|
def solve1(data):
|
|
head = (0, 0)
|
|
tail = (0, 0)
|
|
|
|
all_pos = set()
|
|
all_pos.add(tail)
|
|
|
|
for line in data.splitlines():
|
|
line = line.strip()
|
|
dir, dist = line.split(" ")
|
|
dist = int(dist)
|
|
for _ in range(dist):
|
|
head, tail = move(dir, head, tail)
|
|
all_pos.add(tail)
|
|
|
|
print(len(all_pos))
|
|
|
|
def move_multiple(dir, segs):
|
|
new_segs = []
|
|
cur_dir = dir
|
|
for i in range(1, len(segs)):
|
|
head, tail = segs[i - 1], segs[i]
|
|
nhead, ntail = move(cur_dir, head, tail)
|
|
new_segs.append(nhead)
|
|
cur_dir = dir_inv[(ntail[0] - tail[0], ntail[1] - tail[1])]
|
|
new_segs.append(ntail)
|
|
return new_segs
|
|
|
|
def solve2(data):
|
|
segs = []
|
|
for _ in range(10): segs.append((0, 0))
|
|
|
|
all_pos = set()
|
|
all_pos.add((0, 0))
|
|
|
|
for line in data.splitlines():
|
|
line = line.strip()
|
|
dir, dist = line.split(" ")
|
|
dist = int(dist)
|
|
for times in range(dist):
|
|
if debug_draw: os.system("clear")
|
|
segs = move_multiple(dir, segs)
|
|
all_pos.add(segs[-1])
|
|
|
|
if debug_draw:
|
|
print(dir, dist - times - 1)
|
|
segs_draw = dict()
|
|
for i, seg in enumerate(segs):
|
|
segs_draw[seg] = i
|
|
print(segs)
|
|
print(segs_draw)
|
|
for y in range(20, -20, -1):
|
|
for x in range(-20, 20):
|
|
n = segs_draw.get((x, y))
|
|
if n is None: print(".", end="")
|
|
else: print(n, end="")
|
|
print()
|
|
input()
|
|
|
|
print(len(all_pos))
|
|
|
|
head = (1, 1)
|
|
tail = (0, 0)
|
|
# print(move("UL", head, tail))
|
|
|
|
solve1(ex_data)
|
|
solve1(data)
|
|
|
|
solve2(ex_data)
|
|
solve2(ex2_data)
|
|
solve2(data)
|