Skip to content

Commit 3c83d1f

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

File tree

4 files changed

+931
-0
lines changed

4 files changed

+931
-0
lines changed
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)
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