Recherche de symétries dans les carrés

14

Écrivez un programme ou une fonction qui accepte une liste d'entiers positifs. Chacun de ces nombres entiers représente la longueur latérale d'un carré sur un plan 2D. Chaque carré peut être déplacé vers n'importe quelle coordonnée entière dans le plan, mais il ne peut pas pivoter ni chevaucher d'autres carrés.

En utilisant un caractère ASCII imprimable différent pour chaque carré (à l'exclusion de l'espace utilisé pour le vide), votre programme / fonction doit imprimer tout arrangement unique des carrés ayant une ligne horizontale ou verticale de symétrie de réflexion. Si un tel arrangement n'existe pas, rien ne doit être imprimé.

Les carrés sont des caractères différents afin de pouvoir les distinguer. Seule la forme faite par l'union de tous les carrés doit être symétrique. Vous pouvez supposer que la liste ne contiendra pas plus de 94 éléments (car il y a 94 caractères).

Par exemple, si l'entrée était [2, 1, 2, 2, 2], une sortie possible est:

DD--
DD--
Z
FFPP
FFPP

Cette forme a une ligne horizontale de symétrie de réflexion; ses moitiés supérieure et inférieure sont des images miroir. Voici quelques autres possibilités: (Notez que les carrés n'ont pas besoin de se toucher et tous les caractères peuvent être utilisés tant qu'il n'y a pas deux carrés avec le même caractère.)

  55
  55
  %%
  %%
@
  HH
  HH
  ((
  ((
       G

     11 33
     11 33

    22   44
    22   44

La ligne de symétrie pourrait également être la frontière entre les caractères, par exemple pour [2, 4]:

!!!!
!!!!  ++
!!!!  ++
!!!!

Certains ensembles de carrés sont impossibles à organiser symétriquement, par exemple [1, 2, 3]:

AAA BB C
AAA BB         (these can't be vertically or horizontally symmetric => no output)
AAA

Et rappelez-vous que la forme globale peut être symétrique même si les limites carrées ne le sont pas. Par exemple, une sortie valide pour [2, 1, 1, 1, 1, 4]est:

AA----
AA----
BC----
DE----

De même, une sortie valide pour [1, 1, 2, 3, 5]est:

44444
44444
44444
44444
44444
33301
33322
33322

Remarques

  • La liste d'entrée comprendra toujours de 1 à 94 éléments.
  • Prenez l'entrée de n'importe quelle manière raisonnable: stdin, ligne de commande, fichier texte, fonction arg. Il peut être légèrement formaté pour répondre à vos besoins, par exemple {1, 2, 3, 4}ou [1 2 3 4].
  • Sortie vers stdout ou similaire. Toutes les quantités d'espaces de début / fin ou de nouvelles lignes sont correctes tant que la forme résultante a la ligne de symétrie.
  • Une ligne de symétrie diagonale ne compte pas (sinon ce serait super facile). De plus, il doit s'agir d'une symétrie réflexionnelle et non pas de rotation ou de transition.
  • Honnêtement, je ne sais pas à quel point cette tâche est difficile à calculer. Vous pouvez publier des réponses partielles qui résolvent certains sous-ensembles du problème (surtout si vous voulez montrer un algorithme particulièrement intelligent). Ceux-ci ne sont pas éligibles pour gagner.
    • Par exemple, vous pouvez supposer que l'entrée a toujours au moins une disposition symétrique (donc les listes comme [1, 2, 3]ne sont jamais entrées).
    • Ou, par exemple, vous ne pouvez considérer que les dispositions où les limites carrées, ainsi que la forme générale, sont symétriques. Dans ce cas, [1, 1, 2, 3, 5]n'aurait aucune sortie.
    • Si vous voulez devenir fou, vous pouvez étendre l'idée aux rectangles ou même aux polyominos .

Notation

Votre score est la taille de votre programme en octets . Le score le plus bas l'emporte. Tiebreaker va la réponse affichée en premier.

Loisirs de Calvin
la source
2
Points bonus pour la résolution [2, 4, 6, 7, 8, 9, 11, 15, 16, 17, 18, 19, 24, 25, 27, 29, 33, 35, 37, 42, 50, 112], bien que, puisque la question donne beaucoup plus de liberté, il existe probablement d'autres solutions.
Sp3000

Réponses:

4

Python 2, 460 452 437 octets

exec"""def f(L):
 if[]==L:
  X{2}[map(" ".__lt__,q)for q in G]);Z{2}zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x)
 for n in range(T*T):
  i=n%T;j=n/T
  if all({1}=" "{0}):
{0}:{1}chr(32+len(L))
   r=f(L[:-1])
{0}:{1}" "
   if r:return r""".format("   for a,b in[(a,b)for a in R for b in R]","G[i+a][j+b]=","=filter(sum,")
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)

Je n'ai joué que légèrement au golf pour l'instant, mais voici quelque chose pour commencer. J'ai essayé d'utiliser les execlignes 10 et 12, mais pour une raison quelconque, cela ne m'a pas permis.

Entrez la liste Lvia STDIN, par exemple [2, 1, 2, 2, 2]. Le programme essaie simplement toutes les possibilités de placer des carrés dans une sum(L) x sum(L)grille.

Exemple de sortie (lignes vierges supprimées pour plus de compacité):

[2, 1, 2, 2, 2]

%%       
%%       
$$       
$$       
"        
##       
##       
!!       
!!      

[2, 4]

""""  
""""  
""""  
""""  
 !!   
 !!   

[2, 1, 1, 1]

$!!  
#!!  
 "   

[1, 1, 2, 3, 5]

%%%%%       
%%%%%       
%%%%%       
%%%%%       
%%%%%       
$$$##       
$$$##       
$$$"!       

[1, 4, 1, 8]

$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
# """" !      
  """"        
  """"        
  """"        

[8, 1, 4, 1]

$   !!!!!!!!  
    !!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
    !!!!!!!!  
"   !!!!!!!!  

(The algorithm starts placing from the last square first, prioritising left then up)

Version légèrement moins déroutante (452 ​​octets):

def f(L):
 if[]==L:
  X=filter(sum,[map(" ".__lt__,q)for q in G]);Z=filter(sum,zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x);V=[(a,b)for a in R for b in R]
 for n in range(T*T):
  i=n%T;j=n/T
  if all(G[i+a][j+b]<"!"for a,b in V):
   for a,b in V:G[i+a][j+b]=chr(32+len(L))
   r=f(L[:-1])
   for a,b in V:G[i+a][j+b]=" "
   if r:return r
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)
Sp3000
la source
@ Calvin'sHobbies Je viens de réaliser que j'ai oublié de supprimer les lignes et les colonnes vides (ce qui aurait signifié que la configuration devait également être symétrique par rapport à la carte ). [1, 1, 2, 3, 5]fonctionne maintenant bien.
Sp3000
Ah. Je pensais que la force brute prenait juste une éternité.
Calvin's Hobbies
@ Calvin'sHobbies C'est le cas pour les plus grandes planches, mais mettre des contraintes supplémentaires ne fait qu'empirer les choses: P
Sp3000
Je pense que vous pouvez enregistrer certains caractères en utilisant l' astuce d'indentation .
Calvin's Hobbies