import 2019 aoc

This commit is contained in:
Thibaud Gasser 2024-12-03 15:26:47 +01:00
commit c6c3acaa9a
11 changed files with 815 additions and 0 deletions

131
.gitignore vendored Normal file
View File

@ -0,0 +1,131 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

41
2019/day1/day1.py Normal file
View File

@ -0,0 +1,41 @@
#! /usr/bin/env python3
def calculate_fuel_iterative(mass):
total = 0
new_mass = mass
while True:
new_mass = new_mass // 3 - 2
if new_mass < 0:
break
total += new_mass
return total
def calculate_total_fuel_mass(input_file, mass_function=lambda x: x // 3 - 2):
total = 0
with open(input_file) as masses:
for mass in masses:
total += mass_function(int(mass))
return total
def test_part2():
inputs = (14, 1969, 100756)
expected = (2, 966, 50346)
for i, inp in enumerate(inputs):
result = calculate_fuel_iterative(inp)
assert result == expected[i], "Result for {} should be {}, was {}".format(
inp, expected[i], result
)
print("All tests passed for part 2.")
if __name__ == "__main__":
print("Part 1 - total mass: ", calculate_total_fuel_mass("./input.txt"))
test_part2()
print(
"Part 2 -- total mass: ",
calculate_total_fuel_mass("./input.txt", calculate_fuel_iterative),
)

100
2019/day1/input.txt Normal file
View File

@ -0,0 +1,100 @@
62259
75368
93740
119724
112546
137714
96999
130673
102398
73819
100734
85337
62764
82115
127696
54391
103213
77954
112513
112392
138404
92989
108521
83163
109720
91918
114443
54306
90623
66833
58505
85919
77539
149419
128385
66452
94677
109179
62072
137245
136226
145783
60689
103320
145931
101286
63458
122468
87858
105675
146185
57417
96883
70739
97494
140951
149416
83137
66122
134319
58511
139600
102929
112240
149634
64142
83332
129526
99058
148889
50087
74961
133606
143518
68849
97045
73920
61357
115941
56740
111773
77880
90792
77103
111355
125898
56547
84918
113822
74113
98557
80928
60519
146379
59354
102490
72584
59000
63151
114253

69
2019/day2/day2.py Normal file
View File

@ -0,0 +1,69 @@
def interpret_intcode(input_prog):
# Instruction pointer: index of the next element to be executed
ip = 0
while ip < len(input_prog):
instruction = input_prog[ip]
if instruction == 99:
break
elif instruction == 1:
# The operands to sum are at the memory location ip+1 and ip+2.
operands = (input_prog[input_prog[ip + 1]], input_prog[input_prog[ip + 2]])
result = sum(operands)
target = input_prog[ip + 3]
input_prog[target] = result
ip += 4
elif instruction == 2:
# The operands to multiply are at the memory location ip+1 and ip+2.
operands = (input_prog[input_prog[ip + 1]], input_prog[input_prog[ip + 2]])
result = operands[0] * operands[1]
target = input_prog[ip + 3]
input_prog[target] = result
ip += 4
def tests():
inputs = (
[1, 0, 0, 0, 99], # ADD 1 + 1 to location 0
[2, 3, 0, 3, 99], # MUL 2 * 3 to location 3
[2, 4, 4, 5, 99, 0],
[1, 1, 1, 4, 99, 5, 6, 0, 99],
)
expected_outputs = (
[2, 0, 0, 0, 99], # 1 + 1 = 2
[2, 3, 0, 6, 99], # 3 * 2 = 6
[2, 4, 4, 5, 99, 9801], # 99 * 99 = 9801
[30, 1, 1, 4, 2, 5, 6, 0, 99],
)
for i, inp in enumerate(inputs):
result = inp[:]
interpret_intcode(result)
assert (
result == expected_outputs[i]
), f"Expected output for {inp} is {expected_outputs[i]}, but found {result} instead."
print("All tests passed.")
def run_program(memory, noun, verb):
memory[1] = noun
memory[2] = verb
interpret_intcode(memory)
return memory[0]
if __name__ == "__main__":
tests()
with open("input.txt") as inp:
memory = [int(x) for x in inp.readline().strip().split(",")]
# Pass a copy to avoid modifying the original memory
print("Part 1 answer: ", run_program(memory[:], 12, 2))
# Part 2
result = 0
for verb in range(99):
for noun in range(99):
if run_program(memory[:], noun, verb) == 19690720:
print(f"Part 2: noun={noun}, verb={verb}")
print("Result = ", 100 * noun + verb)
break

1
2019/day2/input.txt Normal file
View File

@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,13,19,1,9,19,23,1,6,23,27,2,27,9,31,2,6,31,35,1,5,35,39,1,10,39,43,1,43,13,47,1,47,9,51,1,51,9,55,1,55,9,59,2,9,59,63,2,9,63,67,1,5,67,71,2,13,71,75,1,6,75,79,1,10,79,83,2,6,83,87,1,87,5,91,1,91,9,95,1,95,10,99,2,9,99,103,1,5,103,107,1,5,107,111,2,111,10,115,1,6,115,119,2,10,119,123,1,6,123,127,1,127,5,131,2,9,131,135,1,5,135,139,1,139,10,143,1,143,2,147,1,147,5,0,99,2,0,14,0

78
2019/day3/day3.py Normal file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env python3
def manhattan_distance(p):
return abs(p[0]) + abs(p[1])
def points_for_wire(wire):
x, y, count = 0, 0, 0
points = {}
# (x, y)
directions = {"R": (1, 0), "L": (-1, 0), "U": (0, 1), "D": (0, -1)}
for p in wire:
# D42 -> for _ in range(42)
for _ in range(int(p[1:])):
offset = directions[p[0]]
x += offset[0]
y += offset[1]
count += 1
points[(x ,y)] = count
return points
def find_min_distance(wire1, wire2):
points1 = points_for_wire(wire1)
points2 = points_for_wire(wire2)
intersections = points1.keys() & points2.keys()
closest = min((intersection for intersection in intersections), key=manhattan_distance)
return manhattan_distance(closest)
def find_least_steps(wire1, wire2):
points1 = points_for_wire(wire1)
points2 = points_for_wire(wire2)
intersections = points1.keys() & points2.keys()
# Intersection with the least steps
least_steps = min(intersections, key=lambda x: points1[x] + points2[x])
return points1[least_steps] + points2[least_steps]
def tests():
inputs = (
(("R8", "U5", "L5", "D3"), ("U7", "R6", "D4", "L4")),
(("R75","D30","R83", "U83", "L12", "D49", "R71", "U7", "L72"), ("U62", "R66", "U55", "R34", "D71", "R55", "D58", "R83")),
(("R98", "U47", "R26", "D63", "R33", "U87", "L62", "D20", "R33", "U53", "R51"), ("U98", "R91", "D20", "R16", "D67", "R40", "U7", "R15", "U6", "R7"))
)
# Part 1
expected = (6, 159, 135)
for i, inp in enumerate(inputs):
result = find_min_distance(inp[0], inp[1])
assert result == expected[i], "Result for {} should be {}, was {}".format(
inp, expected[i], result
)
# Part 2
# expected number of steps
expected_part2 = (30, 610, 410)
print("All tests passed.")
for i, inp in enumerate(inputs):
result = find_least_steps(inp[0], inp[1])
assert result == expected_part2[i], "Result for {} should be {}, was {}".format(
inp, expected_part2[i], result
)
if __name__ == "__main__":
tests()
with open("input.txt") as raw_input:
lines = raw_input.readlines()
wire1, wire2 = [line.strip("\n").split(",") for line in lines]
print("Part 1 -- distance = ", find_min_distance(wire1, wire2))
print("Part 2 -- steps = ", find_least_steps(wire1, wire2))

2
2019/day3/input.txt Normal file
View File

@ -0,0 +1,2 @@
R997,U849,R349,U641,R581,D39,R285,U139,R455,D346,L965,D707,R393,D302,L263,U58,R950,U731,R858,D748,R302,U211,R588,D441,L153,D417,R861,U775,R777,U204,R929,U868,L62,U163,R841,D214,L648,U626,R501,D751,L641,D961,L23,D430,L73,D692,R49,U334,L601,U996,R444,D658,R633,D30,L861,D811,R10,D394,R9,U227,L848,U420,L378,D622,L501,U397,R855,U369,R615,U591,L674,D166,L181,U61,L224,U463,L203,U594,R93,U614,L959,U198,L689,D229,L674,U255,R843,D382,R538,U923,L960,D775,L879,U97,R137,U665,L340,D941,L775,D57,R852,D167,R980,U704,L843,U989,L611,D32,L724,D790,L32,U984,L39,U671,L994,U399,R475,D85,L322,D936,R117,D261,R705,D696,L523,D433,L239,U477,L247,D465,R560,D902,L589,U682,R645,U376,L989,D121,L215,U514,R519,U407,L218,D444,R704,D436,L680,U759,R937,U400,R533,D860,R782,D233,R840,D549,L508,U380,L992,U406,L213,D403,L413,D532,L429,U186,R262,U313,L913,U873,L838,D882,R851,U70,R185,D131,R945,D595,L330,U446,R88,D243,L561,D952,R982,D395,L708,U459,L82,D885,L996,U955,L406,U697,L183,U266,L878,D839,R843,D891,R118,U772,R590,D376,L500,U370,R607,D12,L310,D436,L602,D365,R886,U239,L471,D418,L122,U18,R879,D693,R856,U848,L657,D911,L63,U431,R41,U752,R919,U323,L61,D263,L370,D85,R929,D213,R350,U818,R458,D912,R509,U394,L734,U49,R810,D87,L870,U658,R499,U550,L402,U244,L112,U859,R836,U951,R222,D944,L691,D731,R742,D52,R984,D453,L514,U692,R812,U35,L844,D177,L110,D22,R61,U253,R618,D51,R163,U835,R704,U148,R766,U297,R457,D170,L104,D441,R330,D330,R989,D538,R668,D811,R62,D67,L470,D526,R788,U376,R708,U3,R961
L1009,D381,R970,U429,L230,D909,R516,D957,R981,U609,L480,D139,L861,U168,L48,U620,R531,D466,L726,D380,R977,D454,L318,D397,R994,U402,L77,U93,L359,D72,R968,D956,L174,D22,R218,U619,R593,U32,L154,U55,L169,U415,L171,U666,R617,U109,L265,U773,R541,D808,L797,U478,R731,U379,R311,D137,L806,U298,R362,D458,L254,D539,R700,U853,R246,D588,L28,U203,L432,U946,R663,D408,R974,U59,L683,D36,L139,U738,L780,U414,L401,D93,R212,D973,L710,U892,L357,D177,R823,D4,R46,D924,L235,D898,R67,U220,L592,U87,R94,U584,R979,D843,L299,D648,L491,U360,R824,D245,L944,D24,R616,U975,L4,U42,L984,U181,R902,D835,L687,D413,L767,U632,L754,U270,R413,U51,L825,D377,L596,U960,L378,U706,L859,D708,L156,D991,L814,U351,R923,D749,L16,D651,R20,D86,R801,U811,L228,U161,L871,U129,R215,U235,L784,U896,R94,U145,R822,U494,R248,D98,R494,U156,L495,U311,R66,D873,L294,D620,L885,U395,R778,D227,R966,U756,L694,D707,R983,D950,R706,D730,R415,U886,L465,D622,L13,D938,R324,D464,R723,U804,R942,D635,L729,D317,L522,U469,R550,D141,R302,U999,L642,U509,R431,D380,R18,D676,R449,D759,L495,U901,R1,D745,L655,U449,L439,D818,R55,D541,R420,U764,L426,D176,L520,U3,L663,D221,L80,D449,L987,U349,L71,U632,L887,D231,R655,D208,R698,D639,R804,U616,R532,U846,R363,D141,R659,U470,L798,U144,L675,U483,L944,U380,L329,U72,L894,D130,R53,U109,R610,U770,R778,U493,R972,D340,L866,U980,L305,D812,R130,D954,R253,D33,L912,U950,L438,D680,R891,U725,R171,D587,R549,D367,L4,U313,R522,D128,L711,D405,L769,D496,L527,U373,R725,D261,L268,D939,L902,D58,L858,D190,L442

37
2019/day4/day4.py Normal file
View File

@ -0,0 +1,37 @@
#! /usr/bin/env python3
def check_increase(number):
num = str(number)
for i in range(len(num) - 1):
if num[i+1] < num[i]:
return False
return True
def check_adjacent(number):
num = str(number)
for digit in num:
count = num.count(digit)
if count == 2: # Part one : <= 2
return True
return False
def tests():
assert check_increase(123456) == True
assert check_increase(123454) == False
assert check_adjacent(112345) == True
assert check_adjacent(123445) == True
assert check_adjacent(123456) == False
def main(start, end):
matches = 0
for n in range(start, end + 1):
if check_increase(n) and check_adjacent(n):
matches += 1
return matches
if __name__ == "__main__":
tests()
print("Matches : ", main(367479, 893698))

163
2019/day5/day5.py Normal file
View File

@ -0,0 +1,163 @@
#! /usr/bin/env python3
from collections import namedtuple
from enum import Enum
import logging
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.WARN)
def get_nth_digit(n, number):
"Returns the nth digit of the input number"
return number // 10 ** n % 10
class Operation(Enum):
ADDITION = 1
MULTIPLICATION = 2
INPUT = 3
OUTPUT = 4
JMP_IF_TRUE = 5
JMP_IF_FALSE = 6
LESS_THAN = 7
EQUALS = 8
TERMINATION = 99
class Mode(Enum):
POSITION = 0
IMMEDIATE = 1
class Instruction:
def __init__(self, opcode):
self.operation = Operation(opcode % 100)
self.modes = [Mode(get_nth_digit(n, opcode)) for n in range(2, 5)]
self.handler_name = f"handle_{self.operation.name.lower()}"
self.handler = getattr(self, self.handler_name, self.handle_termination)
def __repr__(self):
return f"Instruction({self.operation}, {self.modes})"
def handle(self, program, ip):
return self.handler(program, ip)
def handle_addition(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"ADD {first} {second}")
result = first + second
# the last mode should *always* be POSITION
program[program[ip + 3]] = result
ip += 4
return ip
def handle_multiplication(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"MUL {first} {second}")
result = first * second
# the last mode should *always* be POSITION
program[program[ip + 3]] = result
ip += 4
return ip
def handle_input(self, program, ip):
ip += 2
program[program[ip + 1]] = int(input("Enter ID > "))
return ip
def handle_output(self, program, ip):
print("OUT ", program[program[ip + 1]])
ip += 2
return ip
def handle_jmp_if_true(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"JMPT {first} {second}")
return second if first != 0 else ip + 3
def handle_jmp_if_false(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"JMPF {first} {second}")
return second if first == 0 else ip + 3
def handle_less_than(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"LT {first} {second}")
program[program[ip + 3]] = int(first < second)
ip += 4
return ip
def handle_equals(self, program, ip):
first, second = self._get_parameters(program, ip)
logging.debug(f"EQ {first} {second}")
program[program[ip + 3]] = int(first == second)
ip += 4
return ip
def handle_termination(self, program, ip):
print("HALT")
return ip
def _get_parameters(self, program, ip):
first = (
program[ip + 1]
if self.modes[0] is Mode.IMMEDIATE
else program[program[ip + 1]]
)
second = (
program[ip + 2]
if self.modes[1] is Mode.IMMEDIATE
else program[program[ip + 2]]
)
return first, second
def interpret_intcode(program, stdin=None):
ip = 0
while program[ip] != 99:
opcode = program[ip]
instruction = Instruction(opcode)
ip = instruction.handle(program, ip)
def tests():
inputs = (
[1, 0, 0, 0, 99], # ADD 1 + 1 to location 0
[2, 3, 0, 3, 99], # MUL 2 * 3 to location 3
[2, 4, 4, 5, 99, 0],
[1, 1, 1, 4, 99, 5, 6, 0, 99],
[1101, 1, 1, 0, 99], # ADD 1 + 1 to location 0 (direct access)
)
expected_outputs = (
[2, 0, 0, 0, 99], # 1 + 1 = 2
[2, 3, 0, 6, 99], # 3 * 2 = 6
[2, 4, 4, 5, 99, 9801], # 99 * 99 = 9801
[30, 1, 1, 4, 2, 5, 6, 0, 99],
[2, 1, 1, 0, 99], # 1 + 1 = 2 (direct access)
)
for i, inp in enumerate(inputs):
result = inp[:]
interpret_intcode(result)
assert (
result == expected_outputs[i]
), f"Expected output for {inp} is {expected_outputs[i]}, but found {result} instead."
print("\nAll tests passed.\n")
def run_input_program(filename):
import os
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(SCRIPT_DIR, filename)) as inp:
print("Start of input program.")
memory = [int(x) for x in inp.readline().strip().split(",")]
interpret_intcode(memory, 5)
if __name__ == "__main__":
tests()
# a = [3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9]
# b = [3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1]
# interpret_intcode(b, 0)
# interpret_intcode(a, 0)
run_input_program("input.txt")

192
2019/day5/day52.py Normal file
View File

@ -0,0 +1,192 @@
import logging
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.DEBUG)
class Instruction:
code, argument_num = 0, 0
def execute(self, intcode, arguments):
pass
def new_pc(self, intcode):
return intcode.pc + self.argument_num + 1
class PlusInstruction(Instruction):
code, argument_num = 1, 3
def execute(self, intcode, arguments):
logging.debug(f"ADD {arguments[0].value} {arguments[1].value}")
intcode.set(arguments[2].address, arguments[0].value + arguments[1].value)
return self.new_pc(intcode)
class MultiplyInstruction(Instruction):
code, argument_num = 2, 3
def execute(self, intcode, arguments):
logging.debug(f"MUL {arguments[0].value} {arguments[1].value}")
intcode.set(arguments[2].address, arguments[0].value * arguments[1].value)
return self.new_pc(intcode)
class InputInstruction(Instruction):
code, argument_num = 3, 1
def execute(self, intcode, arguments):
intcode.set(arguments[0].address, intcode.get_input())
return self.new_pc(intcode)
class OutputInstruction(Instruction):
code, argument_num = 4, 1
def execute(self, intcode, arguments):
intcode.output = arguments[0].value
return self.new_pc(intcode)
class JumpIfTrueInstruction(Instruction):
code, argument_num = 5, 2
def execute(self, intcode, arguments):
logging.debug(f"JMPT {arguments[0].value} {arguments[1].value}")
return arguments[1].value if arguments[0].value != 0 else self.new_pc(intcode)
class JumpIfFalseInstruction(Instruction):
code, argument_num = 6, 2
def execute(self, intcode, arguments):
logging.debug(f"JMPF {arguments[0].value} {arguments[1].value}")
return arguments[1].value if arguments[0].value == 0 else self.new_pc(intcode)
class LessThanInstruction(Instruction):
code, argument_num = 7, 3
def execute(self, intcode, arguments):
logging.debug(f"LT {arguments[0].value} {arguments[1].value}")
intcode.set(arguments[2].address, int(arguments[0].value < arguments[1].value))
return self.new_pc(intcode)
class EqualsInstruction(Instruction):
code, argument_num = 8, 3
def execute(self, intcode, arguments):
intcode.set(arguments[2].address, int(arguments[0].value == arguments[1].value))
return self.new_pc(intcode)
class RelativeBaseOffsetInstruction(Instruction):
code, argument_num = 9, 1
def execute(self, intcode, arguments):
intcode.relative_base += arguments[0].value
return self.new_pc(intcode)
class HaltInstruction(Instruction):
code, argument_num = 99, 0
def execute(self, intcode, arguments):
intcode.halted = True
return None
class Argument:
def __init__(self, value, address):
self.value = value
self.address = address
class IntCode:
def __init__(self, program, inputs=[], input_func=None):
self.program = program[:]
self.inputs = inputs[::-1]
self.input_func = input_func
self.relative_base = 0
self.memory = {}
self.output = None
self.halted = False
self.pc = 0
def _get_instruction(self, instruction_code):
return next(
cls for cls in Instruction.__subclasses__() if cls.code == instruction_code
)
def _parse_arguments(self, argument_num):
modes = str(self.program[self.pc]).zfill(5)[:3][::-1]
arguments = []
for i in range(argument_num):
value = self.program[self.pc + i + 1] + (
self.relative_base if modes[i] == "2" else 0
)
if modes[i] == "1":
arguments.append(Argument(value, value))
else:
arguments.append(
Argument(
self.program[value]
if value < len(self.program)
else self.memory.get(value, 0),
value,
)
)
return arguments
def run(self):
self.output = None
while not self.halted and self.output is None:
instruction = self._get_instruction(self.program[self.pc] % 100)
arguments = self._parse_arguments(instruction.argument_num)
self.pc = instruction().execute(self, arguments)
return self.output
def execute(self):
last_output = None
while not self.halted:
output = self.run()
if not self.halted:
last_output = output
return last_output
def clone(self):
cloned = IntCode(self.program)
cloned.inputs = self.inputs[:]
cloned.input_func = self.input_func
cloned.relative_base = self.relative_base
cloned.memory = {key: value for key, value in self.memory.items()}
cloned.output = self.output
cloned.halted = self.halted
cloned.pc = self.pc
return cloned
def get(self, address):
return (
self.program[address]
if address < len(self.program)
else self.memory.get(value + self.relative_base, 0)
)
def set(self, address, value):
target = self.program if address < len(self.program) else self.memory
target[address] = value
def input(self, value):
self.inputs = [value] + self.inputs
def get_input(self):
return self.inputs.pop() if self.inputs else self.input_func()
import os
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
code = list(map(int, open(os.path.join(SCRIPT_DIR, "input.txt")).read().split(",")))
part2 = IntCode(code, [5]).execute()
print(part2)

1
2019/day5/input.txt Normal file
View File

@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1102,67,92,225,1101,14,84,225,1002,217,69,224,101,-5175,224,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1,214,95,224,101,-127,224,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1101,8,41,225,2,17,91,224,1001,224,-518,224,4,224,1002,223,8,223,101,2,224,224,1,223,224,223,1101,37,27,225,1101,61,11,225,101,44,66,224,101,-85,224,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1102,7,32,224,101,-224,224,224,4,224,102,8,223,223,1001,224,6,224,1,224,223,223,1001,14,82,224,101,-174,224,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,102,65,210,224,101,-5525,224,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1101,81,9,224,101,-90,224,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,71,85,225,1102,61,66,225,1102,75,53,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,226,226,224,102,2,223,223,1005,224,329,1001,223,1,223,1108,677,677,224,1002,223,2,223,1006,224,344,101,1,223,223,1007,226,677,224,102,2,223,223,1005,224,359,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,374,101,1,223,223,1108,677,226,224,1002,223,2,223,1005,224,389,1001,223,1,223,108,226,677,224,102,2,223,223,1006,224,404,101,1,223,223,1108,226,677,224,102,2,223,223,1005,224,419,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,434,101,1,223,223,7,677,226,224,1002,223,2,223,1005,224,449,101,1,223,223,1008,226,226,224,102,2,223,223,1005,224,464,1001,223,1,223,107,226,677,224,1002,223,2,223,1006,224,479,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,494,1001,223,1,223,1008,226,677,224,102,2,223,223,1006,224,509,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,524,101,1,223,223,1007,226,226,224,1002,223,2,223,1006,224,539,1001,223,1,223,107,226,226,224,102,2,223,223,1006,224,554,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,7,226,677,224,102,2,223,223,1006,224,584,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,599,101,1,223,223,1107,677,677,224,1002,223,2,223,1005,224,614,101,1,223,223,8,226,677,224,102,2,223,223,1005,224,629,1001,223,1,223,7,226,226,224,1002,223,2,223,1006,224,644,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,659,101,1,223,223,1107,226,677,224,1002,223,2,223,1006,224,674,101,1,223,223,4,223,99,226