Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


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