summaryrefslogtreecommitdiff
path: root/day12/day12.py
blob: 2476725a6412904a87444e4a0115d4ad49e28c51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""Day 12."""
import math

with open("input") as f:
    instructions = f.read().rstrip().split("\n")

DIRECTIONS = ("N", "E", "S", "W")
CURRENT_DIRECTION = "E"
CORDS = {
    "x": 0,
    "y": 0,
}
WAYPOINT = {
    'x': 10,
    'y': 1,
}


def left(current_direction, degree):
    idx = DIRECTIONS.index(current_direction) - (degree // 90)
    return DIRECTIONS[idx % len(DIRECTIONS)]


def right(current_direction, degree):
    idx = DIRECTIONS.index(current_direction) + (degree // 90)
    return DIRECTIONS[idx % len(DIRECTIONS)]


def update_coords(direction, value):
    if direction == "N":
        CORDS["y"] += value
    if direction == "E":
        CORDS["x"] += value
    if direction == "S":
        CORDS["y"] -= value
    if direction == "W":
        CORDS["x"] -= value


for inst in instructions:
    direction, value = inst[0], int(inst[1:])
    if direction == "L":
        CURRENT_DIRECTION = left(CURRENT_DIRECTION, value)
    elif direction == "R":
        CURRENT_DIRECTION = right(CURRENT_DIRECTION, value)
    elif direction == "F":
        update_coords(CURRENT_DIRECTION, value)
    else:
        update_coords(direction, value)

# Part 1
part_1 = abs(CORDS["x"]) + abs(CORDS["y"])
print(part_1)
assert part_1 == 882

# reset coords
CORDS = {
    "x": 0,
    "y": 0,
}

def update_waypoint(direction, value):
    if direction == "N":
        WAYPOINT["y"] += value
    if direction == "E":
        WAYPOINT["x"] += value
    if direction == "S":
        WAYPOINT["y"] -= value
    if direction == "W":
        WAYPOINT["x"] -= value


def clockwise(degrees):
    """rotate clockwise."""
    x = WAYPOINT["x"]
    y = WAYPOINT["y"]
    rads = math.radians(degrees % 360)
    return (
        round(x * math.cos(rads) + y * math.sin(rads)),
        round(-x * math.sin(rads) + y * math.cos(rads))
    )

for inst in instructions:
    direction, value = inst[0], int(inst[1:])
    if direction == "L":
        newx, newy = clockwise(360 - value)
        WAYPOINT["x"] = newx
        WAYPOINT["y"] = newy
    elif direction == "R":
        newx, newy = clockwise(value)
        WAYPOINT["x"] = newx
        WAYPOINT["y"] = newy
    elif direction == "F":
        CORDS["x"] += WAYPOINT["x"] * value
        CORDS["y"] += WAYPOINT["y"] * value
    else:
        update_waypoint(direction, value)


part_2 = abs(CORDS["x"]) + abs(CORDS["y"])
assert part_2 == 28885
print(part_2)