You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.9 KiB
Python

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'<Point pos={self.pos} vel={self.vel}>'
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)