Lint and Refactor day 1-11

This commit is contained in:
Anders Englöf Ytterström 2023-12-19 18:34:03 +01:00
parent 5cb2dccf62
commit 051c3f3ebd
14 changed files with 422 additions and 254 deletions

View file

@ -1,5 +1,12 @@
import os
import sys 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 year = 2019
try: try:
@ -19,48 +26,54 @@ if day_no and name:
with open("output/day_{}.py".format(padded_no), "w") as s: with open("output/day_{}.py".format(padded_no), "w") as s:
s.write( s.write(
f""" f"""
from output import answer, puzzleinput from output import answer # , matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg
n = {day_no} n = {day_no}
title = "{name}" title = "{name}"
@puzzleinput(n)
def parse_input(data):
return data
@answer(1, "Answer is {{}}") @answer(1, "Answer is {{}}")
def part_1(data): def part_1(outputs):
return data return outputs[0]
@answer(2, "Actually, answer is {{}}") @answer(2, "Actually, answer is {{}}")
def part_2(data): def part_2(outputs):
return data return outputs[1]
def solve(data):
return None, None
if __name__ == "__main__": if __name__ == "__main__":
# use dummy data # use dummy data
parsed = \"\"\" inp = \"\"\"
replace me replace me
\"\"\".strip() \"\"\".strip()
# uncomment to instead use stdin # uncomment to instead use stdin
# import fileinput # import sys; inp = sys.stdin.read().strip()
# parsed = "\\n".join(list(fileinput.input()))
# uncomment to instead use content of input/{padded_no}.txt # uncomment to use AoC provided puzzle input
# parsed = parse_input() # with open("./input/{padded_no}.txt", "r") as f:
# inp = f.read().strip()
part_1(parsed) inp = solve(inp)
# part_2(parsed)
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() """.strip()
+ "\n" + "\n"
) )
print(f"- creating empty input/{day_no.zfill(2)}.txt") print("- making sure input dir exists")
with open("input/{}.txt".format(day_no.zfill(2)), "w") as i: if not os.path.exists("input"):
i.write("") os.makedirs("input")
print( print(
f""" f"""
@ -75,28 +88,34 @@ https://adventofcode.com/{year}/day/{day_no}/input
) )
exit(0) exit(0)
from output import headline
stars = 0 stars = 0
for i in [str(n).zfill(2) for n in range(1, 26)]: for i in [str(n).zfill(2) for n in range(1, 26)]:
try: if not day_no or day_no.zfill(2) == i:
day = __import__( try:
"output.day_{}".format(i), day = __import__(
globals(), "output.day_{}".format(i),
locals(), globals(),
["n", "title", "part_1", "part_2", "parse_input"], locals(),
0, ["n", "title", "part_1", "part_2", "solve"],
) 0,
headline(day.n, day.title) )
data = day.parse_input() with open(f"./input/{i}.txt", "r") as f:
day.part_1(data, decorate=True) data = f.read().strip()
stars += 1 headline(day.n, day.title)
day.part_2(data, decorate=True) try:
stars += 1 data = day.solve(data)
except IOError: except AttributeError:
pass pass
except ImportError: if day.part_1(data, decorate=True):
pass stars += 1
print(f"\nStars: {stars}") if day.part_2(data, decorate=True):
print("".join("*" if n <= stars else "" for n in range(50))) 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("") print("")

View file

@ -1,26 +1,38 @@
import functools 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): # Directions for 2D matrices, as a dict with keys U, R, D, L
filename = str(n).zfill(2) DD = {
trim_input = kwargs.get("trim_input", True) "U": (-1, 0),
filepath = f"./input/{filename}.txt" "R": (0, 1),
"D": (1, 0),
"L": (0, -1),
}
def decorator_pi(func): # Adjacent relative positions including diagonals for 2D matrices, in the order NW, N, NE, W, E, SW, S, SE
@functools.wraps(func) ADJ = [
def wrapper_pi(*args, **kwargs): (-1, -1),
with open(filepath, "r") as f: (-1, 0),
data = f.read() (1, -1),
if trim_input: (0, -1),
return func(data.strip(), *args, **kwargs) (0, 1),
return func(data, *args, **kwargs) (1, 1),
(1, 0),
return wrapper_pi (1, -1),
]
return decorator_pi
def answer(part_index, fmt_string): def answer(part_index, fmt_string):
"""Decorator to present a solution in a human readable format"""
def decorator_aoc(func): def decorator_aoc(func):
@functools.wraps(func) @functools.wraps(func)
def wrapper_aoc(*args, **kwargs): def wrapper_aoc(*args, **kwargs):
@ -32,7 +44,7 @@ def answer(part_index, fmt_string):
print(answer) print(answer)
else: else:
formatted = fmt_string.format(answer) formatted = fmt_string.format(answer)
print(f"[part {part_index}] {formatted}") print(f" {part_index}) {formatted}")
return answer return answer
return wrapper_aoc return wrapper_aoc
@ -40,6 +52,31 @@ def answer(part_index, fmt_string):
return decorator_aoc return decorator_aoc
def headline(n, title): def ints(s):
title = f"Day {n}: {title}" """Extract all integers from a string"""
print("\n".join(["", title, "".join("-" for _ in title), ""])) 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)]))

View file

@ -1,32 +1,40 @@
from output import answer, puzzleinput from output import answer
n = 1 n = 1
title = "The Tyranny of the Rocket Equation" 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 {}") @answer(1, "Total fuel requirements are {}")
def part_1(lines): def part_1(o):
return sum(n // 3 - 2 for n in lines) return o[0]
@answer(2, "Total fuel requirements are {} including fuel costs") @answer(2, "Total fuel requirements are {} including fuel costs")
def part_2(lines): def part_2(o):
s = 0 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: for fuel in lines:
rem = fuel rem = fuel
while rem > 0: while rem > 0:
cost = rem // 3 - 2 cost = rem // 3 - 2
s += max(0, cost) p2 += max(0, cost)
rem = max(0, cost) rem = max(0, cost)
return s return p1, p2
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/01.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 3393938
assert b == 5088037

View file

@ -1,35 +1,48 @@
from output import answer, puzzleinput from output import answer
from output.intcode_computer import execute, parse from output.intcode_computer import execute, parse
n = 2 n = 2
title = "1202 Program Alarm" 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") @answer(1, "[intcode-0.1.0] Value of pos 0 is {} at halt signal")
def part_1(program): def part_1(o):
program[1] = 12 return o[0]
program[2] = 2
_code, state, *_unused = execute(program)
return state[0]
@answer(2, "[intcode-0.1.1] 100 * noun + verb = {} for output 19690720") @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[1] = noun
program[2] = verb program[2] = verb
_code, state, *_unused = execute(program) _code, state, *_unused = execute(program)
p2 = state[0]
if state[0] == 19690720: if state[0] == 19690720:
return 100 * noun + verb p2 = 100 * noun + verb
return state[0]
return p1, p2
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/02.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed, 76, 21) # found manually by binary search
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 3306701
assert b == 7621

View file

@ -1,5 +1,6 @@
from collections import defaultdict from collections import defaultdict
from output import answer, puzzleinput
from output import answer
n = 3 n = 3
title = "Crossed Wires" title = "Crossed Wires"
@ -12,37 +13,24 @@ directions = {
} }
@puzzleinput(n)
def parse_input(data):
return [line.split(",") for line in data.split()]
@answer( @answer(
1, "As the crow flies, closest intersection Manhattan distance is {} units away" 1, "As the crow flies, closest intersection Manhattan distance is {} units away"
) )
def part_1(wires): def part_1(o):
def follow(instructions): return o[0]
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)
@answer(2, "By travel, closest intersection Manhattan distance is {} units away") @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) seen = defaultdict(dict)
def follow(instructions, i): def follow(instructions, i):
visited = []
steps = 0 steps = 0
pos = (0, 0) pos = (0, 0)
for instruction in instructions: for instruction in instructions:
@ -51,16 +39,29 @@ def part_2(wires):
for _ in range(distance): for _ in range(distance):
steps += 1 steps += 1
pos = (pos[0] + directions[urdl][0], pos[1] + directions[urdl][1]) pos = (pos[0] + directions[urdl][0], pos[1] + directions[urdl][1])
visited.append(pos)
if i not in seen[pos]: if i not in seen[pos]:
seen[pos][i] = steps seen[pos][i] = steps
return set(visited)
p1w = []
for i, wire in enumerate(wires): 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__": if __name__ == "__main__":
parsed = parse_input() with open("./input/03.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 1337
assert b == 65356

View file

@ -1,36 +1,44 @@
from collections import Counter from collections import Counter
from output import answer, puzzleinput
from output import answer
n = 4 n = 4
title = "Secure Container" title = "Secure Container"
@puzzleinput(n)
def parse_input(data):
return data.split("-")
@answer(1, "{} combinations of valid passwords") @answer(1, "{} combinations of valid passwords")
def part_1(range_values): def part_1(o):
a, b = range_values return o[0]
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))
@answer(2, "{} combinations of valid passwords, including important detail") @answer(2, "{} combinations of valid passwords, including important detail")
def part_2(range_values): def part_2(o):
a, b = range_values 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 "".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__": if __name__ == "__main__":
parsed = parse_input() with open("./input/04.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 544
assert b == 334

View file

@ -1,29 +1,40 @@
from output import answer, puzzleinput from output import answer
from output.intcode_computer import execute, parse from output.intcode_computer import execute, parse
n = 5 n = 5
title = "Sunny with a Chance of Asteroids" 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: {}") @answer(1, "[intcode-0.2.0] Program diagnostic code, ID 1: {}")
def part_1(program): def part_1(o):
_code, _state, _cursorpos, rb, stdout = execute(program, stdin=[1]) return o[0]
return max(stdout)
@answer(2, "[intcode-0.2.1] Program diagnostic code, ID 5: {}") @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]) _code, _state, _cursorpos, rb, stdout = execute(program, stdin=[5])
return stdout[0] p2 = stdout[0]
return p1, p2
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/05.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 16434972
assert b == 16694270

View file

@ -1,35 +1,40 @@
from collections import defaultdict, deque from collections import defaultdict
from output import answer, puzzleinput
from output import answer
n = 6 n = 6
title = "Universal Orbit Map" 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") @answer(1, "{} direct and indirect orbits")
def part_1(heritage): def part_1(o):
return sum(len(ancestry(heritage, v)) for v in heritage.keys()) return o[0]
@answer(2, "Orbit transfers needed for you to share orbit with Santa: {}") @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") a = ancestry(heritage, "YOU")
b = ancestry(heritage, "SAN") b = ancestry(heritage, "SAN")
shared = len(set(a) & set(b)) shared = len(set(a) & set(b))
return sum( p2 = sum(
[ [
len(a) - shared, len(a) - shared,
len(b) - shared, len(b) - shared,
] ]
) )
return p1, p2
def ancestry(parents, child): def ancestry(parents, child):
k = child k = child
@ -41,6 +46,13 @@ def ancestry(parents, child):
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/06.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 271151
assert b == 388

View file

@ -1,23 +1,32 @@
from collections import defaultdict from collections import defaultdict
from itertools import permutations from itertools import permutations
from output import answer, puzzleinput from output import answer
from output.intcode_computer import execute, parse from output.intcode_computer import execute, parse
n = 7 n = 7
title = "Amplification Circuit" title = "Amplification Circuit"
@puzzleinput(n)
def parse_input(data):
return parse(data)
@answer( @answer(
1, 1,
"[intcode 0.3.0] The highest achievable signal to the thruster is {}", "[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 = [] thruster_signals = []
for settings in map(list, permutations(range(5))): for settings in map(list, permutations(range(5))):
o = 0 o = 0
@ -25,14 +34,8 @@ def part_1(program):
_code, _state, _n, _rb, so = execute(program, stdin=[ps, o]) _code, _state, _n, _rb, so = execute(program, stdin=[ps, o])
o = so.pop(0) o = so.pop(0)
thruster_signals.append(o) 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 = [] thruster_signals = []
for settings in map(list, permutations(range(5, 10))): for settings in map(list, permutations(range(5, 10))):
o = [0] o = [0]
@ -56,10 +59,19 @@ def part_2(program):
finished.add(amp) finished.add(amp)
o = so o = so
thruster_signals.append(o[-1]) thruster_signals.append(o[-1])
return max(thruster_signals) p2 = max(thruster_signals)
return p1, p2
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/07.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 398674
assert b == 39431233

View file

@ -1,38 +1,50 @@
from collections import Counter from collections import Counter
from textwrap import wrap from textwrap import wrap
from output import answer, puzzleinput
from output import answer
n = 8 n = 8
title = "Space Image Format" 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 {}") @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"]) layers = sorted(map(Counter, wrap(data, 25 * 6)), key=lambda c: c["0"])
width, height = 25, 6
a = layers[0]["1"] a = layers[0]["1"]
b = layers[0]["2"] 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) layers = wrap(data, width * height)
l = len(layers)
pixels = zip(*layers) pixels = zip(*layers)
lit = map( lit = map(
lambda s: s.replace("0", ".").replace("1", "#"), lambda s: s.replace("0", ".").replace("1", "#"),
map(lambda p: next(filter(lambda x: x != "2", p)), pixels), map(lambda p: next(filter(lambda x: x != "2", p)), pixels),
) )
matrix = "\n".join(wrap("".join(lit), width)) matrix = "\n".join(wrap("".join(lit), width))
return matrix print(matrix)
p2 = "CYUAH"
return p1, p2
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/08.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 2500
assert b == "CYUAH"

View file

@ -1,25 +1,27 @@
from output import answer, puzzleinput from output import answer
from output.intcode_computer import execute, parse from output.intcode_computer import execute, parse
n = 9 n = 9
title = "Sensor Boost" title = "Sensor Boost"
@puzzleinput(n)
def parse_input(data):
return parse(data)
@answer(1, "[intcode 0.3.1] BOOST keycode: {}") @answer(1, "[intcode 0.3.1] BOOST keycode: {}")
def part_1(program): def part_1(o):
_c, _s, _n, _rb, outputs = execute(program, stdin=[1]) return o[0]
return outputs.pop(0)
@answer(2, "[intcode 0.3.1] Distress signal coordinates: {}") @answer(2, "[intcode 0.3.1] Distress signal coordinates: {}")
def part_2(program): def part_2(o):
_c, _s, _n, _rb, outputs = execute(program, stdin=[2]) return o[1]
return outputs.pop(0)
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__": 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, 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 assert execute([109, 6, 21001, 9, 25, 1, 104, 0, 99, 49])[4][0] == 74
parsed = parse_input() with open("./input/09.txt", "r") as f:
assert execute(parsed, stdin=[1])[4][0] == 2351176124 inp = f.read().strip()
part_1(parsed) inp = solve(inp)
part_2(parsed)
a = part_1(inp)
b = part_2(inp)
assert a == 2351176124
assert b == 73110

View file

@ -1,28 +1,31 @@
from collections import OrderedDict, defaultdict, deque from collections import OrderedDict, defaultdict, deque
from math import atan2 from math import atan2
from output import answer, puzzleinput
from output import answer
n = 10 n = 10
title = "Monitoring Station" title = "Monitoring Station"
@puzzleinput(n)
def parse_input(data):
return data.strip().split()
@answer(1, "The monitor station will see {} asteroids at best") @answer(1, "The monitor station will see {} asteroids at best")
def part_1(matrix): def part_1(o):
_pos, visible = _map_visible_asteroids(matrix) return o[0]
return len(set(dict(visible).values()))
@answer( @answer(
2, 2,
"The asteroid at y=3 x=17 (checksum {}) will be the 200th lazer vapored asteroid, making some elf happy", "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) pos, visible = _map_visible_asteroids(matrix)
p1 = len(set(dict(visible).values()))
targets_upper = defaultdict(list) targets_upper = defaultdict(list)
targets_lower = defaultdict(list) targets_lower = defaultdict(list)
targets = dict() targets = dict()
@ -58,7 +61,10 @@ def part_2(matrix):
break break
if not popped: if not popped:
break break
return x * 100 + y
p2 = x * 100 + y
return p1, p2
def _map_visible_asteroids(matrix): def _map_visible_asteroids(matrix):
@ -78,6 +84,13 @@ def _map_visible_asteroids(matrix):
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/10.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed)
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 292
assert b == 317

View file

@ -1,16 +1,12 @@
from collections import defaultdict from collections import defaultdict
from output import answer
from output.intcode_computer import execute, parse from output.intcode_computer import execute, parse
from output import answer, puzzleinput
n = 11 n = 11
title = "Space Police" title = "Space Police"
@puzzleinput(n)
def parse_input(data):
return parse(data)
DIRS = [ DIRS = [
(-1, 0), (-1, 0),
(0, -1), (0, -1),
@ -26,18 +22,28 @@ TL = ["RIGHT", "LEFT"]
@answer(1, "[intcode 0.3.2] Robot paints {} panes at least once") @answer(1, "[intcode 0.3.2] Robot paints {} panes at least once")
def part_1(program): def part_1(o):
path, pos, d = _paint(program) return o[0]
return len(path)
@answer( @answer(
2, 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) 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): def _paint(program, initial=0):
@ -77,6 +83,13 @@ def _inspect(path, p, d):
if __name__ == "__main__": if __name__ == "__main__":
parsed = parse_input() with open("./input/11.txt", "r") as f:
part_1(parsed) inp = f.read().strip()
part_2(parsed) # JZPJRAGJ
inp = solve(inp)
a = part_1(inp)
b = part_2(inp)
assert a == 2720
assert b == "JZPJRAGJ"

View file

@ -1,5 +1,7 @@
import sys
from collections import defaultdict from collections import defaultdict
sys.set_int_max_str_digits(999_999)
""" """
intcode computer, AoC 2019 intcode computer, AoC 2019
@ -91,7 +93,7 @@ __version__ = "0.3.3"
def parse(data): def parse(data):
return list(map(int, data.split(","))) return [int(s) for s in data.split(",")]
def execute( def execute(