Skip to content

Commit 5bd2006

Browse files
committed
Added days 2019-16 and 2019-17
1 parent 2ebcb1d commit 5bd2006

File tree

2 files changed

+254
-0
lines changed

2 files changed

+254
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding
3+
4+
from complex_utils import *
5+
6+
test_data = {}
7+
8+
test = 1
9+
test_data[test] = {
10+
"input": """12345678""",
11+
"expected": ["01029498 after 4 phases", "Unknown"],
12+
}
13+
14+
test += 1
15+
test_data[test] = {
16+
"input": """80871224585914546619083218645595""",
17+
"expected": ["24176176", "Unknown"],
18+
}
19+
20+
test += 1
21+
test_data[test] = {
22+
"input": """03036732577212944063491565474664""",
23+
"expected": ["Unknown", "84462026"],
24+
}
25+
26+
test = "real"
27+
input_file = os.path.join(
28+
os.path.dirname(__file__),
29+
"Inputs",
30+
os.path.basename(__file__).replace(".py", ".txt"),
31+
)
32+
test_data[test] = {
33+
"input": open(input_file, "r+").read().strip(),
34+
"expected": ["27229269", "26857164"],
35+
}
36+
37+
# -------------------------------- Control program execution ------------------------- #
38+
39+
case_to_test = "real"
40+
part_to_test = 2
41+
42+
# -------------------------------- Initialize some variables ------------------------- #
43+
44+
puzzle_input = test_data[case_to_test]["input"]
45+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
46+
puzzle_actual_result = "Unknown"
47+
48+
49+
# -------------------------------- Actual code execution ----------------------------- #
50+
51+
base_pattern = [0, 1, 0, -1]
52+
53+
if part_to_test == 1:
54+
signal = [int(x) for x in puzzle_input]
55+
56+
for phase in range(100):
57+
output = [0] * len(signal)
58+
for i in range(len(signal)):
59+
pattern = []
60+
for j in range(len(base_pattern)):
61+
pattern += [base_pattern[j]] * (i + 1)
62+
63+
while len(pattern) < len(signal) + 1:
64+
pattern += pattern
65+
del pattern[0]
66+
67+
output[i] = sum([pattern[j] * signal[j] for j in range(len(signal))])
68+
output[i] = abs(output[i]) % 10
69+
signal = output[:]
70+
71+
puzzle_actual_result = "".join(map(str, output[:8]))
72+
73+
74+
else:
75+
# The signal's length is 650 * 10000 = 6500000
76+
# The first 7 digits of the input are 5978261
77+
# Therefore, the first number to be calculated will ignore the first 5978261 of the input
78+
# Also, since 5978261 < 6500000 < 5978261*2, the part with '0, -1' in the pattern is after the signal's length
79+
# Therefore it can be ignored
80+
signal = [int(x) for x in puzzle_input] * 10 ** 4
81+
start = int(puzzle_input[:7])
82+
signal = signal[start:]
83+
84+
sum_signal = sum([int(x) for x in puzzle_input]) % 10
85+
len_signal = len(puzzle_input)
86+
87+
output = [0] * len(signal)
88+
89+
for phase in range(100):
90+
output[-1] = signal[-1]
91+
for i in range(1, len(signal)):
92+
output[-i - 1] = output[-i] + signal[-i - 1]
93+
94+
signal = [x % 10 for x in output]
95+
96+
puzzle_actual_result = "".join(map(str, signal[:8]))
97+
98+
99+
# -------------------------------- Outputs / results --------------------------------- #
100+
101+
print("Expected result : " + str(puzzle_expected_result))
102+
print("Actual result : " + str(puzzle_actual_result))

2019/17-Set and Forget.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding, IntCode
3+
4+
from complex_utils import *
5+
6+
test_data = {}
7+
8+
test = "real"
9+
input_file = os.path.join(
10+
os.path.dirname(__file__),
11+
"Inputs",
12+
os.path.basename(__file__).replace(".py", ".txt"),
13+
)
14+
test_data[test] = {
15+
"input": open(input_file, "r+").read().strip(),
16+
"expected": ["5068", "1415975"],
17+
}
18+
19+
# -------------------------------- Control program execution ------------------------- #
20+
21+
case_to_test = "real"
22+
part_to_test = 2
23+
verbose_level = 0
24+
25+
# -------------------------------- Initialize some variables ------------------------- #
26+
27+
puzzle_input = test_data[case_to_test]["input"]
28+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
29+
puzzle_actual_result = "Unknown"
30+
31+
32+
# -------------------------------- Actual code execution ----------------------------- #
33+
34+
position = 0
35+
36+
droid = IntCode.IntCode(puzzle_input)
37+
droid.run()
38+
grid = []
39+
for output in droid.outputs:
40+
if chr(output) == "#":
41+
grid.append(position)
42+
elif chr(output) in ["^", "v", ">", "<"]:
43+
droid_pos = [position, accent_to_dir[chr(output)]]
44+
45+
if chr(output) == "\n":
46+
position = j * (position.imag - 1)
47+
else:
48+
position += 1
49+
50+
51+
if part_to_test == 1:
52+
alignment_parameter = 0
53+
for x in range(1, int(max_real(grid))):
54+
for y in range(int(min_imag(grid)), -1):
55+
if x + y * j in grid:
56+
if all([x + y * j + dir in grid for dir in directions_straight]):
57+
alignment_parameter += x * -y
58+
59+
puzzle_actual_result = alignment_parameter
60+
61+
62+
else:
63+
steps = []
64+
visited = []
65+
66+
# Find the path, in the long form (L,12,R,8,.....)
67+
while True:
68+
position, direction = droid_pos
69+
visited.append(position)
70+
if position + direction in grid:
71+
steps[-1] += 1
72+
droid_pos[0] += droid_pos[1]
73+
else:
74+
option = [
75+
(turn[0].upper(), direction * relative_directions[turn])
76+
for turn in relative_directions
77+
if position + direction * relative_directions[turn] in grid
78+
if position + direction * relative_directions[turn] not in visited
79+
]
80+
if len(option) > 1:
81+
print("error")
82+
raise Exception(position, direction, option)
83+
84+
if option:
85+
option = option[0]
86+
steps += [option[0], 1]
87+
droid_pos[1] = option[1]
88+
droid_pos[0] += droid_pos[1]
89+
else:
90+
break
91+
92+
steps = list(map(str, steps))
93+
steps_inline = ",".join(steps)
94+
95+
# Shorten the path
96+
subprograms = []
97+
nb_to_letter = {0: "A", 1: "B", 2: "C"}
98+
99+
offset = 0
100+
for i in range(3):
101+
while len(subprograms) == i:
102+
nb_steps = min(20, len(steps) - offset)
103+
subprogram = steps[offset : offset + nb_steps]
104+
subprogram_inline = ",".join(subprogram)
105+
106+
# The limits of 3 is arbitrary
107+
while (
108+
steps_inline.count(subprogram_inline) < 3 or len(subprogram_inline) > 20
109+
):
110+
# Shorten subprogram for test
111+
if len(subprogram) <= 2:
112+
break
113+
else:
114+
if subprogram[-1] in ("A", "B", "C"):
115+
del subprogram[-1]
116+
else:
117+
del subprogram[-2:]
118+
119+
subprogram_inline = ",".join(subprogram)
120+
121+
# Found one!
122+
if steps_inline.count(subprogram_inline) >= 3 and len(subprogram) > 2:
123+
subprograms.append(subprogram_inline)
124+
steps_inline = steps_inline.replace(subprogram_inline, nb_to_letter[i])
125+
steps = steps_inline.split(",")
126+
else:
127+
if steps[offset] in ["A", "B", "C"]:
128+
offset += 1
129+
else:
130+
offset += 2
131+
offset = 0
132+
133+
# Now send all that to the robot
134+
droid.instructions[0] = 2
135+
inputs = (
136+
steps_inline + "\n" + "\n".join(subprograms) + "\nn\n"
137+
) # the last n is for the video
138+
for letter in inputs:
139+
droid.add_input(ord(letter))
140+
droid.restart()
141+
droid.run()
142+
143+
puzzle_actual_result = droid.outputs.pop()
144+
if verbose_level:
145+
for output in droid.outputs:
146+
print(chr(output), end="")
147+
148+
149+
# -------------------------------- Outputs / results --------------------------------- #
150+
151+
print("Expected result : " + str(puzzle_expected_result))
152+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)