Considérons une grille de N
x N
éléments uniques. Chaque élément a une lettre (de A à la N
e lettre, inclus) et un nombre (de 1 à N
, inclus). Par conséquent, chaque paire chiffre / lettre se trouve dans la grille exactement une fois.
Votre travail consiste à organiser une grille telle que:
Chaque ligne, colonne et diagonale (y compris l'habillage) contient chaque lettre et chiffre exactement une fois.
En enveloppant, je veux dire que
* * * # *
* * # * *
* # * * *
# * * * *
* * * * #
est une diagonale, avec toutes les diagonales similaires qui frappent les bords.
Un exemple de 5x5
grille est:
A1 B2 C3 D4 E5
C4 D5 E1 A2 B3
E2 A3 B4 C5 D1
B5 C1 D2 E3 A4
D3 E4 A5 B1 C2
Votre tâche consiste à écrire un programme qui accepte un nombre N
, et à imprimer une grille N
x N
comme décrit ci-dessus. Votre programme devrait fonctionner pour tout 0 < N <= 26
. Si une grille particulière n'est pas possible, vous devez imprimer Impossible
.
Le codage en dur de la réponse N
n'est pas autorisé. Un programme est codé en dur s'il calcule la grille de manière différente (selon moi) pour tout N > 26
(ou s'il ne parvient pas à calculer). (Ceci est destiné à empêcher le précalcul, y compris les grilles invalides précalculées ou les décalages pour des grilles données).
C'est un problème de code le plus rapide, et votre score est la somme des temps nécessaires pour exécuter votre programme sur tous les possibles N
sur mon ordinateur. Dans votre réponse, veuillez exécuter votre programme sur tout N
(je n'ai donc à le chronométrer qu'une seule fois). Si aucun programme ne peut le calculer en moins de 60 secondes, le gagnant est la réponse qui peut calculer la grille avec la plus grande N
en 60 secondes. Si plusieurs programmes ont le même maximum N
, le bris d'égalité est la solution la plus rapide.
(J'ai une machine Windows 8 correctement alimentée, et tous les compilateurs ou interprètes nécessaires doivent être disponibles gratuitement).
la source
Réponses:
Python 3
Comment ça fonctionne?
La mise en œuvre naïve consisterait à parcourir tous les arrangements possibles de lettres et de chiffres dans une grille NxN et à en rechercher un qui est également un carré latin orthogonal-diagonal (ODLS) (et donc, pour certains, il suffirait de parcourir tous les configurations et retour impossible). Un tel algorithme ne répondrait pas à ce défi en raison d'une complexité temporelle absurde. Il y a donc trois simplifications et justifications majeures (preuves partielles et aperçu de pourquoi cela fonctionne) aux constructions ODLS utilisées dans mon implémentation:
La première est la notion selon laquelle il suffit de générer un carré latin diagonal valide (une grille NxN telle que chaque ligne, colonne, diagonale enveloppée contient chaque élément d'un ensemble de N éléments distincts exactement une fois) des N premières lettres du alphabet. Si nous pouvons construire un tel carré latin diagonal (DLS), un ODLS peut être construit en utilisant le DLS avec un échange d'éléments approprié et un retournement. Justification:
La deuxième simplification est la notion que si nous trouvions une configuration (SC) appropriée d'un élément (une grille NxN telle que chaque ligne, colonne, diagonale enveloppée contient cet élément exactement une fois), alors un DLS pourrait être construit en remplaçant l'élément et déplacer le SC. Justification:
La dernière simplification est la suivante - tous les DLS de N premiers, à l'exception de N = 2 ou N = 3, peuvent être construits, et si N peut être factorisé en deux nombres dont le DLS approprié peut être construit, alors un DLS de ce N peut être construit. Je suppose que l'inverse est également valable. (En d'autres termes, nous ne pouvons construire qu'un DLS pour N qui n'est pas divisible par 2 ou 3)
Une image de ce que je voulais dire avec le DLS plus petit - plus grand
la source