Skip to content

Commit f6537b7

Browse files
committed
Added days 2020-12 and 2020-13
1 parent 17e9266 commit f6537b7

File tree

2 files changed

+262
-0
lines changed

2 files changed

+262
-0
lines changed

2020/12-Rain Risk.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """F10
38+
N3
39+
F7
40+
R90
41+
F11""",
42+
"expected": ["25", "286"],
43+
}
44+
45+
test = "real"
46+
input_file = os.path.join(
47+
os.path.dirname(__file__),
48+
"Inputs",
49+
os.path.basename(__file__).replace(".py", ".txt"),
50+
)
51+
test_data[test] = {
52+
"input": open(input_file, "r+").read(),
53+
"expected": ["820", "66614"],
54+
}
55+
56+
57+
# -------------------------------- Control program execution ------------------------- #
58+
59+
case_to_test = "real"
60+
part_to_test = 2
61+
62+
# -------------------------------- Initialize some variables ------------------------- #
63+
64+
puzzle_input = test_data[case_to_test]["input"]
65+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
66+
puzzle_actual_result = "Unknown"
67+
68+
69+
# -------------------------------- Actual code execution ----------------------------- #
70+
71+
relative_directions = {
72+
"L": 1j,
73+
"R": -1j,
74+
"F": 1,
75+
"B": -1,
76+
}
77+
78+
79+
if part_to_test == 1:
80+
position = 0
81+
direction = east
82+
for string in puzzle_input.split("\n"):
83+
if string[0] in ("N", "S", "E", "W"):
84+
position += text_to_direction[string[0]] * int(string[1:])
85+
elif string[0] == "F":
86+
position += direction * int(string[1:])
87+
elif string[0] in ("L", "R"):
88+
angle = int(string[1:]) % 360
89+
if angle == 0:
90+
pass
91+
elif angle == 90:
92+
direction *= relative_directions[string[0]]
93+
elif angle == 180:
94+
direction *= -1
95+
elif angle == 270:
96+
direction *= -1 * relative_directions[string[0]]
97+
98+
puzzle_actual_result = int(abs(position.real) + abs(position.imag))
99+
100+
101+
else:
102+
ship_pos = 0
103+
wpt_rel_pos = 10 + 1j
104+
for string in puzzle_input.split("\n"):
105+
if string[0] in ("N", "S", "E", "W"):
106+
wpt_rel_pos += text_to_direction[string[0]] * int(string[1:])
107+
elif string[0] == "F":
108+
delta = wpt_rel_pos * int(string[1:])
109+
ship_pos += delta
110+
elif string[0] in ("L", "R"):
111+
angle = int(string[1:]) % 360
112+
if angle == 0:
113+
pass
114+
elif angle == 90:
115+
wpt_rel_pos *= relative_directions[string[0]]
116+
elif angle == 180:
117+
wpt_rel_pos *= -1
118+
elif angle == 270:
119+
wpt_rel_pos *= -1 * relative_directions[string[0]]
120+
121+
puzzle_actual_result = int(abs(ship_pos.real) + abs(ship_pos.imag))
122+
123+
124+
# -------------------------------- Outputs / results --------------------------------- #
125+
126+
print("Case :", case_to_test, "- Part", part_to_test)
127+
print("Expected result : " + str(puzzle_expected_result))
128+
print("Actual result : " + str(puzzle_actual_result))
129+
# Date created: 2020-12-12 07:21:36.624800
130+
# Part 1: 2020-12-12 07:28:36
131+
# Part 2: 2020-12-12 07:34:51

2020/13-Shuttle Search.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, dot, assembly, re, itertools, math
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """939
38+
7,13,x,x,59,x,31,19""",
39+
"expected": ["295", "1068781"],
40+
}
41+
42+
test = "real"
43+
input_file = os.path.join(
44+
os.path.dirname(__file__),
45+
"Inputs",
46+
os.path.basename(__file__).replace(".py", ".txt"),
47+
)
48+
test_data[test] = {
49+
"input": open(input_file, "r+").read(),
50+
"expected": ["2382", "906332393333683"],
51+
}
52+
53+
54+
# -------------------------------- Control program execution ------------------------- #
55+
56+
case_to_test = "real"
57+
part_to_test = 2
58+
59+
# -------------------------------- Initialize some variables ------------------------- #
60+
61+
puzzle_input = test_data[case_to_test]["input"]
62+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
63+
puzzle_actual_result = "Unknown"
64+
65+
66+
# -------------------------------- Actual code execution ----------------------------- #
67+
68+
if part_to_test == 1:
69+
data = puzzle_input.split("\n")
70+
curr_time = int(data[0])
71+
busses = ints(data[1])
72+
next_time = curr_time * 10
73+
74+
for bus in busses:
75+
next_round = bus - curr_time % bus + curr_time
76+
print(next_round, bus, curr_time)
77+
if next_round < next_time:
78+
next_time = next_round
79+
next_bus = bus
80+
81+
puzzle_actual_result = (next_time - curr_time) * next_bus
82+
83+
84+
else:
85+
data = puzzle_input.split("\n")
86+
busses = data[1].split(",")
87+
bus_offsets = {}
88+
89+
i = 0
90+
for bus in busses:
91+
if bus == "x":
92+
pass
93+
else:
94+
bus_offsets[int(bus)] = i
95+
i += 1
96+
97+
timestamp = 0
98+
99+
# I first solved this thanks to a diophantine equation solvers found on Internet
100+
101+
# Then I looked at the solutions megathread to learn more
102+
# This is the proper algorithm that works in a feasible time
103+
# It's called the Chinese remainder theorem
104+
# See https://crypto.stanford.edu/pbc/notes/numbertheory/crt.html
105+
prod_modulos = math.prod(bus_offsets.keys())
106+
for bus, offset in bus_offsets.items():
107+
timestamp += -offset * (prod_modulos // bus) * pow(prod_modulos // bus, -1, bus)
108+
timestamp %= prod_modulos
109+
110+
# The below algorithm is the brute-force version: very slow but should work
111+
# Since timestamp is calculated above, this won't do anything
112+
# To make it run, uncomment the below line
113+
# timestamp = 0
114+
115+
min_bus = min(bus_offsets.keys())
116+
while True:
117+
if all([(timestamp + bus_offsets[bus]) % bus == 0 for bus in bus_offsets]):
118+
puzzle_actual_result = timestamp
119+
break
120+
else:
121+
timestamp += min_bus
122+
123+
124+
# -------------------------------- Outputs / results --------------------------------- #
125+
126+
print("Case :", case_to_test, "- Part", part_to_test)
127+
print("Expected result : " + str(puzzle_expected_result))
128+
print("Actual result : " + str(puzzle_actual_result))
129+
# Date created: 2020-12-13 06:25:25.641468
130+
# Part 1: 2020-12-13 06:31:06
131+
# Part 2: 2020-12-13 07:12:10

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy