diff --git a/2020-python/inputs/day_12 b/2020-python/inputs/day_12 new file mode 100644 index 0000000..29f07f6 --- /dev/null +++ b/2020-python/inputs/day_12 @@ -0,0 +1,789 @@ +R180 +S4 +L90 +S2 +R90 +W3 +F30 +R90 +W3 +L90 +F68 +L90 +E5 +F88 +S1 +L90 +F46 +W5 +F51 +S2 +L90 +F53 +S5 +F19 +W2 +L90 +F91 +E2 +S3 +F83 +N5 +F79 +W1 +S3 +F11 +E4 +F53 +W4 +S5 +R90 +E1 +F76 +R90 +F47 +E5 +R90 +W3 +R90 +S5 +L180 +W5 +N4 +F10 +S2 +R90 +S4 +W4 +F29 +S5 +F34 +E2 +S4 +R90 +F73 +N2 +F43 +W1 +N4 +R90 +S3 +F26 +S5 +W1 +N5 +R90 +W3 +F29 +R90 +W4 +F81 +R90 +E5 +S4 +W1 +F73 +N2 +E1 +F66 +L90 +E4 +S4 +E3 +N2 +F34 +L90 +W1 +F13 +S4 +E2 +F21 +N5 +E5 +N2 +F65 +L90 +N3 +R270 +F49 +E5 +L90 +E5 +R90 +F20 +S4 +F99 +W3 +N2 +E5 +L90 +F94 +R90 +S2 +R90 +S3 +F47 +S3 +R90 +F71 +W1 +R90 +N4 +E5 +S1 +F72 +L90 +F18 +E5 +F94 +L270 +F80 +W5 +R180 +N1 +F40 +R180 +N1 +E3 +N5 +F29 +R90 +E1 +R90 +E3 +L180 +E3 +R90 +S2 +L90 +E3 +L180 +F80 +E2 +S5 +E1 +N2 +L180 +F25 +N2 +L90 +F66 +R90 +F48 +N3 +L180 +N3 +R90 +E5 +R90 +F52 +R180 +S5 +L270 +S4 +L90 +F53 +S4 +W3 +W4 +F36 +W2 +N2 +N4 +L90 +W1 +R90 +E4 +F30 +N5 +W1 +S2 +W5 +F98 +W1 +N1 +F92 +L180 +N2 +R90 +S4 +L90 +F66 +N3 +L90 +F33 +W2 +S2 +E4 +F8 +W2 +L180 +F15 +S1 +E1 +F14 +S1 +W2 +L270 +F86 +E1 +R180 +W5 +R90 +N3 +L90 +N5 +E1 +F78 +N1 +L90 +F1 +F73 +R90 +F68 +W4 +F79 +F34 +N5 +R180 +E5 +L180 +S3 +W5 +F27 +R180 +F70 +R90 +S4 +F62 +L180 +N3 +R90 +S5 +F4 +R90 +S5 +W2 +N5 +R90 +F81 +L90 +N1 +F32 +E2 +N1 +W2 +L180 +E5 +R180 +S3 +E3 +R90 +S3 +F1 +N5 +E3 +F60 +W2 +F58 +L180 +S2 +E3 +L90 +F36 +L90 +E4 +E1 +F29 +W2 +R90 +R180 +N3 +L90 +R180 +S5 +W1 +F13 +R90 +W5 +S2 +R180 +F16 +W4 +L90 +W2 +S5 +F25 +R90 +F40 +L90 +L90 +F76 +S2 +R180 +N2 +R180 +W4 +S5 +F61 +N4 +E1 +F57 +E5 +F72 +W4 +F61 +R90 +S4 +F52 +W2 +N1 +F30 +L90 +F59 +N1 +L90 +W2 +N2 +F51 +E5 +F16 +S1 +W3 +L90 +F92 +E3 +N2 +F22 +L180 +N3 +F10 +E4 +N2 +F43 +R90 +F99 +S3 +R180 +E1 +S1 +W2 +L180 +F56 +N3 +F6 +N4 +F21 +L90 +N4 +L180 +N4 +F15 +E5 +S3 +W1 +F57 +E3 +S4 +W3 +L90 +S3 +L90 +F41 +E1 +S5 +L90 +F63 +N4 +F89 +F57 +S1 +L90 +S4 +L180 +F96 +L180 +N5 +E4 +L90 +E1 +S1 +F77 +S3 +L90 +E4 +L90 +E5 +L90 +N3 +L180 +S1 +N2 +L90 +N3 +R90 +F45 +R180 +F57 +N3 +R90 +E4 +L180 +F37 +L90 +W2 +R90 +S1 +R90 +N3 +F77 +W5 +F80 +S1 +S5 +R90 +N5 +E5 +S3 +L270 +F15 +L180 +W5 +F48 +E1 +L180 +S4 +E1 +S4 +W5 +F76 +S1 +E1 +S1 +F55 +L90 +F70 +R180 +R90 +E4 +R90 +S3 +E2 +S3 +F84 +S4 +W3 +F100 +R90 +S1 +L90 +F37 +W4 +F3 +R180 +N3 +R90 +L90 +W2 +F28 +R270 +N5 +R180 +S2 +E4 +F54 +L90 +W5 +R90 +F79 +N3 +R90 +F34 +W1 +N3 +F76 +W3 +F2 +W1 +L90 +R90 +F72 +N1 +E3 +F79 +W1 +L90 +F8 +E4 +F87 +E2 +F4 +S3 +L90 +F100 +F94 +E4 +R270 +S1 +E2 +F70 +E4 +L90 +S2 +W5 +L90 +S5 +W2 +S2 +W5 +F19 +E2 +E1 +F62 +L90 +F55 +E3 +R180 +F74 +S3 +W2 +F66 +L180 +F32 +W5 +F66 +W1 +F48 +S3 +R90 +N5 +W2 +N2 +F18 +E3 +F41 +L90 +N4 +F56 +L90 +R90 +F42 +R90 +S3 +L90 +E2 +S2 +F7 +W3 +N5 +L180 +L90 +L90 +N5 +L90 +W4 +F82 +W2 +F68 +S1 +E3 +S2 +F87 +L90 +F93 +L90 +F16 +L90 +S4 +L90 +N3 +E2 +R90 +S2 +R180 +F94 +W1 +S3 +F68 +S2 +F70 +S3 +W4 +F29 +E5 +R180 +S2 +F63 +L180 +F65 +R90 +W1 +F64 +E1 +L180 +L90 +S5 +F65 +L90 +N3 +N4 +L270 +S1 +E2 +S3 +W3 +N1 +E5 +F16 +E2 +L90 +N1 +L90 +E1 +S4 +W2 +R180 +F27 +N1 +R180 +E2 +L90 +F20 +N1 +W3 +N1 +R90 +W5 +R90 +E3 +S2 +F48 +N1 +R180 +N3 +W1 +S4 +F92 +S3 +R90 +S5 +E1 +W5 +R90 +S2 +W1 +L90 +R180 +E3 +N3 +E1 +R180 +E4 +L90 +E5 +L90 +W3 +L270 +E1 +S5 +W5 +L180 +W3 +S2 +F16 +W5 +S4 +R90 +N3 +L90 +N4 +F43 +N2 +F83 +S2 +W5 +F58 +W4 +N5 +R180 +E3 +F81 +L90 +F61 +L90 +W4 +F41 +E3 +N2 +F74 +R90 +F6 +R90 +W1 +F18 +R90 +R90 +N2 +F87 +S4 +F16 +S3 +E3 +F67 +R90 +E2 +L90 +S4 +R90 +F5 +W1 +R90 +W4 +F54 +S1 +W1 +F100 +S5 +E2 +L90 +W3 +F61 +L180 +W2 +S3 +F68 +F35 +N3 +R180 +E4 +R270 +S5 +E4 +L180 +S3 +R90 +N5 +E4 +F60 +W4 +S1 +L90 +L180 +N5 +L180 +W3 +S1 +E3 +S1 +N2 +E4 +R180 +N4 +F7 +N3 +W4 +F89 +N4 +E3 +L90 +F97 diff --git a/2020-python/solutions/day_12.py b/2020-python/solutions/day_12.py new file mode 100644 index 0000000..ea4d50d --- /dev/null +++ b/2020-python/solutions/day_12.py @@ -0,0 +1,116 @@ +"""AOC 2020 Day 12""" + +import pathlib +import time + +TEST_INPUT = """F10 +N3 +F7 +R90 +F11""" + +LEFT, RIGHT = 'L', 'R' +FORWARD = 'F' +NORTH, SOUTH, EAST, WEST = 'N', 'S', 'E', 'W' + +def read_input(input_path: str) -> str: + """take input file path and return a str with the file's content""" + with open(input_path, 'r') as input_file: + input_data = input_file.read().strip() + return input_data + +def extract(input_data: str) -> list: + """take input data and return the appropriate data structure""" + entries = [] + for line in input_data.split('\n'): + instruction = (line[0], int(line[1:])) + entries.append(instruction) + return entries + +def rotate_ship(direction: str, rotation: str) -> str: + """rotate the ship""" + if direction == NORTH: + return WEST if rotation == LEFT else EAST + if direction == SOUTH: + return EAST if rotation == LEFT else WEST + if direction == EAST: + return NORTH if rotation == LEFT else SOUTH + if direction == WEST: + return SOUTH if rotation == LEFT else NORTH + return None + +def move(direction: str, x: int, y: int, value: int) -> tuple: + """move the ship or the waypoint""" + if direction == NORTH: + return (x, y+value) + if direction == SOUTH: + return (x, y-value) + if direction == EAST: + return (x+value, y) + if direction == WEST: + return (x-value, y) + return None + +def rotate_waypoint(direction: str, x: int, y: int, value: int) -> tuple: + """rotate waypoint around ship""" + if (direction == LEFT and value == 90) or (direction == RIGHT and value == 270): + return (-y, x) + if ((direction == LEFT and value == 180) or (direction == RIGHT and value == 180)): + return (-x, -y) + if ((direction == LEFT and value == 270) or (direction == RIGHT and value == 90)): + return (y, -x) + return None + +def part1(entries: list) -> int: + """part1 solver""" + direction = EAST + x_ship, y_ship = 0, 0 + + for action, value in entries: + if action == FORWARD: + x_ship, y_ship = move(direction, x_ship, y_ship, value) + elif action in (LEFT, RIGHT): + for _ in range(value//90): + direction = rotate_ship(direction, action) + else: + x_ship, y_ship = move(action, x_ship, y_ship, value) + return abs(x_ship) + abs(y_ship) + +def part2(entries: list) -> int: + """part2 solver""" + x_ship, y_ship = 0, 0 + x_wp, y_wp = 10, 1 + + for action, value in entries: + if action == FORWARD: + x_ship += x_wp * value + y_ship += y_wp * value + elif action in (LEFT, RIGHT): + x_wp, y_wp = rotate_waypoint(action, x_wp, y_wp, value) + else: + x_wp, y_wp = move(action, x_wp, y_wp, value) + return abs(x_ship) + abs(y_ship) + +def test_input_day_12(): + """pytest testing function""" + entries = extract(TEST_INPUT) + assert part1(entries) == 25 + assert part2(entries) == 286 + +def test_bench_day_12(benchmark): + """pytest-benchmark function""" + benchmark(main) + +def main(): + """main function""" + input_path = str(pathlib.Path(__file__).resolve().parent.parent) + "/inputs/" + str(pathlib.Path(__file__).stem) + start_time = time.time() + input_data = read_input(input_path) + entries = extract(input_data) + print("Part 1: %d" % part1(entries)) + print("Part 2: %d" % part2(entries)) + end_time = time.time() + print("Execution time: %f" % (end_time-start_time)) + +if __name__ == "__main__": + main() diff --git a/README.md b/README.md index 6009b44..188d27e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ | [Day 5](https://adventofcode.com/2020/day/5) | [5.993ms](./2020-python/solutions/day_05.py) | [---](./2020-python/solutions/day_05.py) | | [Day 6](https://adventofcode.com/2020/day/6) | [2.587ms](./2020-python/solutions/day_06.py) | [2.275ms](./2020-python/solutions/day_06.py) | | [Day 7](https://adventofcode.com/2020/day/7) | [1.689ms](./2020-python/solutions/day_07.py) | [1.565ms](./2020-python/solutions/day_07.py) | -| [Day 8](https://adventofcode.com/2020/day/8) | [6.313ms](./2020-python/solutions/day_08.py) | [794.417us](./2020-python/solutions/day_08.py) | +| [Day 8](https://adventofcode.com/2020/day/8) | [6.313ms](./2020-python/solutions/day_08.py) | [794.417µs](./2020-python/solutions/day_08.py) | | [Day 9](https://adventofcode.com/2020/day/9) | [7.220ms](./2020-python/solutions/day_09.py) | [4.783ms](./2020-python/solutions/day_09.py) | -| [Day 10](https://adventofcode.com/2020/day/10) | [139.110us](./2020-python/solutions/day_10.py) | [98.594us](./2020-python/solutions/day_10.py) | +| [Day 10](https://adventofcode.com/2020/day/10) | [139.110us](./2020-python/solutions/day_10.py) | [98.594µs](./2020-python/solutions/day_10.py) | | [Day 11](https://adventofcode.com/2020/day/11) | [2.879s](./2020-python/solutions/day_11.py) | [419.447ms](./2020-python/solutions/day_11.py) | +| [Day 12](https://adventofcode.com/2020/day/12) | [746.181µs](./2020-python/solutions/day_12.py) | [211.216µs](./2020-python/solutions/day_12.py) |