Skip to content

Commit 7901443

Browse files
committed
Added days 2019-11, 2019-12 and 2019-13
1 parent 3b45a66 commit 7901443

File tree

3 files changed

+331
-0
lines changed

3 files changed

+331
-0
lines changed

2019/11-Space Police.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding, IntCode
3+
4+
from complex_utils import *
5+
6+
test_data = {}
7+
8+
test = 1
9+
test_data[test] = {
10+
"input": """""",
11+
"expected": ["Unknown", "Unknown"],
12+
}
13+
14+
test = "real"
15+
input_file = os.path.join(
16+
os.path.dirname(__file__),
17+
"Inputs",
18+
os.path.basename(__file__).replace(".py", ".txt"),
19+
)
20+
test_data[test] = {
21+
"input": open(input_file, "r+").read().strip(),
22+
"expected": ["1934", "RKURGKGK"],
23+
}
24+
25+
# -------------------------------- Control program execution ------------------------- #
26+
27+
case_to_test = "real"
28+
part_to_test = 2
29+
30+
# -------------------------------- Initialize some variables ------------------------- #
31+
32+
puzzle_input = test_data[case_to_test]["input"]
33+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
34+
puzzle_actual_result = "Unknown"
35+
36+
37+
# -------------------------------- Actual code execution ----------------------------- #
38+
39+
position = 0
40+
direction = north
41+
if part_to_test == 1:
42+
panels = {0: 0}
43+
else:
44+
panels = {0: 1}
45+
46+
47+
computer = IntCode.IntCode(puzzle_input)
48+
49+
while computer.state != "Stopped":
50+
if position in panels:
51+
computer.add_input(panels[position])
52+
else:
53+
computer.add_input(0)
54+
computer.restart()
55+
computer.run()
56+
color, dir = computer.outputs[-2:]
57+
panels[position] = color
58+
direction *= (
59+
relative_directions["left"] if dir == 0 else relative_directions["right"]
60+
)
61+
position += direction
62+
63+
if part_to_test == 1:
64+
puzzle_actual_result = len(panels)
65+
else:
66+
grid = pathfinding.Graph()
67+
grid.vertices = {x: "X" if panels[x] == 1 else " " for x in panels}
68+
puzzle_actual_result = "\n" + grid.vertices_to_grid(wall=" ")
69+
70+
71+
# -------------------------------- Outputs / results --------------------------------- #
72+
73+
print("Expected result : " + str(puzzle_expected_result))
74+
print("Actual result : " + str(puzzle_actual_result))

2019/12-The N-Body Problem.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding, re, math, copy
3+
4+
from complex_utils import *
5+
6+
test_data = {}
7+
8+
test = 1
9+
test_data[test] = {
10+
"input": """<x=-1, y=0, z=2>
11+
<x=2, y=-10, z=-7>
12+
<x=4, y=-8, z=8>
13+
<x=3, y=5, z=-1>""",
14+
"expected": ["179 after 10 steps", "2772"],
15+
}
16+
17+
test = "real"
18+
input_file = os.path.join(
19+
os.path.dirname(__file__),
20+
"Inputs",
21+
os.path.basename(__file__).replace(".py", ".txt"),
22+
)
23+
test_data[test] = {
24+
"input": open(input_file, "r+").read().strip(),
25+
"expected": ["12773", "306798770391636"],
26+
}
27+
28+
# -------------------------------- Control program execution ------------------------- #
29+
30+
case_to_test = "real"
31+
part_to_test = 2
32+
33+
# -------------------------------- Initialize some variables ------------------------- #
34+
35+
puzzle_input = test_data[case_to_test]["input"]
36+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
37+
puzzle_actual_result = "Unknown"
38+
39+
40+
# -------------------------------- Actual code execution ----------------------------- #
41+
42+
stars = []
43+
for string in puzzle_input.split("\n"):
44+
x, y, z = map(int, re.findall("[-0-9]{1,}", string))
45+
stars.append([x, y, z, 0, 0, 0])
46+
47+
if part_to_test == 1:
48+
for step in range(1000):
49+
for star_id in range(len(stars)):
50+
for coord in range(3):
51+
stars[star_id][3 + coord] += sum(
52+
[1 for other in stars if stars[star_id][coord] < other[coord]]
53+
)
54+
stars[star_id][3 + coord] += sum(
55+
[-1 for other in stars if stars[star_id][coord] > other[coord]]
56+
)
57+
58+
for star_id in range(len(stars)):
59+
for coord in range(3):
60+
stars[star_id][coord] += stars[star_id][3 + coord]
61+
62+
energy = sum(
63+
[
64+
(abs(x) + abs(y) + abs(z)) * (abs(dx) + abs(dy) + abs(dz))
65+
for (x, y, z, dx, dy, dz) in stars
66+
]
67+
)
68+
puzzle_actual_result = energy
69+
70+
else:
71+
72+
# 1st trick: For this part, do the computation on each axis independently (since they're independent)
73+
# 2nd trick: the function state => next state is invertible, so any repetition will go through the initial state (we can't have 3>0>1>0>1>0>1, it has to be something like 3>0>1>3>0>1)
74+
repeats = []
75+
for coord in range(3):
76+
step = -1
77+
repeat = 0
78+
stars_pos_vel = [
79+
[stars[star_id][coord], stars[star_id][coord + 3]]
80+
for star_id in range(len(stars))
81+
]
82+
init_stars_pos_vel = [
83+
[stars[star_id][coord], stars[star_id][coord + 3]]
84+
for star_id in range(len(stars))
85+
]
86+
87+
while repeat == 0: # and step < 20:
88+
step += 1
89+
for star_id in range(len(stars)):
90+
stars_pos_vel[star_id][1] += sum(
91+
[
92+
1
93+
for other in stars_pos_vel
94+
if stars_pos_vel[star_id][0] < other[0]
95+
]
96+
)
97+
stars_pos_vel[star_id][1] -= sum(
98+
[
99+
1
100+
for other in stars_pos_vel
101+
if stars_pos_vel[star_id][0] > other[0]
102+
]
103+
)
104+
105+
for star_id in range(len(stars)):
106+
stars_pos_vel[star_id][0] += stars_pos_vel[star_id][1]
107+
108+
if stars_pos_vel == init_stars_pos_vel:
109+
repeat = step + 1
110+
111+
repeats.append(repeat)
112+
113+
lcm = repeats[0]
114+
for val in repeats:
115+
lcm = lcm * val // math.gcd(lcm, val)
116+
117+
puzzle_actual_result = lcm
118+
119+
# -------------------------------- Outputs / results --------------------------------- #
120+
121+
print("Expected result : " + str(puzzle_expected_result))
122+
print("Actual result : " + str(puzzle_actual_result))

2019/13-Care Package.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, pathfinding, IntCode
3+
4+
from complex_utils import *
5+
6+
test_data = {}
7+
8+
test = 1
9+
test_data[test] = {
10+
"input": """""",
11+
"expected": ["Unknown", "Unknown"],
12+
}
13+
14+
test = "real"
15+
input_file = os.path.join(
16+
os.path.dirname(__file__),
17+
"Inputs",
18+
os.path.basename(__file__).replace(".py", ".txt"),
19+
)
20+
test_data[test] = {
21+
"input": open(input_file, "r+").read().strip(),
22+
"expected": ["462", "23981"],
23+
}
24+
25+
# -------------------------------- Control program execution ------------------------- #
26+
27+
case_to_test = "real"
28+
part_to_test = 2
29+
verbose_level = 1
30+
31+
# -------------------------------- Initialize some variables ------------------------- #
32+
33+
puzzle_input = test_data[case_to_test]["input"]
34+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
35+
puzzle_actual_result = "Unknown"
36+
37+
38+
# -------------------------------- Actual code execution ----------------------------- #
39+
40+
tiles = {0: " ", 1: "#", 2: "ø", 3: "_", 4: "o"}
41+
grid = pathfinding.Graph()
42+
computer = IntCode.IntCode(puzzle_input)
43+
44+
if part_to_test == 1:
45+
computer.run()
46+
grid.vertices = {}
47+
for i in range(len(computer.outputs) // 3):
48+
position = SuperComplex(
49+
computer.outputs[i * 3] - j * computer.outputs[i * 3 + 1]
50+
)
51+
grid.vertices[position] = tiles[computer.outputs[i * 3 + 2]]
52+
53+
puzzle_actual_result = sum([1 for val in grid.vertices.values() if val == "ø"])
54+
55+
56+
else:
57+
computer.instructions[0] = 2
58+
blocks_left = 1
59+
score = 0
60+
61+
vertices = {}
62+
63+
while blocks_left > 0 and computer.state != "Failure":
64+
computer.run()
65+
66+
# Check if we can still play
67+
blocks_left = 0
68+
ball_position = 0
69+
paddle_position = 0
70+
for i in range(len(computer.outputs) // 3):
71+
72+
vertices[
73+
computer.outputs[i * 3] - j * computer.outputs[i * 3 + 1]
74+
] = computer.outputs[i * 3 + 2]
75+
# The ball has not fallen
76+
if computer.outputs[i * 3 + 2] == 4:
77+
ball_position = (
78+
computer.outputs[i * 3] - j * computer.outputs[i * 3 + 1]
79+
)
80+
if ball_position.imag < -21:
81+
print("Failed")
82+
computer.state = "Failure"
83+
break
84+
# Check the score
85+
elif computer.outputs[i * 3] == -1 and computer.outputs[i * 3 + 1] == 0:
86+
score = computer.outputs[i * 3 + 2]
87+
88+
# Store the paddle position
89+
elif computer.outputs[i * 3 + 2] == 3:
90+
paddle_position = (
91+
computer.outputs[i * 3] - j * computer.outputs[i * 3 + 1]
92+
)
93+
94+
# There are still blocks to break
95+
blocks_left = len([x for x in vertices if vertices[x] == 2])
96+
97+
# Move paddle
98+
if paddle_position.real < ball_position.real:
99+
joystick = 1
100+
elif paddle_position.real > ball_position.real:
101+
joystick = -1
102+
else:
103+
joystick = 0
104+
computer.add_input(joystick)
105+
106+
if verbose_level >= 2:
107+
print(
108+
"Movements",
109+
len(computer.all_inputs),
110+
" - Score",
111+
score,
112+
" - Blocks left",
113+
blocks_left,
114+
" - Ball",
115+
ball_position,
116+
" - Paddle",
117+
paddle_position,
118+
" - Direction",
119+
joystick,
120+
)
121+
122+
# 'Restart' the computer to process the input
123+
computer.restart()
124+
125+
# Outputs the grid (just for fun)
126+
grid.vertices = {x: tiles.get(vertices[x], vertices[x]) for x in vertices}
127+
print(grid.vertices_to_grid())
128+
129+
puzzle_actual_result = score
130+
131+
132+
# -------------------------------- Outputs / results --------------------------------- #
133+
134+
print("Expected result : " + str(puzzle_expected_result))
135+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)