◂ 8 décembre 2024 ▸
Resonant Collinearity : Prolonger des lignes de points entiers à partir de paires de deux points.
.......A....h.R. …
.A.4z......y.p.. …
...............h …
⋮
Code qui vérifie (pour rien avec les données de départ) aussi les points intermédiaires, via un PGDC des différences x et y des points.
Visuel sympa fait par
jimsqueak sur Reddit.
- code.py
- pointsTraitsExemple.jpg
- points.jpg
- pointsTraits.jpg
- vizualisation08_by_reddituser_jimsqueak.mp4
import math
with open("input.txt", 'r', encoding='utf-8') as f:
lines = [line[:-1] for line in f.readlines()]
W = len(lines[0])
H = len(lines)
nb = 0
antennas = {}
for y,line in enumerate(lines):
for x,c in enumerate(line):
if c == '.':
continue
if c not in antennas:
antennas[c] = []
antennas[c].append((x,y))
# Legacy of bad understanding of part 1
def thirds(x1, y1, x2, y2):
if (x2-x1) % 3 != 0 or (y2-y1) % 3 != 0:
return []
else:
return [ ( (2*x1+x2)//3, (2*y1+y2)//3 ),
( (x1+2*x2)//3, (y1+2*y2)//3 ) ]
def get_antinode_left_part1(x1, y1, x2, y2):
xn = 2*x2 - x1
yn = 2*y2 - y1
if 0 <= xn < W and 0 <= yn < H:
return (xn,yn)
else:
return None
def get_antinodes_part2(x1, y1, x2, y2):
r = [(x1,y1)]
dx = x2 - x1
dy = y2 - y1
d = math.gcd(dx, dy) # d is always 1 with the data provided :-/
px = dx // d
py = dy // d
for direction in (1, -1):
x,y = x1,y1
while 0 <= x < W and 0 <= y < H:
r.append((x,y))
x += px * direction
y += py * direction
return r
antinodes1 = set()
antinodes2 = set()
for places in antennas.values():
for i in range(len(places) - 1):
for j in range(i+1, len(places)):
antinodes1.add(get_antinode_left_part1(*places[i], *places[j]))
antinodes1.add(get_antinode_left_part1(*places[j], *places[i]))
antinodes2.update(get_antinodes_part2(*places[i], *places[j]))
antinodes1.remove(None)
answer_part1 = len(antinodes1)
answer_part2 = len(antinodes2)
# Draw initial grid
print('\n'.join(lines), '\n')
# and now with antinodes of part 2
for y,line in enumerate(lines):
for x,c in enumerate(line):
if (x,y) in antinodes2:
print('·' if c == '.' else '#', end='')
else:
print(' ' if c == '.' else c, end='')
print()
print("Réponse partie 1 :", answer_part1)
print("Réponse partie 2 :", answer_part2)
# A little stat
all_letters = set()
for start, end in ('09', 'AZ', 'az'):
all_letters.update(chr(val) for val in range(ord(start), ord(end)+1))
present = antennas.keys()
if len(present) > len(all_letters) // 2:
message = 'all but '
letters = all_letters.difference(set(present))
else:
message = ''
letters = present
print("Number of frequencies :", len(antennas), '(' + message + ''.join(sorted(letters)) + ')') # Tous les chiffres et lettres prises, sauf BKMV et bkmv.