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