class Node(): def __init__(self, data): h = [data.popleft(), data.popleft()] self.children = [Node(data) for i in range(h[0])] self.meta = [data.popleft() for i in range(h[1])] def v1(self): return sum(self.meta) + sum(c.v1() for c in self.children) def value(self): return sum(self.meta) if len(self.children) < 1 else sum( self.children[m - 1].value() for m in self.meta if m <= len(self.children)) import loadFile, collections print("Sum of all metadata: {}\nValue of root node: {}".format(*[ getattr( Node(collections.deque(map(int, next(loadFile.loadfile(8)).split(" ")))), m) () for m in ["v1", "value"] ]))
self.h = int(h) self.r = self.x + self.w self.b = self.y + self.h self.overlap = False def area(self, other): # returns None if rectangles don't intersect xmin = max(self.l, other.l) xmax = min(self.r, other.r) ymin = max(self.t, other.t) ymax = min(self.b, other.b) if (xmax - xmin > 0 and ymax - ymin > 0): self.overlap = other.overlap = True for i in range(xmin, xmax): for j in range(ymin, ymax): overlaps.add(str(i) + "x" + str(j)) if __name__ == "__main__": pattern = re.compile( r"#(?P<id>\d+)\s@\s(?P<x>\d+),(?P<y>\d+)\s(?P<w>\d+)x(?P<h>\d+)") regions = [] for line in loadfile(3): m = pattern.match(line) #print(m.groupdict()) r = Region(**m.groupdict()) for r1 in regions: r1.area(r) regions.append(r) print(len(overlaps)) print([r.id for r in regions if not r.overlap])
setTile(i, y, tile) print(f"\n{left} - {right} @ {y}:", row) print(f"{left} - {right} @ {y + 1}:", [getTile(i, y + 1) for i in range(left, right + 1)]) def printTiles(): area = [[min(vals), max(vals) + 1] for vals in zip(*[map(int, k.split(",")) for k in TILES.keys()])] for y in range(*area[1]): for x in range(*area[0]): print(getTile(x, y), end="") print() if __name__ == "__main__": reval = r"(\d+)(?:\.{2}(\d+))?" px = re.compile(r"x=" + reval) py = re.compile(r"y=" + reval) for line in loadfile(17, sample=False): xr = px.search(line) xlim = [int(xr[1]), int(xr[2]) + 1 if xr[2] != None else int(xr[1]) + 1] yr = py.search(line) ylim = [int(yr[1]), int(yr[2]) + 1 if yr[2] != None else int(yr[1]) + 1] Y_MAX = max(Y_MAX, ylim[1] - 1) Y_MIN = min(Y_MIN, ylim[0]) for x in range(xlim[0], xlim[1]): for y in range(ylim[0], ylim[1]): setTile(x, y, "#") #printTiles() x = 500 y = 0 spread(x, y + 1) print(len([t for t in TILES if t in "~|"]))
from loadFile import loadfile from scipy.spatial import Voronoi, voronoi_plot_2d import matplotlib.pyplot as plot if __name__ == "__main__": points = [p.split(",") for p in loadfile(6)] vor = Voronoi(points, qhull_options="Qbb Qc") print(vor.regions) regions = [r for r in vor.regions if -1 not in r] voronoi_plot_2d(vor) plot.show()
class MovingPoint(Point): def __init__(self, x, y, dx, dy): super().__init__(x, y) self.dx = int(dx) self.dy = int(dy) def pos(self, num): return (self.x + num * self.dx, self.y + num * self.dy) if __name__ == "__main__": pattern = re.compile( r"position=<(?P<x>[ -]\d+), (?P<y>[ -]\d+)> velocity=<(?P<dx>[ -]\d+), (?P<dy>[ -]\d+)>" ) points = [] for line in loadfile(10): m = pattern.match(line).groupdict() points.append(MovingPoint(m["x"], m["y"], m["dx"], m["dy"])) sizes = [ sum([ max(vals) - min(vals) for vals in zip(*[p.pos(i) for p in points]) ]) for i in range(20000) ] minSizeIndex = sizes.index(min(sizes)) unique = set(Point(*p.pos(minSizeIndex)) for p in points) mins = [min(v) for v in zip(*unique)] out = {} for point in unique: x = point.x - mins[0]
c = c.upper() if displayLen > 1: c += str(id // 26 + 1) print(c, end=" ") if displayLen > 0: print("") def incRange(limits): for i in range(limits[0], limits[1] + 1): yield i if __name__ == "__main__": points = [(lambda x, y: [int(x), int(y)])(*p.split(",")) for p in loadfile(6)] threshold = 10000 #points = [[1, 1], [1, 6], [8, 3], [3, 4], [5, 5], [8, 9]] # Sample #threshold = 32 # Sample xlim, ylim = [[min(vals) - 1, max(vals) + 1] for vals in zip(*points)] #print(xlim, ylim) getDistCount(points, xlim, ylim) #, True) edges = set() def excludeArea(x, y): area = Point.get(x, y).closest() if area != None: edges.add(area)
self.ops = ops[1:] def setAfter(self, after): self.after = after self.valid = {o for o in funcs.values() if o.apply(self.before.copy(), *self.ops) == self.after} #if len(self.valid) == 1: # list(self.valid)[0].opcode = self.opNum if __name__ == "__main__": opcodes = {} samples = [] current = None begin = re.compile(r"Before:\s+\[(.+)\]") end = re.compile(r"After:\s+\[(.+)\]") empty = 0 registers = [0] * 4 for line in loadfile(16): if empty == 3: empty += 1 # Force next step for n, ops in opcodes.items(): o = {op for op in ops if op.opcode < 0} if len(o) == 1: o.pop().opcode = n opcodes = {o.opcode: o for o in funcs.values()} elif empty > 3: proc = [int(i) for i in line.split(" ")] print(proc) registers = opcodes[proc[0]].apply(registers, *proc[1:]) else: if len(line) < 1: empty += 1 continue
and len(remaining.intersection(node.parents)) < 1 ][0:numWorkers - len(current)] # print(current, available) for node in available: current[node] = node.duration # print(current) step = min(current.values()) sec += step # print("Currently building: {}\nSkipping {} secs, total time ellapsed: {}".format({n.key: d for n,d in current.items()}, step, sec)) for n, d in dict(current).items(): d -= step if d < 1: del current[n] remaining.remove(n) else: current[n] = d return sec if __name__ == "__main__": pattern = re.compile(r"^Step ([A-Z]) .+ step ([A-Z])") for line in loadfile(7): m = pattern.match(line) Node(m[1]).addChild(m[2]) order = sortNodes() print("Sorted order:", "".join(order)) print("Total build time:", build(order))
def matchChars(data): for i in range(len(data)): a = data[i] for j in range(i, len(data)): b = data[j] errors = 0 chars = [] for k in range(len(a)): if a[k] == b[k]: chars.append(a[k]) else: errors += 1 if errors > 1: break if errors == 1: return "".join(chars) if __name__ == "__main__": # part 1 c2 = 0 c3 = 0 for line in loadfile(2): c = countDups(line) c2 += c[0] c3 += c[1] print(c2 * c3) # part 2 print(matchChars(list(loadfile(2))))
from loadFile import loadfile a = ord("a") A = ord("A") def reactedLength(data): last = None while last != data: last = data for i in range(26): data = data.replace(chr(a + i) + chr(A + i), "") data = data.replace(chr(A + i) + chr(a + i), "") return len(data) if __name__ == "__main__": data = list(loadfile(5))[0] # Strip newline character :@ print(reactedLength(data)) best = len(data) for i in range(26): best = min( best, reactedLength( data.replace(chr(a + i), "").replace(chr(A + i), ""))) print(best)
self.y += 1 elif self.facing == 3: # Left (<) self.x -= 1 tracks[f"{self.x},{self.y}"].enter(self) def __lt__(self, other): return self.y < other.y and self.x < other.x def __str__(self): return "^>v<"[self.facing] def __repr__(self): return f"Cart({self.cartID})@{self.x},{self.y} Facing:{str(self)}" if __name__ == "__main__": tracks = {} carts = {} cartID = 0 for y, line in enumerate(loadfile(13)): #for y, line in enumerate(loadfile("day13SampleData.txt")): for x, char in enumerate(line): if char == " ": continue pos = f"{x},{y}" cart = None if char in "^>v<": carts[cartID] = cart = Cart(cartID, x, y, "^>v<".index(char)) cartID += 1 char = "-" if char in "<>" else "|" tracks[pos] = Track(x, y, char, cart) collisionNum = 0 while len(carts) > 1: for cart in sorted(carts.values()):
for index in self.state.keys(): sections.update(self.segment(index + i) for i in range(-2, 3)) return sections def __str__(self, padding=3): return "".join("#" if self.state.get(i, False) else "." for i in range(-padding, self.max + 1)) def value(self): return sum(i for i, v in self.state.items() if v) if __name__ == "__main__": mappings = {} pattern = re.compile(r"([#.]+) => ([#.])") for line in loadfile(12): #for line in loadfile("day12SampleData.txt"): m = pattern.match(line) mappings[m[1]] = m[2] patterns = [k for k, v in mappings.items() if v == "#"] gen0 = PotGeneration(INITIAL_STATE) #gen0 = PotGeneration("#..#.#..##......###...###") #print("00: {}".format(str(gen0))) gen = gen0 gens = {} delta = None deltaCount = 0 for n in range(50000000000): gens[n] = gen = PotGeneration({
total = 0 for s in self.days.values(): total += len(s) return total def mostCommonMin(self): if len(self.allMins) < 1: return 0,0 return self.allMins.most_common(1)[0] if __name__ == "__main__": pattern = re.compile(r"\[1518-(?P<day>\d+-\d+)\s\d+:(?P<min>\d+)\]\s(?:(?:Guard #(?P<gid>\d+) begins shift)|falls a(?P<sleep>sleep)|(?P<wake>wake)s up)") regions = [] guard = None for line in sorted(loadfile(4)): m = pattern.match(line) gid = m.group("gid") sleep = bool(m.group("sleep")) wake = bool(m.group("wake")) if gid: guard = Guard(gid) elif guard: guard.setDay(m.group("day")) minute = int(m.group("min")) if sleep: guard.sleep(minute) elif wake: guard.wake(minute) g = sorted(Guard.ids.values(), key=lambda g: g.sleepAmount(), reverse=True)[0] print("Guard {} slept for {} min(s) total. Most slept minute: {}".format(g.id, g.sleepAmount(), g.mostCommonMin()[0]))
def __init__(self, data): self.numChild = data.popleft() self.numMeta = data.popleft() self.children = [] for i in range(self.numChild): self.children.append(Node(data)) self.meta = [] for i in range(self.numMeta): self.meta.append(data.popleft()) Node.nodes.append(self) @property def value(self): if self.numChild < 1: return sum(self.meta) else: total = 0 for i in [m - 1 for m in self.meta]: if i < self.numChild: total += self.children[i].value return total if __name__ == "__main__": data = deque(map(int, next(loadfile(8)).split(" "))) #data = deque(map(int, "2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2".split(" "))) root = Node(data) print("Sum of all metadata:", sum(sum(n.meta) for n in Node.nodes)) print("Value of root node:", root.value)