import fileinput class Rope: def __init__(self): self.head = [0,0] self.tail = [0,0] self.visited = set([tuple(self.tail)]) def chatchup(self): if max(abs(self.head[0] - self.tail[0]), abs(self.head[1] - self.tail[1])) <= 1: # Same pos or next to each other pass else: if self.head[1] > self.tail[1]: self.tail[1] += 1 elif self.head[1] < self.tail[1]: self.tail[1] -= 1 if self.head[0] > self.tail[0]: self.tail[0] += 1 elif self.head[0] < self.tail[0]: self.tail[0] -= 1 self.visited.add(tuple(self.tail)) def step(self, d, count): if d == "U": self.head[1] += 1 elif d == "D": self.head[1] -= 1 elif d == "L": self.head[0] += 1 elif d == "R": self.head[0] -= 1 self.chatchup() if count > 1: self.step(d, count-1) class LongRope: def __init__(self): self.ropes = [] for _ in range(9): self.ropes.append(Rope()) def step(self, d, count): if d == "U": self.ropes[0].head[1] += 1 elif d == "D": self.ropes[0].head[1] -= 1 elif d == "L": self.ropes[0].head[0] += 1 elif d == "R": self.ropes[0].head[0] -= 1 self.ropes[0].chatchup() for idx in range(1, len(self.ropes)): self.ropes[idx].head = self.ropes[idx-1].tail self.ropes[idx].chatchup() if count > 1: self.step(d,count-1) def solve(lines): rope = Rope() for d, count in map(lambda x: x.split(' '), filter(lambda x: x != "", map(lambda x: x.strip(), lines))): count = int(count) rope.step(d, count) return len(rope.visited) def solveb(lines): rope = LongRope() for d, count in map(lambda x: x.split(' '), filter(lambda x: x != "", map(lambda x: x.strip(), lines))): count = int(count) rope.step(d, count) return len(rope.ropes[-1].visited) if __name__ == "__main__": print(f"Visited {solve(fileinput.input())}") print(f"Visited long {solveb(fileinput.input())}")