import re from pprint import pprint from PIL import Image class Point: def __init__(self, pos, vel): self.pos = pos self.vel = vel def pos_at(self, sec): x = self.pos[0] + self.vel[0] * sec y = self.pos[1] + self.vel[1] * sec return (x, y) def __repr__(self): return f'' class Picture: def __init__(self, width, height): self.data = [] for _ in range(height): self.data.append(['.'] * width) def draw(self, x, y): self.data[y][x] = '#' def paint(self): for row in self.data: print(''.join(row)) def parse(point_str): pos = (int(point_str[10:16]), int(point_str[17:24])) vel = (int(point_str[36:38]), int(point_str[39:42])) return(Point(pos, vel)) with open('input.txt', 'r') as f: points = [parse(x) for x in f.readlines()] def calc_bbox(points, sec): coords = [p.pos_at(sec) for p in points] min_x = min([x[0] for x in coords]) min_y = min([x[1] for x in coords]) max_x = max([x[0] for x in coords]) max_y = max([x[1] for x in coords]) return [(min_x, min_y), (max_x, max_y)] def delta_from_bbox(bbox): return (bbox[1][0] - bbox[0][0], bbox[1][1] - bbox[0][1]) def calc_min_res(): cur_res = 10000000000000000000 i = 0 while 1: bbox = calc_bbox(points, i) delta = delta_from_bbox(bbox) res = delta[0] * delta[1] if res > cur_res: return i - 1 cur_res = res i += 1 print('Calculating min res') i = calc_min_res() print('Finished. Points closest at second:', i) def paint(points, sec): coords = [p.pos_at(i) for p in points] bbox = calc_bbox(points, sec) delta = delta_from_bbox(bbox) pic = Picture(delta[0] + 1, delta[1] + 1) for pos in coords: pic.draw(pos[0] - bbox[0][0], pos[1] - bbox[0][1]) pic.paint() paint(points, i)