You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
from sys import argv
|
|
|
|
|
|
|
|
|
|
|
|
def _no_op(x=None):
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
|
|
def get_input(day: int, parser: callable = _no_op):
|
|
|
|
with open(f'inputs/{day}') as inp:
|
|
|
|
return parser(inp.read())
|
|
|
|
|
|
|
|
|
|
|
|
def parse_lines(raw: str):
|
|
|
|
return raw.splitlines(keepends=False)
|
|
|
|
|
|
|
|
|
|
|
|
def parse_lines_with_type_and_default(typ: callable, default):
|
|
|
|
def inner(raw: str):
|
|
|
|
lines = raw.splitlines(keepends=False)
|
|
|
|
out = []
|
|
|
|
for line in lines:
|
|
|
|
try:
|
|
|
|
out.append(typ(line))
|
|
|
|
except:
|
|
|
|
out.append(default)
|
|
|
|
return out
|
|
|
|
return inner
|
|
|
|
|
|
|
|
|
|
|
|
def parse_lines_with_func(f: callable):
|
|
|
|
def inner(raw: str):
|
|
|
|
lines = raw.splitlines(keepends=False)
|
|
|
|
out = [f(line) for line in lines]
|
|
|
|
return out
|
|
|
|
return inner
|
|
|
|
|
|
|
|
|
|
|
|
def group_on_empty_line(casting_func: callable = _no_op):
|
|
|
|
def inner(raw: str):
|
|
|
|
lines = raw.splitlines(keepends=False)
|
|
|
|
out = []
|
|
|
|
current = []
|
|
|
|
for line in lines:
|
|
|
|
if not line:
|
|
|
|
out.append(current)
|
|
|
|
current = []
|
|
|
|
else:
|
|
|
|
current.append(casting_func(line))
|
|
|
|
|
|
|
|
return out
|
|
|
|
return inner
|
|
|
|
|
|
|
|
|
|
|
|
def main(part1: callable = _no_op, part2: callable = _no_op):
|
|
|
|
match argv[-1]:
|
|
|
|
case "1":
|
|
|
|
ret = part1()
|
|
|
|
if ret is not None:
|
|
|
|
print(ret)
|
|
|
|
case "2":
|
|
|
|
ret = part2()
|
|
|
|
if ret is not None:
|
|
|
|
print(ret)
|
|
|
|
case _:
|
|
|
|
ret1 = part1()
|
|
|
|
if ret1 is not None:
|
|
|
|
print("part1:", ret1)
|
|
|
|
ret2 = part2()
|
|
|
|
if ret2 is not None:
|
|
|
|
print("part2:", ret2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|