import sys sys.path.append("../common") import aoc def parse_line(l): s = l.split(">") vals = list() for ss in s: if len(ss) == 0: continue ss = ss.split("<",1)[1] vals.append([int(x) for x in ss.split(",")]) return vals data = [parse_line(l) for l in aoc.data.split("\n") if len(l) != 0] posdata = [x[0] for x in data] veldata = [x[1] for x in data] def check_adj(pi): for p in posdata: if abs(p[0] - pi[0]) + abs(p[1] - pi[1]) == 1: return True return False def check_data(): for p in posdata: if not check_adj(p): return False return True def bounds(): minx = None maxx = None miny = None maxy = None for p in posdata: if minx is None or p[0] < minx: minx = p[0] if maxx is None or p[0] > maxx: maxx = p[0] if miny is None or p[1] < miny: miny = p[1] if maxy is None or p[1] > maxy: maxy = p[1] return minx, maxx, miny, maxy def solve(part, args): count = 0 distx = None disty = None while True: for i in range(len(data)): posdata[i][0] += veldata[i][0] posdata[i][1] += veldata[i][1] count += 1 minx, maxx, miny, maxy = bounds() if distx == None: distx = maxx - minx disty = maxy - miny else: cdistx = maxx - minx cdisty = maxy - miny if cdistx > distx or cdisty > disty: for i in range(len(data)): posdata[i][0] -= veldata[i][0] posdata[i][1] -= veldata[i][1] count -= 1 break else: distx = cdistx disty = cdisty if count % 100 == 0: aoc.debug("\r" + " " * 50, end="") aoc.debug(f"\rcluster size: {distx}, {disty}", end="") if part == 1: return count elif part == 2: answer = "" minx, maxx, miny, maxy = bounds() for y in range(maxy - miny + 1): f = lambda x: "#" if list([x + minx, y + miny]) in posdata else " " answer += "".join([f(x) for x in range(maxx - minx + 1)]) + "\n" print(repr(answer)) print(repr(sol2)) return answer else: assert(False) sol2 = """\ # # ###### # ##### # # # # #### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## ##### # ##### ###### ## # ## ## # # # # # # ## # ### ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # ###### ##### # # # # ### # # # """ aoc.run(lambda args: solve(1, args), lambda args: solve(2, args), sols=[10659, sol2])