From c3975b22aee3218725612b2cc617a56d8af170ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Rasmussen?= Date: Mon, 14 Dec 2020 15:26:16 +0100 Subject: [PATCH] Day 12, part 2 --- 2020/12/main.py | 137 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 33 deletions(-) diff --git a/2020/12/main.py b/2020/12/main.py index be9e67c..f3ed867 100644 --- a/2020/12/main.py +++ b/2020/12/main.py @@ -1,8 +1,19 @@ -class Ferry: +import math + +class Waypoint: def __init__(self): self.heading = 90 # east self.pos_north = 0 self.pos_east = 0 + self.commands = { + "N": self.move_north, + "S": self.move_south, + "E": self.move_east, + "W": self.move_west, + "L": self.rotate_left, + "R": self.rotate_right, + "F": self.move_forward, + } def load(self, filename): with open(filename, "r", encoding="utf-8") as f: @@ -10,50 +21,110 @@ class Ferry: data = line.rstrip() self.process(data) - def rotate(self, degrees): + def move_north(self, value): + self.pos_north += value + + def move_south(self, value): + self.pos_north -= value + + def move_east(self, value): + self.pos_east += value + + def move_west(self, value): + self.pos_east -= value + + def rotate_left(self, degrees): + self.heading -= degrees + self.__fix_heading() + + def rotate_right(self, degrees): self.heading += degrees + self.__fix_heading() + + def move_forward(self, value): + if self.heading == 0: + self.pos_north += value + elif self.heading == 90: + self.pos_east += value + elif self.heading == 180: + self.pos_north -= value + elif self.heading == 270: + self.pos_east -= value + else: + raise Exception(self.heading) + + def __fix_heading(self): while self.heading < 0: self.heading += 360 while self.heading >= 360: self.heading -= 360 def process(self, input): - command = input[:1] + cchar = input[:1] value = int(input[1:]) - - if command == "N": - self.pos_north += value - elif command == "S": - self.pos_north -= value - elif command == "E": - self.pos_east += value - elif command == "W": - self.pos_east -= value - elif command == "L": - self.rotate(-value) - elif command == "R": - self.rotate(value) - elif command == "F": - if self.heading == 0: - self.pos_north += value - elif self.heading == 90: - self.pos_east += value - elif self.heading == 180: - self.pos_north -= value - elif self.heading == 270: - self.pos_east -= value - else: - raise Exception(self.heading) - else: - raise Exception(command) - - print(input, self.pos_east, self.pos_north) + command = self.commands[cchar] + command(value) def get_md(self): return abs(self.pos_east) + abs(self.pos_north) + +class Ship: + def __init__(self): + self.waypoint = Waypoint() + self.pos_north = 0 + self.pos_east = 0 + self.commands = { + "F": self.move_forward, + "L": self.rotate_left, + "R": self.rotate_right, + } + + def load(self, filename): + with open(filename, "r", encoding="utf-8") as f: + for line in f: + data = line.rstrip() + self.process(data) + + def process(self, input): + cchar = input[:1] + value = int(input[1:]) + if cchar in self.commands: + command = self.commands[cchar] + command(value) + else: + self.waypoint.process(input) + + def move_forward(self, value): + self.pos_north += self.waypoint.pos_north * value + self.pos_east += self.waypoint.pos_east * value + + def rotate_right(self, degrees): + self.rotate_left(-degrees) + + def rotate_left(self, degrees): + radians = degrees / 180 * math.pi + c = math.cos(radians) + s = math.sin(radians) + e = c * self.waypoint.pos_east - s * self.waypoint.pos_north + n = s * self.waypoint.pos_east + c * self.waypoint.pos_north + self.waypoint.pos_east = round(e) + self.waypoint.pos_north = round(n) + + def get_md(self): + return abs(self.pos_east) + abs(self.pos_north) + + + if __name__ == "__main__": - f = Ferry() + f = Waypoint() f.load("data.txt") md = f.get_md() - print(f"Manhattan distance is {md}") + print(f"1: Manhattan distance is {md}") + + f = Ship() + f.waypoint.pos_east = 10 + f.waypoint.pos_north = 1 + f.load("data.txt") + md = f.get_md() + print(f"2: Manhattan distance is {md}")