Files
AdventOfCode2024/18/18-2-anim.py
2024-12-18 19:48:26 +01:00

135 lines
3.9 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import cv2
from time import time
from copy import deepcopy
start_time = time()
file = "./input.txt"
XY_DIMENSION = 70
FIRST_BYTES = 1024
#file = "./ex.txt"
#XY_DIMENSION = 6
#FIRST_BYTES = 12
out_file_name = "solution_10"
GROW_FACTOR = 10
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = 30
frame_size = ((XY_DIMENSION+1) * GROW_FACTOR, (XY_DIMENSION + 1) * GROW_FACTOR)
out_mp4 = cv2.VideoWriter(f'./{out_file_name}.mp4', fourcc, fps, frame_size)
gif_anim=[]
def array_to_image(ar):
global GROW_FACTOR
# Konvertiere das Array in ein NumPy-Array
np_array = np.array(ar)
# Erstelle ein leeres RGB-Bild
height, width = np_array.shape
image = Image.new('RGB', (width * GROW_FACTOR, height * GROW_FACTOR))
# Fülle das Bild mit Pixeln basierend auf den Array-Werten
for y in range(height):
for x in range(width):
if np_array[y, x] == "#":
color = (200, 0, 0)
elif np_array[y, x] == "O":
color = (50, 200,50)
else:
color = (0,0,0) # Standardfarbe schwarz
for dy in range(GROW_FACTOR):
for dx in range(GROW_FACTOR):
image.putpixel((x * GROW_FACTOR + dx, y * GROW_FACTOR + dy), color)
return image
def add_text_to_image(image, num):
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("arial.ttf", 20) # Wählen Sie eine Schriftart und Größe
draw.text((5,5), f"{num:04d}", fill=(255, 255, 255), font=font) # Weißer Text
return image
def pil_to_cv2(pil_image):
return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
def make_empty_grid(dimension:int)->list[list[str]]:
result = []
for _ in range(dimension+1):
result.append(["." for _ in range(dimension+1)])
return result
def print_grid(f):
for r in f:
for s in r:
if s == 0:
print(".", end="")
else:
print(s, end="")
print()
def fill_grid(gri:list[list[str]], ma:list[list[int]], filler:str)->list[list[str]]:
result = deepcopy(gri)
for m in ma:
x , y = m[0],m[1]
result[y][x] = filler
return result
def read_input(input_file:str, ) -> list[list[int]]:
out = []
f = open(input_file, "r")
for line in f:
line = line.strip()
if line == "":
continue
else:
out.append(list(map(int,line.split(','))))
f.close()
return out
from collections import deque
def shortest_path(array, start, end):
zeilen, spalten = len(array), len(array[0])
visited = set()
queue = deque([(start, [start])])
while queue:
(x, y), pfad = queue.popleft()
if (x, y) == end:
return len(pfad) - 1, pfad
for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
nx, ny = x + dx, y + dy
if 0 <= nx < zeilen and 0 <= ny < spalten and array[nx][ny] == '.' and (nx, ny) not in visited:
queue.append(((nx, ny), pfad + [(ny, nx)]))
visited.add((nx, ny))
return -1, [] # Kein Pfad gefunden
if __name__ == "__main__":
grid = make_empty_grid(XY_DIMENSION)
corrupted = read_input(file)
for i in range(FIRST_BYTES, len(corrupted)):
g = fill_grid(grid,corrupted[:i],"#")
sp = shortest_path(g,(0,0),(XY_DIMENSION,XY_DIMENSION))
g_with_path = fill_grid(g, sp[1], "O")
img = array_to_image(g_with_path)
gif_anim.append(img)
cv2_image = pil_to_cv2(img)
out_mp4.write(cv2_image)
if sp[0] == -1:
print(f"First Blocking Field: {corrupted[:i][-1]}")
break
out_mp4.release()
gif_anim[0].save(f'./{out_file_name}.gif', save_all=True, append_images=gif_anim[1:],
optimize=False, duration=30, loop=0)
print(f'Runtime: {time()-start_time:.4f} s')