◂ 13 décembre 2023 ▸
Point of Incidence : Trouver des axes de symétrie avec droit à une différence
#.#.##.##.#
#..#..####.
#.#####..##
⋮
..##.##.##.
..#.#..##..
#.....###..###.
.###....#..#...
⋮
- code.py
f = open("input.txt", 'r', encoding='utf-8')
lines = [line[:-1] for line in f.readlines()]
grilles = [[]]
for line in lines:
if line == '':
grilles.append([])
else:
grilles[-1].append(list(line))
def calc_nb_diffs(tab1, tab2): # 0, 1 ou 2 (=2 ou plus)
nb_diff = 0
for i in range(len(tab1)):
if tab1[i] != tab2[i]:
nb_diff += 1
if nb_diff == 2:
break
return nb_diff
def trouver_lignes_similaires_premiere(lignes: list[list[str]]) -> tuple[list[int],list[int]]:
""" retourne les indices des lignes similaires, dans deux listes : une pour lignes égales
et une pour les lignes qui ont une différence de 1 caractère. """
listes_indices = ([],[])
for row in range(1, len(lignes), 2): # parcourir de 2 en 2, car l'axe doit être *entre* deux lignes
ligne = lignes[row]
nb_diff = calc_nb_diffs(ligne, lignes[0])
if nb_diff < 2:
listes_indices[nb_diff].append(row)
return listes_indices
def trouver_indices_axe_horiz_debut(grille):
indices_parties = [[],[]]
for nb_erreur_depart, indices in zip([0,1], trouver_lignes_similaires_premiere(grille)):
for indice in indices:
nb_erreurs = nb_erreur_depart
ok = True
for i in range(1, indice//2+1):
nb_diff = calc_nb_diffs(grille[i], grille[indice-i])
if nb_erreurs + nb_diff > 1:
ok = False
break
else:
nb_erreurs += nb_diff
if ok:
indices_parties[nb_erreurs].append(indice)
return indices_parties
def trouver_indices_axes(grille) -> tuple[list[int], list[int]]:
""" Retourne la liste des axes horizontaux pour chaque partie, puis la liste des axes verticaux"""
indices_axes_verticaux = 2*[0]
indices_axes_horizontaux = 2*[0]
trouve = 2*[False]
grille_lignes_inversees = grille[::-1]
grille_colonnes_inversees = [[grille[r][c] for r in range(len(grille))] for c in range(len(grille[0]))]
grille_toute_inversee = grille_colonnes_inversees[::-1]
for g in [grille, grille_lignes_inversees, grille_colonnes_inversees, grille_toute_inversee]:
indice = trouver_indices_axe_horiz_debut(g)
assert all(len(id) <= 1 for id in indice)
for partie in (0,1):
if indice[partie]:
indice[partie] = indice[partie][0]
assert not trouve[partie]
trouve[partie] = True
if g is grille:
indices_axes_horizontaux[partie] += (indice[partie] + 1) // 2
elif g is grille_lignes_inversees:
indices_axes_horizontaux[partie] += (2*len(g) - indice[partie] - 1) // 2
elif g is grille_colonnes_inversees:
indices_axes_verticaux[partie] += (indice[partie] + 1) // 2
else: # g is grille_toute_inversee
indices_axes_verticaux[partie] += (2*len(g) - indice[partie] - 1) // 2
#if all(trouve): # Rapide même sans ça et permet de vérifier qu'il n'y a pas plusieurs solutions
# break
assert all(trouve)
return (indices_axes_horizontaux, indices_axes_verticaux)
somme_indices_verticaux = [0,0]
somme_indices_horizontaux = [0,0]
for grille in grilles:
indices_axes_horizontaux, indices_axes_verticaux = trouver_indices_axes(grille)
for partie in (0,1):
somme_indices_horizontaux[partie] += indices_axes_horizontaux[partie]
somme_indices_verticaux[partie] += indices_axes_verticaux[partie]
for partie in (0,1):
print(f"Réponse partie {partie+1}:", 100*somme_indices_horizontaux[partie] + somme_indices_verticaux[partie])