From 051c3f3ebdd0c6394364c55d4ba6c2a4e6c59fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Engl=C3=B6f=20Ytterstr=C3=B6m?= Date: Tue, 19 Dec 2023 18:34:03 +0100 Subject: [PATCH] Lint and Refactor day 1-11 --- 2019-python/aoc.py | 101 +++++++++++++++---------- 2019-python/output/__init__.py | 77 ++++++++++++++----- 2019-python/output/day_01.py | 38 ++++++---- 2019-python/output/day_02.py | 49 +++++++----- 2019-python/output/day_03.py | 57 +++++++------- 2019-python/output/day_04.py | 48 +++++++----- 2019-python/output/day_05.py | 41 ++++++---- 2019-python/output/day_06.py | 46 ++++++----- 2019-python/output/day_07.py | 48 +++++++----- 2019-python/output/day_08.py | 44 +++++++---- 2019-python/output/day_09.py | 39 ++++++---- 2019-python/output/day_10.py | 41 ++++++---- 2019-python/output/day_11.py | 43 +++++++---- 2019-python/output/intcode_computer.py | 4 +- 14 files changed, 422 insertions(+), 254 deletions(-) diff --git a/2019-python/aoc.py b/2019-python/aoc.py index 07a42b2..8dcdaa9 100644 --- a/2019-python/aoc.py +++ b/2019-python/aoc.py @@ -1,5 +1,12 @@ +import os import sys + +def headline(n, title): + """Print day number and name, followed by a ruler. Used by the answer decorator""" + print(f"\n--- Day {n}: {title} ---\n") + + year = 2019 try: @@ -19,48 +26,54 @@ if day_no and name: with open("output/day_{}.py".format(padded_no), "w") as s: s.write( f""" -from output import answer, puzzleinput +from output import answer # , matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg n = {day_no} title = "{name}" -@puzzleinput(n) -def parse_input(data): - return data - - @answer(1, "Answer is {{}}") -def part_1(data): - return data +def part_1(outputs): + return outputs[0] @answer(2, "Actually, answer is {{}}") -def part_2(data): - return data +def part_2(outputs): + return outputs[1] + + +def solve(data): + return None, None if __name__ == "__main__": # use dummy data - parsed = \"\"\" + inp = \"\"\" replace me \"\"\".strip() # uncomment to instead use stdin - # import fileinput - # parsed = "\\n".join(list(fileinput.input())) + # import sys; inp = sys.stdin.read().strip() - # uncomment to instead use content of input/{padded_no}.txt - # parsed = parse_input() + # uncomment to use AoC provided puzzle input + # with open("./input/{padded_no}.txt", "r") as f: + # inp = f.read().strip() - part_1(parsed) - # part_2(parsed) + inp = solve(inp) + + a = part_1(inp) + # b = part_2(inp) + + # uncomment and replace 0 with actual output to refactor code + # and ensure nonbreaking changes + # assert a == 0 + # assert b == 0 """.strip() + "\n" ) - print(f"- creating empty input/{day_no.zfill(2)}.txt") - with open("input/{}.txt".format(day_no.zfill(2)), "w") as i: - i.write("") + print("- making sure input dir exists") + if not os.path.exists("input"): + os.makedirs("input") print( f""" @@ -75,28 +88,34 @@ https://adventofcode.com/{year}/day/{day_no}/input ) exit(0) -from output import headline stars = 0 for i in [str(n).zfill(2) for n in range(1, 26)]: - try: - day = __import__( - "output.day_{}".format(i), - globals(), - locals(), - ["n", "title", "part_1", "part_2", "parse_input"], - 0, - ) - headline(day.n, day.title) - data = day.parse_input() - day.part_1(data, decorate=True) - stars += 1 - day.part_2(data, decorate=True) - stars += 1 - except IOError: - pass - except ImportError: - pass -print(f"\nStars: {stars}") -print("".join("*" if n <= stars else "•" for n in range(50))) + if not day_no or day_no.zfill(2) == i: + try: + day = __import__( + "output.day_{}".format(i), + globals(), + locals(), + ["n", "title", "part_1", "part_2", "solve"], + 0, + ) + with open(f"./input/{i}.txt", "r") as f: + data = f.read().strip() + headline(day.n, day.title) + try: + data = day.solve(data) + except AttributeError: + pass + if day.part_1(data, decorate=True): + stars += 1 + if day.part_2(data, decorate=True): + stars += 1 + except IOError: + pass + except ImportError: + pass +if not day_no: + print(f"\nStars: {stars}") + print("".join("*" if n < stars else "•" for n in range(50))) print("") diff --git a/2019-python/output/__init__.py b/2019-python/output/__init__.py index 4483fa4..3a034d6 100644 --- a/2019-python/output/__init__.py +++ b/2019-python/output/__init__.py @@ -1,26 +1,38 @@ import functools +import re +# Directions/Adjacents for 2D matrices, in the order UP, RIGHT, DOWN, LEFT +D = [ + (-1, 0), + (0, 1), + (1, 0), + (0, -1), +] -def puzzleinput(n, **kwargs): - filename = str(n).zfill(2) - trim_input = kwargs.get("trim_input", True) - filepath = f"./input/{filename}.txt" +# Directions for 2D matrices, as a dict with keys U, R, D, L +DD = { + "U": (-1, 0), + "R": (0, 1), + "D": (1, 0), + "L": (0, -1), +} - def decorator_pi(func): - @functools.wraps(func) - def wrapper_pi(*args, **kwargs): - with open(filepath, "r") as f: - data = f.read() - if trim_input: - return func(data.strip(), *args, **kwargs) - return func(data, *args, **kwargs) - - return wrapper_pi - - return decorator_pi +# Adjacent relative positions including diagonals for 2D matrices, in the order NW, N, NE, W, E, SW, S, SE +ADJ = [ + (-1, -1), + (-1, 0), + (1, -1), + (0, -1), + (0, 1), + (1, 1), + (1, 0), + (1, -1), +] def answer(part_index, fmt_string): + """Decorator to present a solution in a human readable format""" + def decorator_aoc(func): @functools.wraps(func) def wrapper_aoc(*args, **kwargs): @@ -32,7 +44,7 @@ def answer(part_index, fmt_string): print(answer) else: formatted = fmt_string.format(answer) - print(f"[part {part_index}] {formatted}") + print(f" {part_index}) {formatted}") return answer return wrapper_aoc @@ -40,6 +52,31 @@ def answer(part_index, fmt_string): return decorator_aoc -def headline(n, title): - title = f"Day {n}: {title}" - print("\n".join(["", title, "".join("-" for _ in title), ""])) +def ints(s): + """Extract all integers from a string""" + return [int(n) for n in re.findall(r"\d+", s)] + + +def mhd(a, b): + """Calculates the Manhattan distance between 2 positions in the format (y, x) or (x, y)""" + ar, ac = a + br, bc = b + return abs(ar - br) + abs(ac - bc) + + +def matrix(d): + """Transform a string into an iterable matrix. Returns the matrix, row count and col count""" + m = [tuple(r) for r in d.split()] + return m, len(m), len(m[0]) + + +def mdbg(m): + """Print-debug a matrix""" + for r in m: + print("".join(r)) + + +def vdbg(seen, h, w): + """Print-debug visited positions of a matrix""" + for r in range(h): + print("".join(["#" if (r, c) in seen else "." for c in range(w)])) diff --git a/2019-python/output/day_01.py b/2019-python/output/day_01.py index 64a49f7..86179b6 100644 --- a/2019-python/output/day_01.py +++ b/2019-python/output/day_01.py @@ -1,32 +1,40 @@ -from output import answer, puzzleinput +from output import answer n = 1 title = "The Tyranny of the Rocket Equation" -@puzzleinput(n) -def parse_input(data): - return list(map(int, data.split())) - - @answer(1, "Total fuel requirements are {}") -def part_1(lines): - return sum(n // 3 - 2 for n in lines) +def part_1(o): + return o[0] @answer(2, "Total fuel requirements are {} including fuel costs") -def part_2(lines): - s = 0 +def part_2(o): + return o[1] + + +def solve(data): + lines = list(map(int, data.split())) + p1 = sum(n // 3 - 2 for n in lines) + p2 = 0 for fuel in lines: rem = fuel while rem > 0: cost = rem // 3 - 2 - s += max(0, cost) + p2 += max(0, cost) rem = max(0, cost) - return s + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/01.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 3393938 + assert b == 5088037 diff --git a/2019-python/output/day_02.py b/2019-python/output/day_02.py index 29ab8cb..0bd3732 100644 --- a/2019-python/output/day_02.py +++ b/2019-python/output/day_02.py @@ -1,35 +1,48 @@ -from output import answer, puzzleinput - +from output import answer from output.intcode_computer import execute, parse n = 2 title = "1202 Program Alarm" -@puzzleinput(n) -def parse_input(data): - return parse(data) - - @answer(1, "[intcode-0.1.0] Value of pos 0 is {} at halt signal") -def part_1(program): - program[1] = 12 - program[2] = 2 - _code, state, *_unused = execute(program) - return state[0] +def part_1(o): + return o[0] @answer(2, "[intcode-0.1.1] 100 * noun + verb = {} for output 19690720") -def part_2(program, noun=76, verb=21): +def part_2(o): + return o[1] + + +def solve(data): + program = parse(data) + + program[1] = 12 + program[2] = 2 + _code, state, *_unused = execute(program) + noun = 76 # found manually by binary search + verb = 21 + p1 = state[0] + program[1] = noun program[2] = verb _code, state, *_unused = execute(program) + p2 = state[0] if state[0] == 19690720: - return 100 * noun + verb - return state[0] + p2 = 100 * noun + verb + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed, 76, 21) # found manually by binary search + with open("./input/02.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 3306701 + assert b == 7621 diff --git a/2019-python/output/day_03.py b/2019-python/output/day_03.py index 79967b1..0b3277f 100644 --- a/2019-python/output/day_03.py +++ b/2019-python/output/day_03.py @@ -1,5 +1,6 @@ from collections import defaultdict -from output import answer, puzzleinput + +from output import answer n = 3 title = "Crossed Wires" @@ -12,37 +13,24 @@ directions = { } -@puzzleinput(n) -def parse_input(data): - return [line.split(",") for line in data.split()] - - @answer( 1, "As the crow flies, closest intersection Manhattan distance is {} units away" ) -def part_1(wires): - def follow(instructions): - seen = [] - pos = (0, 0) - for instruction in instructions: - urdl, *l = instruction - distance = int("".join(l)) - for _ in range(distance): - pos = (pos[0] + directions[urdl][0], pos[1] + directions[urdl][1]) - seen.append(pos) - return set(seen) - - wa = follow(wires[0]) - wb = follow(wires[1]) - - return min(sum(map(abs, i)) for i in wa & wb) +def part_1(o): + return o[0] @answer(2, "By travel, closest intersection Manhattan distance is {} units away") -def part_2(wires): +def part_2(o): + return o[1] + + +def solve(inp): + wires = [line.split(",") for line in inp.split()] seen = defaultdict(dict) def follow(instructions, i): + visited = [] steps = 0 pos = (0, 0) for instruction in instructions: @@ -51,16 +39,29 @@ def part_2(wires): for _ in range(distance): steps += 1 pos = (pos[0] + directions[urdl][0], pos[1] + directions[urdl][1]) + visited.append(pos) if i not in seen[pos]: seen[pos][i] = steps + return set(visited) + p1w = [] for i, wire in enumerate(wires): - follow(wire, i) + p1w.append(follow(wire, i)) + p1 = min(sum(map(abs, i)) for i in p1w[0] & p1w[1]) - return min(sum(v.values()) for v in seen.values() if len(v) > 1) + p2 = min(sum(v.values()) for v in seen.values() if len(v) > 1) + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/03.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 1337 + assert b == 65356 diff --git a/2019-python/output/day_04.py b/2019-python/output/day_04.py index d0464b9..45a5e69 100644 --- a/2019-python/output/day_04.py +++ b/2019-python/output/day_04.py @@ -1,36 +1,44 @@ from collections import Counter -from output import answer, puzzleinput + +from output import answer n = 4 title = "Secure Container" -@puzzleinput(n) -def parse_input(data): - return data.split("-") - - @answer(1, "{} combinations of valid passwords") -def part_1(range_values): - a, b = range_values - - def valid(s): - return "".join(sorted(s)) == s and any(x == y for x, y in zip(s, s[1:])) - - return sum(valid(str(pw)) for pw in range(int(a), int(b) + 1)) +def part_1(o): + return o[0] @answer(2, "{} combinations of valid passwords, including important detail") -def part_2(range_values): - a, b = range_values +def part_2(o): + return o[1] - def valid(s): + +def solve(data): + a, b = data.split("-") + + def v1(s): + return "".join(sorted(s)) == s and any(x == y for x, y in zip(s, s[1:])) + + def v2(s): return "".join(sorted(s)) == s and 2 in Counter(s).values() - return sum(valid(str(pw)) for pw in range(int(a), int(b) + 1)) + p1 = sum(v1(str(pw)) for pw in range(int(a), int(b) + 1)) + p2 = sum(v2(str(pw)) for pw in range(int(a), int(b) + 1)) + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/04.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 544 + assert b == 334 diff --git a/2019-python/output/day_05.py b/2019-python/output/day_05.py index 179e8c3..3075f49 100644 --- a/2019-python/output/day_05.py +++ b/2019-python/output/day_05.py @@ -1,29 +1,40 @@ -from output import answer, puzzleinput - +from output import answer from output.intcode_computer import execute, parse n = 5 title = "Sunny with a Chance of Asteroids" -@puzzleinput(n) -def parse_input(data): - return parse(data) - - @answer(1, "[intcode-0.2.0] Program diagnostic code, ID 1: {}") -def part_1(program): - _code, _state, _cursorpos, rb, stdout = execute(program, stdin=[1]) - return max(stdout) +def part_1(o): + return o[0] @answer(2, "[intcode-0.2.1] Program diagnostic code, ID 5: {}") -def part_2(program): +def part_2(o): + return o[1] + + +def solve(data): + program = parse(data) + + _code, _state, _cursorpos, rb, stdout = execute(program, stdin=[1]) + p1 = max(stdout) + _code, _state, _cursorpos, rb, stdout = execute(program, stdin=[5]) - return stdout[0] + p2 = stdout[0] + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/05.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 16434972 + assert b == 16694270 diff --git a/2019-python/output/day_06.py b/2019-python/output/day_06.py index 3d4f201..9ad8f70 100644 --- a/2019-python/output/day_06.py +++ b/2019-python/output/day_06.py @@ -1,35 +1,40 @@ -from collections import defaultdict, deque -from output import answer, puzzleinput +from collections import defaultdict + +from output import answer n = 6 title = "Universal Orbit Map" -@puzzleinput(n) -def parse_input(data): - heritage = defaultdict(str) - for parent, child in [line.split(")") for line in data.split()]: - heritage[child] = parent - return heritage - - @answer(1, "{} direct and indirect orbits") -def part_1(heritage): - return sum(len(ancestry(heritage, v)) for v in heritage.keys()) +def part_1(o): + return o[0] @answer(2, "Orbit transfers needed for you to share orbit with Santa: {}") -def part_2(heritage): +def part_2(o): + return o[1] + + +def solve(data): + heritage = defaultdict(str) + for parent, child in [line.split(")") for line in data.split()]: + heritage[child] = parent + + p1 = sum(len(ancestry(heritage, v)) for v in heritage.keys()) + a = ancestry(heritage, "YOU") b = ancestry(heritage, "SAN") shared = len(set(a) & set(b)) - return sum( + p2 = sum( [ len(a) - shared, len(b) - shared, ] ) + return p1, p2 + def ancestry(parents, child): k = child @@ -41,6 +46,13 @@ def ancestry(parents, child): if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/06.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 271151 + assert b == 388 diff --git a/2019-python/output/day_07.py b/2019-python/output/day_07.py index 2e90e5e..6b19166 100644 --- a/2019-python/output/day_07.py +++ b/2019-python/output/day_07.py @@ -1,23 +1,32 @@ from collections import defaultdict from itertools import permutations -from output import answer, puzzleinput +from output import answer from output.intcode_computer import execute, parse n = 7 title = "Amplification Circuit" -@puzzleinput(n) -def parse_input(data): - return parse(data) - - @answer( 1, "[intcode 0.3.0] The highest achievable signal to the thruster is {}", ) -def part_1(program): +def part_1(o): + return o[0] + + +@answer( + 2, + "[intcode 0.3.0] By creating a feedback loop, the highest achievable signal to the thruster is {}", +) +def part_2(o): + return o[0] + + +def solve(data): + program = parse(data) + thruster_signals = [] for settings in map(list, permutations(range(5))): o = 0 @@ -25,14 +34,8 @@ def part_1(program): _code, _state, _n, _rb, so = execute(program, stdin=[ps, o]) o = so.pop(0) thruster_signals.append(o) - return max(thruster_signals) + p1 = max(thruster_signals) - -@answer( - 2, - "[intcode 0.3.0] By creating a feedback loop, the highest achievable signal to the thruster is {}", -) -def part_2(program): thruster_signals = [] for settings in map(list, permutations(range(5, 10))): o = [0] @@ -56,10 +59,19 @@ def part_2(program): finished.add(amp) o = so thruster_signals.append(o[-1]) - return max(thruster_signals) + p2 = max(thruster_signals) + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/07.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 398674 + assert b == 39431233 diff --git a/2019-python/output/day_08.py b/2019-python/output/day_08.py index 3abd526..30ad1e0 100644 --- a/2019-python/output/day_08.py +++ b/2019-python/output/day_08.py @@ -1,38 +1,50 @@ from collections import Counter from textwrap import wrap -from output import answer, puzzleinput + +from output import answer n = 8 title = "Space Image Format" -@puzzleinput(n) -def parse_input(data): - return data - - @answer(1, "The product of all 1s and 2s in the layer with fewest 0s is {}") -def part_1(data): +def part_1(o): + return o[0] + + +@answer(2, "The message is {}, the decoded image looks like above") +def part_2(o): + return o[1] + + +def solve(data): layers = sorted(map(Counter, wrap(data, 25 * 6)), key=lambda c: c["0"]) + width, height = 25, 6 a = layers[0]["1"] b = layers[0]["2"] - return a * b + p1 = a * b - -@answer(2, "The message is CYUAH, the decoded image looks like this:\n\n{}") -def part_2(data, width=25, height=6): layers = wrap(data, width * height) - l = len(layers) pixels = zip(*layers) lit = map( lambda s: s.replace("0", ".").replace("1", "#"), map(lambda p: next(filter(lambda x: x != "2", p)), pixels), ) matrix = "\n".join(wrap("".join(lit), width)) - return matrix + print(matrix) + p2 = "CYUAH" + + return p1, p2 if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/08.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 2500 + assert b == "CYUAH" diff --git a/2019-python/output/day_09.py b/2019-python/output/day_09.py index 5d118dc..1e25fa9 100644 --- a/2019-python/output/day_09.py +++ b/2019-python/output/day_09.py @@ -1,25 +1,27 @@ -from output import answer, puzzleinput +from output import answer from output.intcode_computer import execute, parse n = 9 title = "Sensor Boost" -@puzzleinput(n) -def parse_input(data): - return parse(data) - - @answer(1, "[intcode 0.3.1] BOOST keycode: {}") -def part_1(program): - _c, _s, _n, _rb, outputs = execute(program, stdin=[1]) - return outputs.pop(0) +def part_1(o): + return o[0] @answer(2, "[intcode 0.3.1] Distress signal coordinates: {}") -def part_2(program): - _c, _s, _n, _rb, outputs = execute(program, stdin=[2]) - return outputs.pop(0) +def part_2(o): + return o[1] + + +def solve(data): + program = parse(data) + p12 = [] + for inp in [1, 2]: + _c, _s, _n, _rb, outputs = execute(program, stdin=[inp]) + p12.append(outputs.pop(0)) + return p12 if __name__ == "__main__": @@ -72,8 +74,13 @@ if __name__ == "__main__": assert execute([109, 1, 203, 2, 204, 2, 99], stdin=[666])[4][0] == 666 assert execute([109, 6, 21001, 9, 25, 1, 104, 0, 99, 49])[4][0] == 74 - parsed = parse_input() - assert execute(parsed, stdin=[1])[4][0] == 2351176124 + with open("./input/09.txt", "r") as f: + inp = f.read().strip() - part_1(parsed) - part_2(parsed) + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 2351176124 + assert b == 73110 diff --git a/2019-python/output/day_10.py b/2019-python/output/day_10.py index ffaaa37..4e8fcc2 100644 --- a/2019-python/output/day_10.py +++ b/2019-python/output/day_10.py @@ -1,28 +1,31 @@ from collections import OrderedDict, defaultdict, deque from math import atan2 -from output import answer, puzzleinput + +from output import answer n = 10 title = "Monitoring Station" -@puzzleinput(n) -def parse_input(data): - return data.strip().split() - - @answer(1, "The monitor station will see {} asteroids at best") -def part_1(matrix): - _pos, visible = _map_visible_asteroids(matrix) - return len(set(dict(visible).values())) +def part_1(o): + return o[0] @answer( 2, "The asteroid at y=3 x=17 (checksum {}) will be the 200th lazer vapored asteroid, making some elf happy", ) -def part_2(matrix): +def part_2(o): + return o[1] + + +def solve(data): + matrix = data.strip().split() pos, visible = _map_visible_asteroids(matrix) + + p1 = len(set(dict(visible).values())) + targets_upper = defaultdict(list) targets_lower = defaultdict(list) targets = dict() @@ -58,7 +61,10 @@ def part_2(matrix): break if not popped: break - return x * 100 + y + + p2 = x * 100 + y + + return p1, p2 def _map_visible_asteroids(matrix): @@ -78,6 +84,13 @@ def _map_visible_asteroids(matrix): if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) + with open("./input/10.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 292 + assert b == 317 diff --git a/2019-python/output/day_11.py b/2019-python/output/day_11.py index 6f4d790..683656a 100644 --- a/2019-python/output/day_11.py +++ b/2019-python/output/day_11.py @@ -1,16 +1,12 @@ from collections import defaultdict + +from output import answer from output.intcode_computer import execute, parse -from output import answer, puzzleinput n = 11 title = "Space Police" -@puzzleinput(n) -def parse_input(data): - return parse(data) - - DIRS = [ (-1, 0), (0, -1), @@ -26,18 +22,28 @@ TL = ["RIGHT", "LEFT"] @answer(1, "[intcode 0.3.2] Robot paints {} panes at least once") -def part_1(program): - path, pos, d = _paint(program) - return len(path) +def part_1(o): + return o[0] @answer( 2, - '[intcode 0.3.2] The hull has registration identifier "JZPJRAGJ" freshly painted, see below: \n\n{}', + '[intcode 0.3.2] The hull has registration identifier "{}" freshly painted, see above', ) -def part_2(program): +def part_2(o): + return o[1] + + +def solve(data): + program = parse(data) + path, pos, d = _paint(program) + p1 = len(path) + path, pos, d = _paint(program, 1) - return _inspect(path.copy(), pos, d) + print(_inspect(path.copy(), pos, d)) + p2 = "JZPJRAGJ" + + return p1, p2 def _paint(program, initial=0): @@ -77,6 +83,13 @@ def _inspect(path, p, d): if __name__ == "__main__": - parsed = parse_input() - part_1(parsed) - part_2(parsed) # JZPJRAGJ + with open("./input/11.txt", "r") as f: + inp = f.read().strip() + + inp = solve(inp) + + a = part_1(inp) + b = part_2(inp) + + assert a == 2720 + assert b == "JZPJRAGJ" diff --git a/2019-python/output/intcode_computer.py b/2019-python/output/intcode_computer.py index 240bf7c..418ee32 100644 --- a/2019-python/output/intcode_computer.py +++ b/2019-python/output/intcode_computer.py @@ -1,5 +1,7 @@ +import sys from collections import defaultdict +sys.set_int_max_str_digits(999_999) """ intcode computer, AoC 2019 @@ -91,7 +93,7 @@ __version__ = "0.3.3" def parse(data): - return list(map(int, data.split(","))) + return [int(s) for s in data.split(",")] def execute(