Skip to content

Commit 3c83d1f

Browse files
committed
Added days 2019-01 and 2019-02
1 parent b28bff8 commit 3c83d1f

4 files changed

Lines changed: 931 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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": """1969""",
11+
"expected": ["2", "966"],
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": ["3360301", "5037595"],
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+
if part_to_test == 1:
40+
total = 0
41+
for string in puzzle_input.split("\n"):
42+
val = int(string)
43+
val = val // 3 - 2
44+
total += val
45+
46+
puzzle_actual_result = total
47+
48+
49+
else:
50+
total = 0
51+
for string in puzzle_input.split("\n"):
52+
val = int(string)
53+
val = val // 3 - 2
54+
while val > 0:
55+
total += val
56+
val = val // 3 - 2
57+
58+
puzzle_actual_result = total
59+
60+
61+
# -------------------------------- Outputs / results --------------------------------- #
62+
63+
print("Expected result : " + str(puzzle_expected_result))
64+
print("Actual result : " + str(puzzle_actual_result))

2019/02-1202 Program Alarm.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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": """1,9,10,3,2,3,11,0,99,30,40,50""",
11+
"expected": ["3500,9,10,70,2,3,11,0,99,30,40,50", "Unknown"],
12+
}
13+
14+
test += 1
15+
test_data[test] = {
16+
"input": """1,0,0,0,99""",
17+
"expected": ["2,0,0,0,99", "Unknown"],
18+
}
19+
20+
test += 1
21+
test_data[test] = {
22+
"input": """2,4,4,5,99,0""",
23+
"expected": ["2,4,4,5,99,9801", "Unknown"],
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": ["6327510", "4112"],
35+
}
36+
37+
# -------------------------------- Control program execution ------------------------- #
38+
39+
case_to_test = "real"
40+
part_to_test = 2
41+
verbose_level = 2
42+
43+
# -------------------------------- Initialize some variables ------------------------- #
44+
45+
puzzle_input = test_data[case_to_test]["input"]
46+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
47+
puzzle_actual_result = "Unknown"
48+
49+
50+
# -------------------------------- Actual code execution ----------------------------- #
51+
52+
53+
class IntCode:
54+
instructions = []
55+
pointer = 0
56+
state = "Running"
57+
58+
def __init__(self, instructions):
59+
self.instructions = list(map(int, instructions.split(",")))
60+
61+
def reset(self, instructions):
62+
self.instructions = list(map(int, instructions.split(",")))
63+
self.pointer = 0
64+
self.state = "Running"
65+
66+
def get_instruction(self):
67+
if self.instructions[self.pointer] in [1, 2]:
68+
return self.instructions[self.pointer : self.pointer + 4]
69+
else:
70+
return [self.instructions[self.pointer]]
71+
72+
def op_1(self, instr):
73+
self.instructions[instr[3]] = (
74+
self.instructions[instr[1]] + self.instructions[instr[2]]
75+
)
76+
self.pointer += 4
77+
self.state = "Running"
78+
79+
def op_2(self, instr):
80+
self.instructions[instr[3]] = (
81+
self.instructions[instr[1]] * self.instructions[instr[2]]
82+
)
83+
self.pointer += 4
84+
self.state = "Running"
85+
86+
def op_99(self, instr):
87+
self.pointer += 1
88+
self.state = "Stopped"
89+
90+
def run(self):
91+
while self.state == "Running":
92+
current_instruction = self.get_instruction()
93+
getattr(self, "op_" + str(current_instruction[0]))(current_instruction)
94+
if verbose_level >= 3:
95+
print("Pointer after execution:", self.pointer)
96+
print("Instructions:", self.export())
97+
98+
def export(self):
99+
return ",".join(map(str, self.instructions))
100+
101+
102+
if part_to_test == 1:
103+
computer = IntCode(puzzle_input)
104+
if case_to_test == "real":
105+
computer.instructions[1] = 12
106+
computer.instructions[2] = 2
107+
computer.run()
108+
puzzle_actual_result = computer.instructions[0]
109+
110+
111+
else:
112+
computer = IntCode(puzzle_input)
113+
for noon in range(100):
114+
for verb in range(100):
115+
computer.reset(puzzle_input)
116+
computer.instructions[1] = noon
117+
computer.instructions[2] = verb
118+
computer.run()
119+
if computer.instructions[0] == 19690720:
120+
puzzle_actual_result = 100 * noon + verb
121+
break
122+
123+
if puzzle_actual_result != "Unknown":
124+
break
125+
126+
127+
# -------------------------------- Outputs / results --------------------------------- #
128+
129+
print("Expected result : " + str(puzzle_expected_result))
130+
print("Actual result : " + str(puzzle_actual_result))

2019/complex_utils.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
"""
2+
Small library for complex numbers
3+
"""
4+
from math import sqrt
5+
6+
7+
class ReturnTypeWrapper(type):
8+
def __new__(mcs, name, bases, dct):
9+
cls = type.__new__(mcs, name, bases, dct)
10+
for attr, obj in cls.wrapped_base.__dict__.items():
11+
# skip 'member descriptor's and overridden methods
12+
if type(obj) == type(complex.real) or attr in dct:
13+
continue
14+
if getattr(obj, "__objclass__", None) is cls.wrapped_base:
15+
setattr(cls, attr, cls.return_wrapper(obj))
16+
return cls
17+
18+
def return_wrapper(cls, obj):
19+
def convert(value):
20+
return cls(value) if type(value) is cls.wrapped_base else value
21+
22+
def wrapper(*args, **kwargs):
23+
return convert(obj(*args, **kwargs))
24+
25+
wrapper.__name__ = obj.__name__
26+
return wrapper
27+
28+
29+
class SuperComplex(complex):
30+
__metaclass__ = ReturnTypeWrapper
31+
wrapped_base = complex
32+
33+
def __lt__(self, other):
34+
return abs(other - self) < 0
35+
36+
def __le__(self, other):
37+
return abs(other - self) <= 0
38+
39+
def __gt__(self, other):
40+
return abs(other - self) > 0
41+
42+
def __ge__(self, other):
43+
return abs(other - self) >= 0
44+
45+
def __str__(self):
46+
return "(" + str(self.real) + "," + str(self.imag) + ")"
47+
48+
def __add__(self, no):
49+
return SuperComplex(self.real + no.real, self.imag + no.imag)
50+
51+
def __sub__(self, no):
52+
return SuperComplex(self.real - no.real, self.imag - no.imag)
53+
54+
55+
j = SuperComplex(1j)
56+
57+
# Cardinal directions
58+
north = j
59+
south = -j
60+
west = -1
61+
east = 1
62+
northeast = 1 + j
63+
northwest = -1 + j
64+
southeast = 1 - j
65+
southwest = -1 - j
66+
67+
directions_straight = [north, south, west, east]
68+
directions_diagonals = directions_straight + [
69+
northeast,
70+
northwest,
71+
southeast,
72+
southwest,
73+
]
74+
75+
# To be multiplied by the current cartinal direction
76+
relative_directions = {
77+
"left": j,
78+
"right": -j,
79+
"ahead": 1,
80+
"back": -1,
81+
}
82+
83+
84+
def min_real(complexes):
85+
real_values = [x.real for x in complexes]
86+
return min(real_values)
87+
88+
89+
def min_imag(complexes):
90+
real_values = [x.imag for x in complexes]
91+
return min(real_values)
92+
93+
94+
def max_real(complexes):
95+
real_values = [x.real for x in complexes]
96+
return max(real_values)
97+
98+
99+
def max_imag(complexes):
100+
real_values = [x.imag for x in complexes]
101+
return max(real_values)
102+
103+
104+
def manhattan_distance(a, b):
105+
return abs(b.imag - a.imag) + abs(b.real - a.real)
106+
107+
108+
def complex_sort(complexes, mode=""):
109+
# Sorts by real, then by imaginary component (x then y)
110+
if mode == "xy":
111+
complexes.sort(key=lambda a: (a.real, a.imag))
112+
# Sorts by imaginary, then by real component (y then x)
113+
elif mode == "yx":
114+
complexes.sort(key=lambda a: (a.imag, a.real))
115+
# Sorts by negative imaginary, then by real component (-y then x) - 'Reading" order
116+
elif mode == "reading":
117+
complexes.sort(key=lambda a: (-a.imag, a.real))
118+
# Sorts by distance from 0,0 (kind of polar coordinates)
119+
else:
120+
complexes.sort(key=lambda a: sqrt(a.imag ** 2 + a.real ** 2))
121+
return complexes

0 commit comments

Comments
 (0)