Day 12, part 2
This commit is contained in:
parent
30156f0229
commit
c3975b22ae
1 changed files with 104 additions and 33 deletions
137
2020/12/main.py
137
2020/12/main.py
|
@ -1,8 +1,19 @@
|
||||||
class Ferry:
|
import math
|
||||||
|
|
||||||
|
class Waypoint:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.heading = 90 # east
|
self.heading = 90 # east
|
||||||
self.pos_north = 0
|
self.pos_north = 0
|
||||||
self.pos_east = 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):
|
def load(self, filename):
|
||||||
with open(filename, "r", encoding="utf-8") as f:
|
with open(filename, "r", encoding="utf-8") as f:
|
||||||
|
@ -10,50 +21,110 @@ class Ferry:
|
||||||
data = line.rstrip()
|
data = line.rstrip()
|
||||||
self.process(data)
|
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.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:
|
while self.heading < 0:
|
||||||
self.heading += 360
|
self.heading += 360
|
||||||
while self.heading >= 360:
|
while self.heading >= 360:
|
||||||
self.heading -= 360
|
self.heading -= 360
|
||||||
|
|
||||||
def process(self, input):
|
def process(self, input):
|
||||||
command = input[:1]
|
cchar = input[:1]
|
||||||
value = int(input[1:])
|
value = int(input[1:])
|
||||||
|
command = self.commands[cchar]
|
||||||
if command == "N":
|
command(value)
|
||||||
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)
|
|
||||||
|
|
||||||
def get_md(self):
|
def get_md(self):
|
||||||
return abs(self.pos_east) + abs(self.pos_north)
|
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__":
|
if __name__ == "__main__":
|
||||||
f = Ferry()
|
f = Waypoint()
|
||||||
f.load("data.txt")
|
f.load("data.txt")
|
||||||
md = f.get_md()
|
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}")
|
||||||
|
|
Loading…
Reference in a new issue