Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- from PIL import Image, ImageDraw
- # Read the input file
- with open('input.txt', 'r') as file:
- antenna_grid = np.array([[x for x in line] for line in file.read().split('\n') if line != ''])
- rows, cols = antenna_grid.shape
- # Extract antenna positions from the grid
- antenna_positions = {}
- for r, c in zip(*np.nonzero(antenna_grid != '.')):
- frequency = antenna_grid[r, c]
- if frequency not in antenna_positions:
- antenna_positions[frequency] = [(r, c)]
- else:
- antenna_positions[frequency].append((r, c))
- class Antinode:
- def __init__(self, pos: tuple[int, int]):
- self.pos = pos
- self.diameter = 100
- self.animating = True
- def update(self):
- if self.diameter > 30:
- self.diameter -= 2.5
- else:
- self.animating = False
- def draw(self, draw: ImageDraw):
- draw.circle(self.pos, self.diameter/2, outline='#f00', width=int(-1/7*self.diameter + 21))
- W = 2300
- H = 2500
- GRID_SIZE = 2200
- GRID_X = (W - GRID_SIZE) / 2
- GRID_Y = (W - GRID_SIZE) / 2 + H - W
- def grid_to_image_coords(x: int, y: int) -> tuple[int, int]:
- return (x + 1) * (GRID_SIZE / (cols+1)), (y + 1) * (GRID_SIZE / (cols+1))
- frame = 0
- def draw_frame():
- # DRAW GRID IMAGE
- grid_img = Image.new(mode='RGB', size=(GRID_SIZE, GRID_SIZE), color='#fff')
- draw = ImageDraw.Draw(grid_img)
- # antinodes
- for antinode in antinodes:
- antinode.draw(draw)
- # line
- if line_pos1 != None != line_pos2:
- draw.line((line_pos1, line_pos2), fill='#88f', width=20, joint='curve')
- draw.circle(pos1, 45, fill='#00f')
- draw.circle(pos2, 40, fill='#00f')
- # antennas
- for frequency in antenna_positions:
- for r, c in antenna_positions[frequency]:
- pos = grid_to_image_coords(r, c)
- fill = '#000' if pos1 == None or pos1 != pos != pos2 or line_pos1 == None else '#fff'
- size_mult = 1.0 if pos1 == None or pos1 != pos != pos2 or line_pos1 == None else 1.5
- draw.text(pos, frequency, fill=fill, font_size=(GRID_SIZE / (cols-1)) * size_mult, anchor='mm')
- img = Image.new(mode='RGB', size=(W, H), color='#fff')
- draw = ImageDraw.Draw(img)
- # DRAW COMPLETE FRAME
- img = Image.new(mode='RGB', size=(W, H), color='#fff')
- draw = ImageDraw.Draw(img)
- # paste image
- p = 8
- draw.rectangle((GRID_X - p, GRID_Y - p, GRID_X + GRID_SIZE + p, GRID_Y + GRID_SIZE + p), fill='#333')
- Image.Image.paste(img, grid_img, (int(GRID_X), int(GRID_Y)))
- # counter
- draw.text((W / 2, 140), f'antinode locations: {len(antinode_positions)}', fill='#000', font_size=135, anchor='mm')
- global frame
- img.save(f'./frames/frame_{str(frame).zfill(4)}.png', 'PNG')
- frame += 1
- # Check each pair of antennas for antinodes
- antinodes = []
- def update_all_antinodes():
- for antinode in antinodes:
- antinode.update()
- antinode_positions = set()
- line_pos1 = line_pos2 = pos1 = pos2 = None
- draw_frame()
- for frequency in antenna_positions:
- for i, (r1, c1) in enumerate(antenna_positions[frequency]):
- for j, (r2, c2) in enumerate(antenna_positions[frequency][i+1:], 1):
- antinode_r, antinode_c = r1 + r1-r2, c1 + c1-c2
- line_pos1 = grid_to_image_coords(antinode_r, antinode_c)
- if 0 <= antinode_r < rows and 0 <= antinode_c < cols:
- if (antinode_r, antinode_c) not in antinode_positions:
- antinodes.append(Antinode(grid_to_image_coords(antinode_r, antinode_c)))
- antinode_positions.add((antinode_r, antinode_c))
- antinode_r, antinode_c = r2 + r2-r1, c2 + c2-c1
- line_pos2 = grid_to_image_coords(antinode_r, antinode_c)
- if 0 <= antinode_r < rows and 0 <= antinode_c < cols:
- if (antinode_r, antinode_c) not in antinode_positions:
- antinodes.append(Antinode(grid_to_image_coords(antinode_r, antinode_c)))
- antinode_positions.add((antinode_r, antinode_c))
- pos1 = grid_to_image_coords(r1, c1)
- pos2 = grid_to_image_coords(r2, c2)
- for _ in range(4):
- draw_frame()
- update_all_antinodes()
- line_pos1 = line_pos2 = None
- while any(antinode.animating for antinode in antinodes):
- draw_frame()
- update_all_antinodes()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement