2018-12-10 - The Stars Align
(original .ipynb)test_input_str = """position=< 9, 1> velocity=< 0, 2> position=< 7, 0> velocity=<-1, 0> position=< 3, -2> velocity=<-1, 1> position=< 6, 10> velocity=<-2, -1> position=< 2, -4> velocity=< 2, 2> position=<-6, 10> velocity=< 2, -2> position=< 1, 8> velocity=< 1, -1> position=< 1, 7> velocity=< 1, 0> position=<-3, 11> velocity=< 1, -2> position=< 7, 6> velocity=<-1, -1> position=<-2, 3> velocity=< 1, 0> position=<-4, 3> velocity=< 2, 0> position=<10, -3> velocity=<-1, 1> position=< 5, 11> velocity=< 1, -2> position=< 4, 7> velocity=< 0, -1> position=< 8, -2> velocity=< 0, 1> position=<15, 0> velocity=<-2, 0> position=< 1, 6> velocity=< 1, 0> position=< 8, 9> velocity=< 0, -1> position=< 3, 3> velocity=<-1, 1> position=< 0, 5> velocity=< 0, -1> position=<-2, 2> velocity=< 2, 0> position=< 5, -2> velocity=< 1, 2> position=< 1, 4> velocity=< 2, 1> position=<-2, 7> velocity=< 2, -2> position=< 3, 6> velocity=<-1, -1> position=< 5, 0> velocity=< 1, 0> position=<-6, 0> velocity=< 2, 0> position=< 5, 9> velocity=< 1, -2> position=<14, 7> velocity=<-2, 0> position=<-3, 6> velocity=< 2, -1>""" test_input = test_input_str.split("\n") real_input = open("puzzle_input/day10.txt").readlines()
import re class Point(object): def __init__(self, input_str): parsed = re.match("^position=<\s*(-?\d+),\s*(-?\d+)>\s+velocity=<\s*(-?\d+),\s*(-?\d+)>$", input_str) self.pos_x = int(parsed.group(1)) self.pos_y = int(parsed.group(2)) self.vel_x = int(parsed.group(3)) self.vel_y = int(parsed.group(4)) def offset(self, offset_x, offset_y): return (offset_x + self.pos_x, offset_y + self.pos_y) def step(self): self.pos_x += self.vel_x self.pos_y += self.vel_y
from PIL import Image, ImageDraw from IPython.display import Image as IPythonImage from IPython.display import display # find min/max points = [ Point(point) for point in real_input ] min_x = min([ point.pos_x for point in points ]) min_y = min([ point.pos_y for point in points ]) max_x = max([ point.pos_x for point in points ]) max_y = max([ point.pos_y for point in points ]) steps = 0 while max_y - min_y > 100: min_x = min([ point.pos_x for point in points ]) min_y = min([ point.pos_y for point in points ]) max_x = max([ point.pos_x for point in points ]) max_y = max([ point.pos_y for point in points ]) for point in points: point.step() steps += 1 offset_x = -(min_x) offset_y = -(min_y) number_of_frames = 66 frame_names = [] base_frame = Image.new("RGB", (max_x + offset_x, max_y + offset_y), 'white') for frame_id in range(number_of_frames): frame = base_frame.copy() draw = ImageDraw.Draw(frame) draw.point([ point.offset(offset_x, offset_y) for point in points], fill="black") frame_name = './img/img{:02d}.gif'.format(frame_id) min_y = min([ point.pos_y for point in points ]) max_y = max([ point.pos_y for point in points ]) max_x = max([ point.pos_x for point in points ]) max_y = max([ point.pos_y for point in points ]) frame_names.append(frame_name) if (max_y - min_y) < 10: print(max_y - min_y) print(max_x - min_x) frame_names += [ frame_name ] * 33 for point in points: point.step() images = [] for frame_name in frame_names: frame = Image.open(frame_name) images.append(frame) # Save the frames as an animated GIF images[0].save('./img/day10.gif', save_all=True, append_images=images[1:], duration=33, loop=0) display(IPythonImage(url="./img/day10.gif"))
9 98