diff options
Diffstat (limited to 'solutions/py')
| -rw-r--r-- | solutions/py/d01.py | 28 | ||||
| -rw-r--r-- | solutions/py/d02.py | 49 | ||||
| -rw-r--r-- | solutions/py/d03.py | 84 | ||||
| -rw-r--r-- | solutions/py/d04.py | 65 | ||||
| -rw-r--r-- | solutions/py/d05.py | 34 | ||||
| -rw-r--r-- | solutions/py/d06.py | 87 | ||||
| -rw-r--r-- | solutions/py/d07.py | 80 | ||||
| -rw-r--r-- | solutions/py/d08.py | 38 | ||||
| -rw-r--r-- | solutions/py/d09.py | 27 | ||||
| -rw-r--r-- | solutions/py/d10.py | 261 | ||||
| -rw-r--r-- | solutions/py/d11.py | 165 | ||||
| -rw-r--r-- | solutions/py/d12.py | 124 | ||||
| -rw-r--r-- | solutions/py/d13.py | 132 | ||||
| -rw-r--r-- | solutions/py/d14.py | 77 | ||||
| -rw-r--r-- | solutions/py/d15.py | 276 | ||||
| -rw-r--r-- | solutions/py/d16.py | 46 | ||||
| -rw-r--r-- | solutions/py/d17.py | 317 | ||||
| -rw-r--r-- | solutions/py/intcode.py | 146 | ||||
| -rw-r--r-- | solutions/py/main.py | 52 |
19 files changed, 0 insertions, 2088 deletions
diff --git a/solutions/py/d01.py b/solutions/py/d01.py deleted file mode 100644 index d1c57c8..0000000 --- a/solutions/py/d01.py +++ /dev/null @@ -1,28 +0,0 @@ -import math -import sys - -def get_fuel(mass): - fuel = math.floor(mass / 3) - 2 - return 0 if fuel <= 0 else fuel + get_fuel(fuel) - -def pt1(_in): - s = 0 - for line in _in: - mass = int(line) - if mass == 0: - break - fuel = math.floor(mass / 3) - 2 - s += fuel - return s - -def pt2(input): - return sum([get_fuel(int(line)) for line in input]) - -if __name__ == "__main__": - import cProfile - - input = open("../input/01", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d02.py b/solutions/py/d02.py deleted file mode 100644 index 6b5aa0a..0000000 --- a/solutions/py/d02.py +++ /dev/null @@ -1,49 +0,0 @@ -import sys - -def pt1(input): - program = [int(x) for x in input[0].split(",")] - - memory = program.copy() - memory[1] = 12 - memory[2] = 2 - - pointer = 0 - while True: - if memory[pointer] == 99: - break - elif memory[pointer] == 1: - memory[memory[pointer+3]] = memory[memory[pointer+1]] + memory[memory[pointer+2]] - elif memory[pointer] == 2: - memory[memory[pointer+3]] = memory[memory[pointer+1]] * memory[memory[pointer+2]] - pointer += 4 - return memory[0] - -def pt2(input): - program = [int(x) for x in input[0].split(",")] - - for n in range(100): - for v in range(100): - memory = program.copy() - memory[1] = n - memory[2] = v - - pointer = 0 - while True: - if memory[pointer] == 99: - break - elif memory[pointer] == 1: - memory[memory[pointer+3]] = memory[memory[pointer+1]] + memory[memory[pointer+2]] - elif memory[pointer] == 2: - memory[memory[pointer+3]] = memory[memory[pointer+1]] * memory[memory[pointer+2]] - pointer += 4 - if memory[0] == 19690720: - return (n, v, n*100 + v) - -if __name__ == "__main__": - import cProfile - - input = open("../input/02", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d03.py b/solutions/py/d03.py deleted file mode 100644 index 2454cb3..0000000 --- a/solutions/py/d03.py +++ /dev/null @@ -1,84 +0,0 @@ -import math - -def intersection(l1, l2): - l1 = set(l1) - l2 = set(l2) - return [value for value in l2 if value in l1] - -def man_dist(point): - return abs(point[0]) + abs(point[1]) - -def pt1(input): - wire1 = [] - wire2 = [] - for wire, moves in zip((wire1, wire2), (input[0], input[1])): - x = 0 - y = 0 - dx = 0 - dy = 0 - for move in moves.split(","): - if move[0] == "D": - dx = 0 - dy = -1 - elif move[0] == "U": - dx = 0 - dy = 1 - elif move[0] == "R": - dx = 1 - dy = 0 - elif move[0] == "L": - dx = -1 - dy = 0 - for i in range(int(move[1:])): - x += dx - y += dy - wire.append((x, y)) - points = intersection(wire1, wire2) - dist = man_dist(points[0]) - for point in points[1:]: - dist = min(dist, man_dist(point)) - return dist - -def pt2(input): - wire1 = {} - wire2 = {} - # wire {(x,y) : dist} - for wire, moves in zip((wire1, wire2), (input[0], input[1])): - x = 0 - y = 0 - dx = 0 - dy = 0 - steps = 0 - for move in moves.split(","): - if move[0] == "D": - dx = 0 - dy = -1 - elif move[0] == "U": - dx = 0 - dy = 1 - elif move[0] == "R": - dx = 1 - dy = 0 - elif move[0] == "L": - dx = -1 - dy = 0 - for i in range(int(move[1:])): - x += dx - y += dy - steps += 1 - wire[(x, y)] = steps - - points = intersection(list(wire1.keys()), list(wire2.keys())) - length = wire1[points[0]] + wire2[points[0]] - for point in points[1:]: - length = min(length, wire1[point] + wire2[point]) - return length - -if __name__ == "__main__": - import cProfile - - input = open("../input/03", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d04.py b/solutions/py/d04.py deleted file mode 100644 index c9bcbf3..0000000 --- a/solutions/py/d04.py +++ /dev/null @@ -1,65 +0,0 @@ -from collections import Counter - -def isIncreasing(num): - s = list(str(num)) - n = int(s[0]) - n_i = 0 - for sp in s[1:]: - n_i += 1 - if int(sp) < n: - for i in range(n_i, 6): - s[i] = str(n) - return False, int("".join(s)) - n = int(sp) - return (True,) - -def pt1(input): - def containsDouble(num): - s = str(num) - amounts = [0 for _ in range(10)] - for c in s: - amounts[int(c)] += 1 - c = Counter(amounts) - return c[0] + c[1] < 10 - - amount = 0 - n = 357253 - while n < 892942 + 1: - inc = isIncreasing(n) - if inc[0] == True: - if containsDouble(n): - amount += 1 - n += 1 - else: - n = inc[1] - return amount - -def pt2(input): - def containsDouble(num): - s = str(num) - amounts = [0 for _ in range(10)] - for c in s: - amounts[int(c)] += 1 - c = Counter(amounts) - if c[0] + c[1] < 10: - return c[2] >= 1 - - amount = 0 - n = 357253 - while n < 892942 + 1: - inc = isIncreasing(n) - if inc[0] == True: - if containsDouble(n): - amount += 1 - n += 1 - else: - n = inc[1] - return amount - -if __name__ == "__main__": - import cProfile - - cProfile.run("pt1([])") - cProfile.run("pt2([])") - print(pt1([])) - print(pt2([])) diff --git a/solutions/py/d05.py b/solutions/py/d05.py deleted file mode 100644 index 1415b99..0000000 --- a/solutions/py/d05.py +++ /dev/null @@ -1,34 +0,0 @@ -import intcode - -def pt1(input): - program = [int(x) for x in input[0].split(",")] - c = intcode.Computer(program) - c.input = 1 - output = [] - while c.memory[c.pointer] != 99: - c.step() - if c.output != None: - output.append(c.output) - c.output = None - return output - -def pt2(input): - program = [int(x) for x in input[0].split(",")] - c = intcode.Computer(program) - c.input = 5 - output = [] - while c.memory[c.pointer] != 99: - c.step() - if c.output != None: - output.append(c.output) - c.output = None - return output - -if __name__ == "__main__": - import cProfile - - input = open("../input/05", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d06.py b/solutions/py/d06.py deleted file mode 100644 index 0b54362..0000000 --- a/solutions/py/d06.py +++ /dev/null @@ -1,87 +0,0 @@ -from typing import Iterable -import sys - -class Tree(object): - # https://stackoverflow.com/a/28015122 - def __init__(self, name='root', children=None): - self.name = name - self.children = [] - self.parent = None - if children is not None: - for child in children: - self.add_child(child) - def add_child(self, node): - self.children.append(node) - node.parent = self - - def __eq__(self, other): - if isinstance(other, Tree): - return self.name == other.name - return False - def parents(self): - return [self.parent] + self.parent.parents() if self.parent != None\ - else [] - -def gen_tree(input): - trees = {} - seen = set() # seen trees. contains only IDs - leafs = {} - - for orbit in input: - orbit = orbit.split(")") - #print(orbit) - if not orbit[0] in seen: - trees[orbit[0]] = Tree(orbit[0]) - seen.add(orbit[0]) - - # hook up each child to its parent (since every parent now exists) - for orbit in input: - orbit = orbit.rstrip().split(")") - if orbit[1] in seen: - trees[orbit[0]].add_child(trees[orbit[1]]) - else: - leafs[orbit[1]] = Tree(orbit[1]) - trees[orbit[0]].add_child(leafs[orbit[1]]) - for k in trees: - pass - #print(trees[k], trees[k].children) - - trees.update(leafs) - return trees - -sum_depths = 0 -def pt1(input): - tree = gen_tree(input) - depth = 0 - depths = {} - def count_children(tree, depth): - global sum_depths # fusk-rekursion? ville bara att det skulle fungera - sum_depths += depth - depths[tree.name] = depth - for child in tree.children: - count_children(child, depth+1) - count_children(tree["COM"], 0) - return sum_depths - -def pt2(input): - # find common parent and distance to it - tree = gen_tree(input) - src_parents = tree["YOU"].parent.parents() - tar_parents = tree["SAN"].parent.parents() - src_dist = 0 - for src_parent in src_parents: - src_dist += 1 - tar_dist = 0 - for tar_parent in tar_parents: - tar_dist += 1 - if src_parent == tar_parent: - return (src_parent.name, src_dist, tar_dist, src_dist + tar_dist) - -if __name__ == "__main__": - import cProfile - - input = open("../input/06", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d07.py b/solutions/py/d07.py deleted file mode 100644 index 7ab2fe6..0000000 --- a/solutions/py/d07.py +++ /dev/null @@ -1,80 +0,0 @@ -import intcode -import itertools -import queue - -def pt1(input): - program = [int(x) for x in input[0].split(",")] - highest_signal = 0 - highest_sequence = None - for phase_seq in list(itertools.permutations(list(range(0,5)))): - q = queue.Queue(5) - for phase in phase_seq: - q.put(phase) - amps = [intcode.Computer(program) for _ in range(5)] - for amp in amps: - amp.input = q.get() - signal = 0 - for amp in amps: - while True: - amp.step() - if amp.input is None: - amp.input = signal - if amp.output is not None: - signal = amp.output - amp.output = None - break - if signal > highest_signal: - highest_signal = signal - highest_sequence = phase_seq - return (highest_sequence, highest_signal) - -def pt2(input): - program = [int(x) for x in input[0].split(",")] - highest_signal = 0 - highest_sequence = None - for phase_seq in list(itertools.permutations(list(range(5,10)))): - q = queue.Queue(5) - for phase in phase_seq: - q.put(phase) - amps = [intcode.Computer(program) for _ in range(5)] - for amp in amps: - amp.input = q.get() - - signal = 0 - current_amp = 0 - while True: - amp = amps[current_amp] - amp.step() - if amp.input is None: - if amp.phase_read == False: - amp.phase_read = True - amp.input = signal - else: - pass - if amp.output is not None: - signal = amp.output - amp.output = None - current_amp = (current_amp + 1) % 5 - if amps[current_amp].phase_read == True: - amps[current_amp].input = signal - continue - if amp.memory[amp.pointer] == 99: - if current_amp == 4: - break - current_amp = (current_amp + 1) % 5 - amps[current_amp].input = signal - continue - if signal > highest_signal: - highest_signal = signal - highest_sequence = phase_seq - return (highest_sequence, highest_signal) - -if __name__ == "__main__": - import cProfile - - input = open("../input/07", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) - diff --git a/solutions/py/d08.py b/solutions/py/d08.py deleted file mode 100644 index 7df2aec..0000000 --- a/solutions/py/d08.py +++ /dev/null @@ -1,38 +0,0 @@ -def count(layer, num): - return sum([row.count(num) for row in layer]) - -def pt1(input): - img = [] - least_zeroes = 150 # max - n = 0 - for l in range(100): - layer = [[int(input[0][l*25*6 + y*25 + x]) for x in range(25)] for y in range(6)] - if count(layer, 0) < least_zeroes: - least_zeroes = count(layer, 0) - n = count(layer, 1) * count(layer, 2) - img.append(layer) - return n - -def pt2(input): - img = [[[int(input[0][l*25*6 + y*25 + x]) for x in range(25)] for y in range(6)] for l in range(100)] - result = img[0] - for layer in img[1:]: - for x in range(25): - for y in range(6): - if result[y][x] == 2: - result[y][x] = layer[y][x] - str_res = [] - for row in result: - str_res.append("\n ") - for c in row: - str_res.append('\u2588' if c == 1 else ' ') - return "".join(str_res) - -if __name__ == "__main__": - import cProfile - - input = open("../input/08", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d09.py b/solutions/py/d09.py deleted file mode 100644 index ada6763..0000000 --- a/solutions/py/d09.py +++ /dev/null @@ -1,27 +0,0 @@ -import intcode - -def do(input, code): - program = [int(x) for x in input.split(",")] - c = intcode.Computer(program) - c.input = code - output = [] - while True: - c.step() - #print(c.relative_base, c.pointer, c.memory) - if c.SIG_HALT: - break - if c.output is not None: - output.append(c.output) - c.output = None - return output - -def pt1(input): - return do(input[0], 1) - -def pt2(input): - return do(input[0], 2) - -if __name__ == "__main__": - input = open("../input/09", "r").readlines() - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d10.py b/solutions/py/d10.py deleted file mode 100644 index 0d918d9..0000000 --- a/solutions/py/d10.py +++ /dev/null @@ -1,261 +0,0 @@ -import math -import os -import queue -import sys -import time - -def red(dcoord): - dx = dcoord[0] - dy = dcoord[1] - if dx == 0: - return (0, (1 if dy > 0 else -1)) - if dy == 0: - return ((1 if dx > 0 else -1), 0) - gcd = math.gcd(dx, dy) - return (dx // gcd, dy // gcd) - -def angle(x, y): # from y-axis, clockwise - if x >= 0 and y > 0: - return math.atan(abs(x/y)) - if x > 0 and y <= 0: - return math.atan(abs(y/x)) + math.pi/2 - if x <= 0 and y < 0: - return math.atan(abs(x/y)) + math.pi - else: - return math.atan(abs(y/x)) + 3*math.pi / 2 - -def pt1(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - for a in asteroids: - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - return (best[1], best[0]) - -def pt2(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - for a in asteroids: - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - asteroids.remove(best[1]) - x0 = best[1][0] - y0 = best[1][1] - - angles = {} - q = queue.Queue() - for a in asteroids: - angles[a] = angle(a[0] - x0, y0 - a[1]) - - for k, v in sorted(angles.items(), key=lambda item: item[1]): - if k in best[2]: - q.put(k) - - destroyed = 1 - while not q.empty(): - asteroid = q.get() - if destroyed == 200: - return (asteroid, asteroid[0]*100 + asteroid[1]) - asteroids.remove(asteroid) - destroyed += 1 - - # add next asteroid behind to queue - dx = asteroid[0] - x0 - dy = asteroid[1] - y0 - x = x0 - y = y0 - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in asteroids: - q.put((x, y)) - break - x += dx - y += dy - -def print_map(coords, w, h): - time.sleep(0.01) - os.system("clear") - s = "" - for y in range(w): - for x in range(h): - s += (coords[(x, y)] + " ") if (x,y) in coords else " " - s += "\n" - print(s) - -def visualize(input): - asteroids = set() - res = {} - - max_x = len(input[0].rstrip()) - max_y = len(input) - - for y in range(max_y): - for x in range(max_x): - if input[y][x] == "#": - asteroids.add((x,y)) - - #print_map(asteroids, max_x, max_y) - - for a in asteroids: - print(a) - time.sleep(3) - candidates = set(asteroids.copy()) - candidates.remove(a) - seen = set() - while len(candidates) > 0: - #print(len(candidates)) - time.sleep(0.02) - union = {a: "\u2588"} - for c in candidates: - union[c] = "C" - for s in seen: - union[s] = "s" - print_map(union, max_x, max_y) - c = candidates.pop() - seen.add(c) - dx = c[0] - a[0] - dy = c[1] - a[1] - x = a[0] - y = a[1] - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in candidates: - candidates.remove((x, y)) - if (x, y) in seen: - seen.remove((x, y)) - x += dx - y += dy - res[a] = seen - - best = [0, 0, 0] - for coord in res: - amount = len(res[coord]) - if amount > best[0]: - best = [amount, coord, res[coord]] - asteroids.remove(best[1]) - x0 = best[1][0] - y0 = best[1][1] - - angles = {} - q = queue.Queue() - for a in asteroids: - angles[a] = angle(a[0] - x0, y0 - a[1]) - - for k, v in sorted(angles.items(), key=lambda item: item[1]): - if k in best[2]: - q.put(k) - - destroyed = 1 - while not q.empty(): - #print_map(asteroids, max_x, max_y) - asteroid = q.get() - if destroyed == 200: - return (asteroid, asteroid[0]*100 + asteroid[1]) - asteroids.remove(asteroid) - destroyed += 1 - - # add next asteroid behind to queue - dx = asteroid[0] - x0 - dy = asteroid[1] - y0 - x = x0 - y = y0 - x += dx - y += dy - dx, dy = red((dx, dy)) - x += dx - y += dy - while x < max_x and y < max_y and x >= 0 and y >= 0: - if (x, y) in asteroids: - q.put((x, y)) - break - x += dx - y += dy -if __name__ == "__main__": - import cProfile - - input = open("../input/10","r").readlines() - visualize(input) - #cProfile.run("pt1(input)") - #cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d11.py b/solutions/py/d11.py deleted file mode 100644 index e9b280c..0000000 --- a/solutions/py/d11.py +++ /dev/null @@ -1,165 +0,0 @@ -import intcode -import time - - -def draw(colors, ship, direction): - min_x, max_x, min_y, max_y = 0, 0, 0, 0 - ship_c = "" - if direction == 0: - ship_c = "^" - elif direction == 1: - ship_c = "<" - elif direction == 2: - ship_c = "v" - elif direction == 3: - ship_c = ">" - for color in colors: - min_x = min(min_x, color[0]) - max_x = max(max_x, color[0]) - min_y = min(min_y, color[1]) - max_y = max(max_y, color[1]) - s = "" - for y in range(min_y, max_y+1): - s += "\n" - for x in range(min_x, max_x+1): - if (x,y) == ship: - s += ship_c - elif (x,y) in colors: - c = colors[(x,y)] - s += "\u2588" if c == 1 else " " - else: - s += "." - return s - -def pt1(input): - program = [int(x) for x in input[0].split(",")] - x=y = 0 - direction = 0 - # 0 is up - # 1 is left - # 2 is down - # 3 is right - # 4 is up (again) - # turning left is direction += 1 - # turning right is direction -= 1 - # direction is direction % 4 - colors = {} # (x,y): 1/0 (1 = white, 0 = black) - - got_color = False - c = intcode.Computer(program) - while c.memory[c.pointer] != 99: - # input - #print(x, y) - #draw(colors, (x,y), direction % 4) - #input() - #time.sleep(0.1) - c.input = colors.get((x, y), 0) - c.step() - if c.output is not None: - if not got_color: - colors[(x, y)] = c.output - c.output = None - got_color = True - elif got_color: - direction += (1 if c.output == 0 else -1) - dir = direction % 4 - if dir == 0: - y -= 1 - elif dir == 1: - x -= 1 - elif dir == 2: - y += 1 - elif dir == 3: - x += 1 - got_color = False - c.output = None - return len(colors) - -def pt2(input): - program = [int(x) for x in input[0].split(",")] - x=y = 0 - direction = 0 - # 0 is up - # 1 is left - # 2 is down - # 3 is right - # 4 is up (again) - # turning left is direction += 1 - # turning right is direction -= 1 - # direction is direction % 4 - colors = {(0,0): 1} # (x,y): 1/0 (1 = white, 0 = black) - - got_color = False - c = intcode.Computer(program) - while c.memory[c.pointer] != 99: - c.input = colors.get((x, y), 0) - c.step() - if c.output is not None: - if not got_color: - colors[(x, y)] = c.output - c.output = None - got_color = True - elif got_color: - direction += (1 if c.output == 0 else -1) - dir = direction % 4 - if dir == 0: - y -= 1 - elif dir == 1: - x -= 1 - elif dir == 2: - y += 1 - elif dir == 3: - x += 1 - got_color = False - c.output = None - return draw(colors, (0,0), 0) - -def visualize(input): - program = [int(x) for x in input[0].split(",")] - x=y = 0 - direction = 0 - # 0 is up - # 1 is left - # 2 is down - # 3 is right - # 4 is up (again) - # turning left is direction += 1 - # turning right is direction -= 1 - # direction is direction % 4 - colors = {(0,0): 1} # (x,y): 1/0 (1 = white, 0 = black) - - got_color = False - c = intcode.Computer(program) - while c.memory[c.pointer] != 99: - time.sleep(0.002) - print(draw(colors, (x,y), direction % 4)) - c.input = colors.get((x, y), 0) - c.step() - if c.output is not None: - if not got_color: - colors[(x, y)] = c.output - c.output = None - got_color = True - elif got_color: - direction += (1 if c.output == 0 else -1) - dir = direction % 4 - if dir == 0: - y -= 1 - elif dir == 1: - x -= 1 - elif dir == 2: - y += 1 - elif dir == 3: - x += 1 - got_color = False - c.output = None - -if __name__ == "__main__": - import cProfile - - input = open("../input/11", "r").readlines() - cProfile.run("pt1(input)") - cProfile.run("pt2(input)") - print(pt1(input)) - print(pt2(input)) - visualize(input) diff --git a/solutions/py/d12.py b/solutions/py/d12.py deleted file mode 100644 index 3d2b636..0000000 --- a/solutions/py/d12.py +++ /dev/null @@ -1,124 +0,0 @@ -import itertools -import primefac - -class Moon(object): - def __init__(self, x, y, z): - self.x = x - self.y = y - self.z = z - self.dx = 0 - self.dy = 0 - self.dz = 0 - - def step(self): - self.x += self.dx - self.y += self.dy - self.z += self.dz - - def gx(self, other): - if self.x < other.x: - self.dx += 1 - other.dx -= 1 - - def gy(self, other): - if self.y < other.y: - self.dy += 1 - other.dy -= 1 - - def gz(self, other): - if self.z < other.z: - self.dz += 1 - other.dz -= 1 - - def gravity(self, other): - self.gx(other) - self.gy(other) - self.gz(other) - - def get_x(self): - return self.x, self.dx - - def get_y(self): - return self.y, self.dy - - def get_z(self): - return self.z, self.dz - - def get(self): - return self.get_x, self.get_y, self.get_z - -def pt1(input): - moons = [] - - for line in input: - dims = line.rstrip().split(",") - x = int(dims[0][3:]) - y = int(dims[1][3:]) - z = int(dims[2][3:-1]) - moons.append(Moon(x, y, z)) - - for _ in range(1000): - for pair in itertools.permutations(moons, 2): - pair[0].gravity(pair[1]) - for moon in moons: - moon.step() - - tot = 0 - for moon in moons: - pot = abs(moon.x) + abs(moon.y) + abs(moon.z) - kin = abs(moon.dx) + abs(moon.dy) + abs(moon.dz) - tot += pot*kin - return tot - -def get_cycle(init_pos, init_vel): - initial = tuple(init_pos) - pos = init_pos.copy() - vel = init_vel.copy() - iters = 0 - while 1: - for i, j in itertools.permutations(range(4), 2): - if i == j: - continue - if pos[i] < pos[j]: - vel[i] += 1 - vel[j] -= 1 - for i in range(4): - pos[i] += vel[i] - iters += 1 - if pos[0] == initial[0] and pos[1] == initial[1] and \ - pos[2] == initial[2] and pos[3] == initial[3] and \ - vel[0] == 0 and vel[1] == 0 and \ - vel[2] == 0 and vel[3] == 0: - return iters - -def pt2(input): - moons = [] - xs = 0 - ys = 0 - zs = 0 - - for line in input: - dims = line.rstrip().split(",") - x = int(dims[0][3:]) - y = int(dims[1][3:]) - z = int(dims[2][3:-1]) - moons.append(Moon(x, y, z)) - - xs = get_cycle([moon.x for moon in moons], [0 for _ in range(4)]) - ys = get_cycle([moon.y for moon in moons], [0 for _ in range(4)]) - zs = get_cycle([moon.z for moon in moons], [0 for _ in range(4)]) - - factors = [primefac.factorint(n) for n in (xs, ys, zs)] - nums = {} - for factor in factors: - for n in factor: - nums[n] = max(nums.get(n, 0), factor[n]) - ans = 1 - for n in nums: - ans *= n ** nums[n] - return ans - -if __name__ == "__main__": - input = open("../input/12", "r").readlines() - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d13.py b/solutions/py/d13.py deleted file mode 100644 index 3dbc5fb..0000000 --- a/solutions/py/d13.py +++ /dev/null @@ -1,132 +0,0 @@ -import intcode -import queue -import time - -def pt1(input): - c = intcode.Computer([int(x) for x in input[0].split(",")]) - buffer_out = [] - screen = {} - while c.memory[c.pointer] != 99: - c.step() - if c.output is not None: - buffer_out.append(c.output) - c.output = None - if len(buffer_out) == 3: - screen[(buffer_out[0], buffer_out[1])] = buffer_out[2] - buffer_out = [] - blocks = 0 - for p in screen: - if screen[p] == 2: - blocks += 1 - return blocks - - -def pt2(input): - def draw(screen, points): - ball_x = 0 - paddle_x = 0 - min_x = max_x = min_y = max_y = 0 - for p in screen: - if p == (-1,0): - points = screen[p] - elif screen[p] == 3: - paddle_x = p[0] - elif screen[p] == 4: - ball_x = p[0] - return points, ball_x, paddle_x - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - c.memory[0] = 2 - - screen = {} - buffer_out = [] - points = 0 - ball_x = paddle_x = 0 - - while c.memory[c.pointer] != 99: - if c.SIG_INPUT: - points, ball_x, paddle_x = draw(screen, points) - if paddle_x < ball_x: - c.input = 1 - elif paddle_x > ball_x: - c.input = -1 - else: - c.input = 0 - c.step() - if c.output is not None: - buffer_out.append(c.output) - c.output = None - if len(buffer_out) == 3: - screen[(buffer_out[0], buffer_out[1])] = buffer_out[2] - buffer_out = [] - return c.memory[386] - -def visualize(input): - def draw(screen, points): - ball_x = 0 - paddle_x = 0 - min_x = max_x = min_y = max_y = 0 - for p in screen: - min_x = min(min_x, p[0]) - max_x = max(max_x, p[0]) - min_y = min(min_y, p[1]) - max_y = max(max_y, p[1]) - s = "" - for y in range(min_y-1, max_y+1): - for x in range(min_x-1, max_x+1): - if (x,y) in screen: - if (x,y) == (-1,0): - points = screen[(x,y)] - elif screen[(x,y)] == 0: - s += " " - elif screen[(x,y)] == 1: - s += "\u2588" - elif screen[(x,y)] == 2: - s += "#" - elif screen[(x,y)] == 3: - s += "-" - paddle_x = x - elif screen[(x,y)] == 4: - s += "O" - ball_x = x - else: # (x,y) not in screen - s += " " - s += "\n" - return s, points, ball_x, paddle_x - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - c.memory[0] = 2 - - screen = {} - buffer_out = [] - frame_n = 0 - points = 0 - ball_x = paddle_x = 0 - - while c.memory[c.pointer] != 99: - if c.SIG_INPUT: - time.sleep(0.01) - frame_n += 1 - frame, points, ball_x, paddle_x = draw(screen, points) - print(frame) - if paddle_x < ball_x: - c.input = 1 - elif paddle_x > ball_x: - c.input = -1 - else: - c.input = 0 - c.step() - if c.output is not None: - buffer_out.append(c.output) - c.output = None - if len(buffer_out) == 3: - screen[(buffer_out[0], buffer_out[1])] = buffer_out[2] - buffer_out = [] - -if __name__ == "__main__": - import cProfile - - _input = open("../input/13", "r").readlines() - print(pt1(_input)) - print(pt2(_input)) - #visualize(_input) diff --git a/solutions/py/d14.py b/solutions/py/d14.py deleted file mode 100644 index 1d628a4..0000000 --- a/solutions/py/d14.py +++ /dev/null @@ -1,77 +0,0 @@ -import math - -class Chem(object): - def __init__(self, name, created): - self.name = name - self.created = created - - self.amount = 0 - self.left_over = 0 - self.producers = {} - - def add_producer(self, producer, amount): - self.producers[producer] = amount - - def produce(self, to_create): - if self.name == "ORE": - self.amount += to_create - return - if self.left_over > 0: - if self.left_over < to_create: - to_create -= self.left_over - self.left_over = 0 - else: - self.left_over -= to_create - to_create = 0 - productions = math.ceil(to_create / self.created) - self.amount += productions * self.created - self.left_over += productions * self.created - to_create - for producer, amount in self.producers.items(): - producer.produce(productions * amount) - - def __repr__(self): - return str((self.name, self.amount)) - -def read_chems(input): - chems = {"ORE": Chem("ORE", 1)} - for line in input: - output = line.strip().split(" => ")[1] - chems[output.split(" ")[1]] = Chem(output.split(" ")[1], int(output.split(" ")[0])) - - for line in input: - inputs = line.strip().split(" => ")[0] - output = line.strip().split(" => ")[1] - for i in inputs.split(", "): - chems[output.split(" ")[1]] \ - .add_producer(chems[i.split(" ")[1]], int(i.split(" ")[0])) - return chems - -def pt1(input, amount=1): - chems = read_chems(input) - chems["FUEL"].produce(amount) - return chems["ORE"].amount - -def pt2(input): - low, high = 0, int(1e9) - target = 1000000000000 - prev_guess = 0 - while low != high: - guess = (low+high) // 2 - if guess == prev_guess: - break - prev_guess = guess - chems = read_chems(input) - chems["FUEL"].produce(guess) - if chems["ORE"].amount == target: - break - elif chems["ORE"].amount > target: - high = guess - else: - low = guess - #print(low, guess, high) - return guess - -if __name__ == "__main__": - input = open("../input/14", "r").readlines() - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/d15.py b/solutions/py/d15.py deleted file mode 100644 index b2a9b10..0000000 --- a/solutions/py/d15.py +++ /dev/null @@ -1,276 +0,0 @@ -import intcode -import heapq as heap -import collections -import time - -def neighbours(p): - return [(p[0]+1, p[1]), (p[0]-1, p[1]), \ - (p[0], p[1]+1), (p[0], p[1]-1)] - -def get_path(start, end, board, draw_search=False): - if start == end: - return collections.deque() - visited = set() - h = [] - heap.heappush(h, (0, start, collections.deque())) - while True: - cur = heap.heappop(h) - for n in neighbours(cur[1]): - if n == end: - cur[2].append(n) - if draw_search: - print(draw(board, path=cur[2], visited=visited)) - return cur[2] - if n in visited or n not in board or board[n] == "#": - continue - new_path = collections.deque(cur[2]) - new_path.append(n) - visited.add(n) - heap.heappush(h, (cur[0] + 1, n, new_path)) - if draw_search: - time.sleep(0.005) - print(draw(board, path=new_path, visited=visited)) - -def pt1(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - c.SIG_INPUT = False - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - c.output = None - c.SIG_OUTPUT = False - return len(get_path((0,0), oxygen, board)) - -def pt2(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - oxygen = (0,0) - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - c.output = None - - steps = 0 - visited = set(oxygen) - cur_layer = [] - next_layer = [oxygen] - while True: - cur_layer = next_layer.copy() - next_layer = [] - for p in cur_layer: - for n in neighbours(p): - if n in board and board[n] != "#" and n not in visited: - visited.add(n) - next_layer.append(n) - if len(next_layer) == 0: - break - steps += 1 - return steps - -def draw(board, droid=None, path=None, visited=None): - min_x=max_x=min_y=max_y = 0 - for p in board: - min_x = min(p[0], min_x) - max_x = max(p[0], max_x) - min_y = min(p[1], min_y) - max_y = max(p[1], max_y) - s = "" - for y in range(min_y-1, max_y+2): - s += "\n" - for x in range(min_x-1, max_x+2): - point = (x, y) - if droid is not None and point == droid: - s += "D" * 2 - elif path is not None and point in path: - s += "\u2591" * 2 - elif visited is not None and point in visited: - s += "." * 2 - elif point in board: - if board[point] == "#": - s += "\u2588" * 2 - elif board[point] == "S": - s += "\u2591" * 2 - else: - s += " " * 2 - else: - s += "." * 2 - return s - -def visualize(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - time.sleep(0.005) - print(draw(board, droid=(cur_x, cur_y))) - c.output = None - - get_path((0,0), oxygen, board, draw_search=True) - - steps = 0 - visited = set(oxygen) - cur_layer = [] - next_layer = [oxygen] - while True: - cur_layer = next_layer.copy() - next_layer = [] - for p in cur_layer: - for n in neighbours(p): - if n in board and board[n] != "#" and n not in visited: - visited.add(n) - next_layer.append(n) - if len(next_layer) == 0: - break - steps += 1 - -if __name__ == "__main__": - input = open("../input/15", "r").readlines() - print(pt1(input)) - print(pt2(input)) - visualize(input) diff --git a/solutions/py/d16.py b/solutions/py/d16.py deleted file mode 100644 index 93b52d2..0000000 --- a/solutions/py/d16.py +++ /dev/null @@ -1,46 +0,0 @@ -def do(input, phases=100, repeats=1): - nums = [] - for i in range(repeats): - nums += [int(x) for x in input[0].strip()] - - for phase in range(phases): - #print(phase) - new_list = [] - for i in range(len(nums)): # position of number to calculate - new_num = 0 - for k in range(len(nums)): - mod = (k+1) % (4*(i+1)) - if mod >= i + 1 and mod < 2*i + 2: - new_num += nums[k] - elif mod >= 3*i + 3: - new_num -= nums[k] - new_list.append(abs(new_num) % 10) - nums = new_list - return "".join([str(n) for n in nums[:8]]) - -def pt1(input): - return do(input, phases=100, repeats=1) - -def pt2(input, phases=100, repeats=10000): - offset = int(input[0][:7]) - nums = [] - for i in range(repeats): - nums += [int(x) for x in input[0].strip()] - nums = nums[offset:] - for phase in range(phases): - #print(phase) - nums = nums[::-1] - new_nums = [] - n = sum(nums) - while len(nums) != 0: - new_nums.append(abs(n) % 10) - n -= nums.pop() - nums = new_nums - return "".join([str(n) for n in nums[:8]]) - -if __name__ == "__main__": - input = open("../input/16", "r").readlines() - ans1 = pt1(input) - ans2 = pt2(input) - print(ans1) - print(ans2) diff --git a/solutions/py/d17.py b/solutions/py/d17.py deleted file mode 100644 index 42ba045..0000000 --- a/solutions/py/d17.py +++ /dev/null @@ -1,317 +0,0 @@ -import intcode -from collections import deque -import heapq as heap -import time - -def draw(view, intersections={}, robot=None, direction=None): - min_x=max_x=min_y=max_y = 0 - for p in view: - min_x = min(p[0], min_x) - max_x = max(p[0], max_x) - min_y = min(p[1], min_y) - max_y = max(p[1], max_y) - s = "" - for y in range(min_y, max_y+1): - s += "\n" - for x in range(min_x, max_x+1): - point = (x, y) - if robot is not None and point == robot: - if direction == 0: - s += ">" - elif direction == 1: - s += "v" - elif direction == 2: - s += "<" - elif direction == 3: - s += "^" - else: - s += "D" - elif point in intersections: - s += "O" - elif point in view: - s += view[point] * 1 - else: - s += " " * 1 - return s - -def neighbours(p): - return [(p[0]+1, p[1]), (p[0]-1, p[1]), \ - (p[0], p[1]+1), (p[0], p[1]-1)] - -def get_infront(robot, direction): - dx=dy = 0 - if direction == 0: - dx = 1 - elif direction == 1: - dy = 1 - elif direction == 2: - dx = -1 - else: - dy = -1 - return (robot[0]+dx, robot[1]+dy) - -def get_behind(robot, direction): - dx=dy = 0 - if direction == 0: - dx = -1 - elif direction == 1: - dy = -1 - elif direction == 2: - dx = 1 - else: - dy = 1 - return (robot[0]+dx, robot[1]+dy) - -def get_turn(robot, direction, point): - dx = point[0] - robot[0] - dy = point[1] - robot[1] - if dx == 1: - turn_direction = 0 - elif dy == 1: - turn_direction = 1 - elif dx == -1: - turn_direction = 2 - else: - turn_direction = 3 - if direction == turn_direction: - return None - if (direction + 1) % 4 == turn_direction: - return "R" - elif (direction - 1) % 4 == turn_direction: - return "L" - else: - return False - -def get_direction(direction, turn): - if turn == "L": - return (direction - 1) % 4 - elif turn == "R": - return (direction + 1) % 4 - else: - return False - -def get_turnable_points(scaffolds, robot, direction): - valid = set() - for n in neighbours(robot): - if n in scaffolds and n != get_behind(robot, direction): - valid.add(n) - return list(valid) - -def pt1(input): - c = intcode.Computer([int(x) for x in open("../input/17", "r").readlines()[0].split(",")]) - - view = {} - scaffolds = [] - buffer = "" - x=y = 0 - while not c.SIG_HALT: - c.step() - if c.SIG_INPUT: - print("input??") - break - if c.SIG_OUTPUT: - if c.output == 10: - y += 1 - x = 0 - elif c.output == 35: - view[(x,y)] = "#" - scaffolds.append((x,y)) - x += 1 - elif c.output == 46: - view[(x,y)] = "." - x += 1 - else: - view[(x,y)] = "#" - scaffolds.append((x,y)) - robot = (x,y) - if c.output == 60: # < - direction = 2 - elif c.output == 62: # > - direction = 0 - elif c.output == 94: # ^ - direction = 3 - elif c.output == 86 or c.output == 118: # V or v - direction = 1 - else: - print("????????????????") - break - x += 1 - buffer = "" - c.output = None - c.SIG_OUTPUT = False - #print(draw(view)) - - intersections = set() - al_sum = 0 - for s in scaffolds: - ns = 0 - for n in neighbours(s): - if n in scaffolds: - ns += 1 - if ns == 4: - intersections.add(s) - al_sum += s[0] * s[1] - #print(intersections) - #print(draw(view, intersections=intersections, robot=robot, direction=direction)) - return al_sum - -def pt2(input): - c = intcode.Computer([int(x) for x in open("../input/17", "r").readlines()[0].split(",")]) - - view = {} - scaffolds = [] - buffer = "" - x=y = 0 - while not c.SIG_HALT: - c.step() - if c.SIG_INPUT: - print("input??") - break - if c.SIG_OUTPUT: - if c.output == 10: - y += 1 - x = 0 - elif c.output == 35: - view[(x,y)] = "#" - scaffolds.append((x,y)) - x += 1 - elif c.output == 46: - view[(x,y)] = "." - x += 1 - else: - view[(x,y)] = "#" - scaffolds.append((x,y)) - robot = (x,y) - if c.output == 60: # < - direction = 2 - elif c.output == 62: # > - direction = 0 - elif c.output == 94: # ^ - direction = 3 - elif c.output == 86 or c.output == 118: # V or v - direction = 1 - else: - print("????????????????") - break - x += 1 - buffer = "" - c.output = None - c.SIG_OUTPUT = False - #print(draw(view)) - - intersections = set() - for s in scaffolds: - ns = 0 - for n in neighbours(s): - if n in scaffolds: - ns += 1 - if ns == 4: - intersections.add(s) - - ''' - For each path, take steps until a wall is reached. When a wall is reached, tuirn - towards the next unvisited point. Repeat until the end is reached. - - Structure of a deque-element: - Each search-element consists of a single tuple. The tuple contains - - The robot's position - - The robot's direction (after turning) - - The instruction-set up to that point - - The current WIP instruction - - All points that have been visited (as a set) - - Structure of the instruction-set: - The instruction-set consists of a list of tuples. The tuples contain - - A turn-instruction - - The number of steps to take (after turning) - For example: - [(R,8), (R,8), (R,4), (R,4), (R,8)] - ''' - - current = None - direction = 2 - paths = deque() - visited = set() - visited.add(robot) - paths.append((robot, direction, [], ["L", 0], visited)) - while True: - if current is None: - current = paths.popleft() - robot = current[0] - direction = current[1] - instruction_set = current[2] - wip_instruction = current[3] - visited = current[4].copy() - if len(visited) == len(scaffolds): - #print("len(visited) == len(scaffolds)") - instruction_set.append(wip_instruction) - break - if get_infront(robot, direction) not in scaffolds: - # wall in front. save - instruction_set.append(wip_instruction) - avail_points = get_turnable_points(scaffolds, robot, direction) - if len(avail_points) == 0: - if len(visited) == len(scaffolds): - break - else: - current = None - continue - wip_instruction = [get_turn(robot, direction, avail_points[0]), 0] - direction = get_direction(direction, get_turn(robot, direction, avail_points[0])) - paths.append((robot, direction, instruction_set, wip_instruction, visited)) - current = None - else: # wall not in front - ''' - if robot in intersections and wip_instruction[1] != 0: - # queue intersections - new_instruction_set = instruction_set.copy() - new_instruction_set.append(wip_instruction.copy()) - paths.append((robot, get_direction(direction, "L"), \ - new_instruction_set.copy(), ["L", 0], visited)) - paths.append((robot, get_direction(direction, "R"), \ - new_instruction_set.copy(), ["R", 0], visited)) - ''' - # take step - robot = get_infront(robot, direction) - visited.add(robot) - wip_instruction[1] += 1 - - #print(instruction_set) - s = "" - for instruction in instruction_set: - s += str(instruction[0]) + "," + str(instruction[1]) + "\n" - #print(s) - - # hard-coded >:( - main_routine = "A,A,B,C,C,A,C,B,C,B" - routine_a = "L,4,L,4,L,6,R,10,L,6" - routine_b = "L,12,L,6,R,10,L,6" - routine_c = "R,8,R,10,L,6" - - msg = deque() - for s in [main_routine, routine_a, routine_b, routine_c]: - for ch in s: - msg.append(ord(ch)) - msg.append(10) - msg.append(ord("n")) - msg.append(10) - #print(msg) - - c.reset() - c.memory[0] = 2 - output = [] - while not c.SIG_HALT: - c.step() - if c.SIG_INPUT: - c.input = msg.popleft() - c.SIG_INPUT = False - if c.SIG_OUTPUT: - output.append(c.output) - c.output = None - c.SIG_OUTPUT = False - return output[-1] - -if __name__ == "__main__": - input = open("../input/17", "r") - print(pt1(input)) - print(pt2(input)) diff --git a/solutions/py/intcode.py b/solutions/py/intcode.py deleted file mode 100644 index 694fee0..0000000 --- a/solutions/py/intcode.py +++ /dev/null @@ -1,146 +0,0 @@ -param_amount = {1:3, 2:3, 3:1, 4:1, 5:2, 6:2, 7:3, 8:3, 9:1, 99:0} - -ADD = 1 -MULT = 2 -IN = 3 -OUT = 4 -JNZ = 5 -JEZ = 6 -LET = 7 -EQV = 8 -BAS = 9 -HAL = 99 - -class Computer(object): - def __init__(self, program): - self.program = program - self.memory = self.program.copy() - self.memory_size = len(self.program) - self.extra_memory = {} - self.instruction_cache = {} - self.pointer = 0 - self.phase_read = False # for day 7 - self.relative_base = 0 - - self.input = None - self.output = None - - self.SIG_INPUT = False - self.SIG_OUTPUT = False - self.SIG_HALT = False - - def reset(self): - self.memory = self.program.copy() - self.extra_memory = {} - self.instruction_cache = {} - self.pointer = 0 - self.phase_read = False # for day 7 - self.relative_base = 0 - - self.input = None - self.ouput = None - - self.SIG_INPUT = False - self.SIG_OUTPUT = False - self.SIG_HALT = False - - def parse_op(self, op): - if op in self.instruction_cache: - return self.instruction_cache[op] - code = op % 100 - ops = str(op).zfill(param_amount[code]+2) - self.instruction_cache[op] = [code] + [int(x) for x in ops[:-2][::-1]] - return self.instruction_cache[op] - #return [code] + [(op // 10**(i+2)) % 10**(i+1) for i in range(param_amount[code])] - - def clear_flags(self): - self.input = None - self.output = None - - def write(self, addr, val): - if addr >= self.memory_size: - self.extra_memory[addr] = val - else: - self.memory[addr] = val - - def get(self, addr): - if addr >= self.memory_size: - return self.extra_memory.get(addr, 0) - return self.memory[addr] - - def get_param(self, inst, num): - if inst[num] == 0: - return self.get(self.get(self.pointer + num)) - elif inst[num] == 1: - return self.get(self.pointer + num) - elif inst[num] == 2: - return self.get(self.relative_base + self.get(self.pointer + num)) - - def write_param(self, inst, num, val): - if inst[num] == 0: - self.write(self.get(self.pointer + num), val) - elif inst[num] == 1: - self.write(self.pointer + num, val) - elif inst[num] == 2: - self.write(self.relative_base + self.get(self.pointer + num), val) - - def step(self): - if self.SIG_OUTPUT and self.output is None: - self.SIG_OUTPUT = False - if self.SIG_INPUT and self.input is not None: - self.SIG_INPUT = False - - inst = self.parse_op(self.memory[self.pointer]) - if inst[0] == HAL: - self.SIG_HALT = True - return - elif inst[0] == ADD: - self.write_param(inst, 3, \ - self.get_param(inst, 1) + self.get_param(inst, 2)) - self.pointer += 4 - elif inst[0] == MULT: - self.write_param(inst, 3, \ - self.get_param(inst, 1) * self.get_param(inst, 2)) - self.pointer += 4 - elif inst[0] == IN: - if self.input is None: - self.SIG_INPUT = True - return - self.write_param(inst, 1, self.input) - self.input = None - self.SIG_INPUT = False - self.pointer += 2 - elif inst[0] == OUT: - if self.SIG_OUTPUT: - return - self.output = self.get_param(inst, 1) - self.SIG_OUTPUT = True - self.pointer += 2 - elif inst[0] == JNZ: - if self.get_param(inst, 1) != 0: - self.pointer = self.get_param(inst, 2) - else: - self.pointer += 3 - elif inst[0] == JEZ: - if self.get_param(inst, 1) == 0: - self.pointer = self.get_param(inst, 2) - else: - self.pointer += 3 - elif inst[0] == LET: - self.write_param(inst, 3, 1 if \ - self.get_param(inst, 1) < self.get_param(inst, 2) \ - else 0) - self.pointer += 4 - elif inst[0] == EQV: - self.write_param(inst, 3, 1 if \ - self.get_param(inst, 1) == self.get_param(inst, 2) \ - else 0) - self.pointer += 4 - elif inst[0] == BAS: - self.relative_base += self.get_param(inst, 1) - self.pointer += 2 - else: - print(self.memory) - print(self.pointer) - print("invalid instruction", self.memory[self.pointer]) - print(inst) diff --git a/solutions/py/main.py b/solutions/py/main.py deleted file mode 100644 index cc0f04c..0000000 --- a/solutions/py/main.py +++ /dev/null @@ -1,52 +0,0 @@ -import time - -import d01 -import d02 -import d03 -import d04 -import d05 -import d06 -import d07 -import d08 -import d09 -import d10 -import d11 -import d12 -import d13 -import d14 -import d15 -import d16 -import d17 - -mods = [d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, \ - d11, d12, d13, d14, d15, d16, d17] - -skip = [12, 16] - -timings = [[0 for _ in range(2)] for _ in range(len(mods))] -clock_type = time.CLOCK_MONOTONIC - -for mod, day in zip(mods, range(len(mods))): - if day+1 in skip: - continue - print("Day", str(day+1).zfill(2)) - t0 = time.clock_gettime_ns(clock_type) - print("Part", 1, mod.pt1(open("../input/" + str(day+1).zfill(2), "r").readlines())) - timings[day][0] = time.clock_gettime_ns(clock_type) - t0 - t0 = time.clock_gettime_ns(clock_type) - print("Part", 2, mod.pt2(open("../input/" + str(day+1).zfill(2), "r").readlines())) - timings[day][1] = time.clock_gettime_ns(clock_type) - t0 - -print() -tot = 0 -for day in range(len(timings)): - for part in range(2): - tot += timings[day][part] -for day in range(len(timings)): - if day+1 in skip: - print("day {0} skipped".format(str(day+1))) - else: - for part in range(2): - print("day {0}-{1}: {2:.2f}ms\t({3:.1f}%)".format(str(day+1).zfill(2), part+1, \ - timings[day][part] / 1000000, 100*timings[day][part] / tot)) -print("sum", tot / 1000000, "ms") |
