Skip to content

Commit 13768a8

Browse files
committed
Added days 2019-21, 2019-22 and 2019-23
1 parent 3a6c96c commit 13768a8

File tree

3 files changed

+336
-0
lines changed

3 files changed

+336
-0
lines changed

2019/21-Springdroid Adventure.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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(),
16+
"expected": ["19352638", "1141251258"],
17+
}
18+
19+
# -------------------------------- Control program execution ------------------------- #
20+
21+
case_to_test = "real"
22+
part_to_test = 2
23+
24+
# -------------------------------- Initialize some variables ------------------------- #
25+
26+
puzzle_input = test_data[case_to_test]["input"]
27+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
28+
puzzle_actual_result = "Unknown"
29+
30+
31+
# -------------------------------- Actual code execution ----------------------------- #
32+
33+
34+
def add_ascii_input(self, value):
35+
self.add_input([ord(x) for x in value])
36+
37+
38+
IntCode.IntCode.add_ascii_input = add_ascii_input
39+
40+
41+
if part_to_test == 1:
42+
instructions = [
43+
"NOT A T",
44+
"NOT B J",
45+
"OR T J",
46+
"NOT C T",
47+
"OR T J",
48+
"AND D J",
49+
"WALK",
50+
]
51+
else:
52+
instructions = [
53+
"NOT A T",
54+
"NOT B J",
55+
"OR T J",
56+
"NOT C T",
57+
"OR T J",
58+
"AND D J",
59+
"NOT H T",
60+
"NOT T T",
61+
"OR E T",
62+
"AND T J",
63+
"RUN",
64+
]
65+
66+
67+
droid = IntCode.IntCode(puzzle_input)
68+
69+
70+
for instruction in instructions:
71+
droid.add_ascii_input(instruction + "\n")
72+
73+
droid.run()
74+
for output in droid.outputs:
75+
if output > 256:
76+
puzzle_actual_result = output
77+
else:
78+
print(chr(output), end="")
79+
80+
81+
# -------------------------------- Outputs / results --------------------------------- #
82+
83+
print("Expected result : " + str(puzzle_expected_result))
84+
print("Actual result : " + str(puzzle_actual_result))

2019/22-Slam Shuffle.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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": (
11+
"""deal into new stack
12+
cut -2
13+
deal with increment 7
14+
cut 8
15+
cut -4
16+
deal with increment 7
17+
cut 3
18+
deal with increment 9
19+
deal with increment 3
20+
cut -1""",
21+
10,
22+
),
23+
"expected": ["9 2 5 8 1 4 7 0 3 6", "9 2 5 8 1 4 7 0 3 6"],
24+
}
25+
26+
test += 1
27+
test_data[test] = {
28+
"input": (
29+
"""cut 6
30+
deal with increment 7
31+
deal into new stack""",
32+
10,
33+
),
34+
"expected": ["3 0 7 4 1 8 5 2 9 6", "3 0 7 4 1 8 5 2 9 6"],
35+
}
36+
37+
test += 1
38+
test_data[test] = {
39+
"input": (
40+
"""deal with increment 7
41+
cut 3
42+
deal into new stack""",
43+
10,
44+
),
45+
"expected": ["Unknown", "Unknown"],
46+
}
47+
48+
test = "real"
49+
input_file = os.path.join(
50+
os.path.dirname(__file__),
51+
"Inputs",
52+
os.path.basename(__file__).replace(".py", ".txt"),
53+
)
54+
test_data[test] = {
55+
"input": (open(input_file, "r+").read(), 119315717514047),
56+
"expected": ["2480", "62416301438548"],
57+
}
58+
59+
# -------------------------------- Control program execution ------------------------- #
60+
61+
case_to_test = "real"
62+
part_to_test = 2
63+
64+
# -------------------------------- Initialize some variables ------------------------- #
65+
66+
puzzle_input = test_data[case_to_test]["input"]
67+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
68+
puzzle_actual_result = "Unknown"
69+
70+
71+
# -------------------------------- Actual code execution ----------------------------- #
72+
73+
nb_cards = puzzle_input[1]
74+
75+
if part_to_test == 1:
76+
deck = [x for x in range(nb_cards)]
77+
78+
for string in puzzle_input[0].split("\n"):
79+
if string == "":
80+
continue
81+
if string == "deal into new stack":
82+
deck = deck[::-1]
83+
elif string[0:4] == "deal":
84+
number = int(string.split(" ")[-1])
85+
new_deck = [0] * nb_cards
86+
for i in range(0, nb_cards * number, number):
87+
new_deck[i % nb_cards] = deck[i // number]
88+
deck = new_deck[:]
89+
else:
90+
number = int(string.split(" ")[-1])
91+
deck = deck[number:] + deck[:number]
92+
93+
# print (string, deck)
94+
95+
print(deck)
96+
puzzle_actual_result = deck.index(2019)
97+
98+
99+
else:
100+
nb_shuffles = 101741582076661
101+
# Then the goal is to find a, b and x so that after 1 deal means:
102+
# a*initial_position + b = [output] % nb_cards
103+
# a and b can be found by analyzing the movements done
104+
a, b = 1, 0
105+
for string in puzzle_input[0].split("\n")[::-1]:
106+
if string == "":
107+
continue
108+
if string == "deal into new stack":
109+
a *= -1
110+
b *= -1
111+
b -= 1 # Not sure why it's needed...
112+
elif string[0:4] == "deal":
113+
number = int(string.split(" ")[-1])
114+
a *= pow(number, -1, nb_cards)
115+
b *= pow(number, -1, nb_cards)
116+
else:
117+
number = int(string.split(" ")[-1])
118+
b += number
119+
120+
a, b = a % nb_cards, b % nb_cards
121+
122+
# This function applies the shuffles nb_shuffles times
123+
# This is the equation a^nb_shuffles * position + sum[a^k * b for k in range(0, nb_shuffles-1)] % nb_cards
124+
# This translated to a^nb_shuffles * position + b * (1-a^nb_shuffles) / (1-a) % nb_cards
125+
126+
def shuffles(a, b, position, nb_shuffles, nb_cards):
127+
value = pow(a, nb_shuffles, nb_cards) * position
128+
value += b * (1 - pow(a, nb_shuffles, nb_cards)) * pow(1 - a, -1, nb_cards)
129+
value %= nb_cards
130+
return value
131+
132+
puzzle_actual_result = shuffles(a, b, 2020, nb_shuffles, nb_cards)
133+
134+
135+
# -------------------------------- Outputs / results --------------------------------- #
136+
137+
print("Expected result : " + str(puzzle_expected_result))
138+
print("Actual result : " + str(puzzle_actual_result))

2019/23-Category Six.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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(),
22+
"expected": ["23266", "17493"],
23+
}
24+
25+
# -------------------------------- Control program execution ------------------------- #
26+
27+
case_to_test = "real"
28+
part_to_test = 2
29+
verbose_level = 0
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+
computers = [0] * 50
41+
queue = []
42+
nat_queue = []
43+
nat_y_values_sent = []
44+
for i in range(len(computers)):
45+
computers[i] = IntCode.IntCode(puzzle_input, i)
46+
computers[i].add_input(i)
47+
computers[i].reception_duration = 0
48+
49+
50+
total_outputs = 0
51+
while puzzle_actual_result == "Unknown":
52+
for computer in computers:
53+
computer.run(1)
54+
55+
if computer.outputs:
56+
computer.reception_duration = 0
57+
58+
if len(computer.outputs) == 3:
59+
total_outputs += len(computer.outputs)
60+
queue += [computer.outputs]
61+
computer.outputs = []
62+
63+
if verbose_level >= 1 and queue:
64+
print("Queue contains", queue)
65+
print("# outputs from computers", total_outputs)
66+
67+
while queue:
68+
packet = queue.pop(0)
69+
if packet[0] == 255 and part_to_test == 1:
70+
puzzle_actual_result = packet[2]
71+
break
72+
elif packet[0] == 255:
73+
nat_queue = packet[1:]
74+
else:
75+
computers[packet[0]].add_input(packet[1:])
76+
computers[packet[0]].restart()
77+
78+
for computer in computers:
79+
if computer.state == "Paused":
80+
computer.reception_duration += 1
81+
82+
senders = [
83+
computer.reference for computer in computers if computer.reception_duration < 5
84+
]
85+
inputs = [computer.reference for computer in computers if len(computer.inputs) != 0]
86+
87+
if (
88+
all(
89+
[
90+
computer.reception_duration > 5 and len(computer.inputs) == 0
91+
for computer in computers
92+
]
93+
)
94+
and nat_queue
95+
):
96+
computers[0].add_input(nat_queue)
97+
y_sent = nat_queue[-1]
98+
99+
print("NAT sends", nat_queue, "- Previous Y values sent:", nat_y_values_sent)
100+
nat_queue = []
101+
if nat_y_values_sent and y_sent == nat_y_values_sent[-1]:
102+
puzzle_actual_result = y_sent
103+
nat_y_values_sent.append(y_sent)
104+
else:
105+
for computer in computers:
106+
if computer.state == "Paused":
107+
computer.add_input(-1)
108+
computer.restart()
109+
110+
111+
# -------------------------------- Outputs / results --------------------------------- #
112+
113+
print("Expected result : " + str(puzzle_expected_result))
114+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)