Trovare simmetrie nei quadrati


14

Scrivi un programma o una funzione che contiene un elenco di numeri interi positivi. Ognuno di questi numeri interi rappresenta la lunghezza laterale di un quadrato su un piano 2D. Ogni quadrato può essere spostato su qualsiasi coordinata intera nel piano, ma non può ruotare e non può sovrapporsi ad altri quadrati.

Utilizzando un diverso carattere ASCII stampabile per ogni quadrato (escluso lo spazio utilizzato per il vuoto), il programma / funzione deve stampare ogni singola disposizione dei quadrati che abbia una linea orizzontale o verticale di simmetria riflettente. Se tale disposizione non esiste, non è necessario stampare nulla.

I quadrati sono personaggi diversi solo per poter essere separati. Solo la forma creata dall'unione di tutti i quadrati deve essere simmetrica. Puoi presumere che l'elenco non conterrà più di 94 elementi (poiché ci sono 94 caratteri).

Ad esempio, se l'input fosse [2, 1, 2, 2, 2], un possibile output è:

DD--
DD--
Z
FFPP
FFPP

Questa forma ha una linea orizzontale di simmetria riflettente; le sue metà superiore e inferiore sono immagini speculari. Ecco alcune altre possibilità: (Nota che i quadrati non devono essere toccati e che tutti i personaggi possono essere usati purché non siano fatti due quadrati dello stesso personaggio.)

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

     11 33
     11 33

    22   44
    22   44

La linea di simmetria potrebbe anche essere il confine tra i caratteri, ad esempio per [2, 4]:

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

Alcuni insiemi di quadrati sono impossibili da disporre simmetricamente, ad esempio [1, 2, 3]:

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

E ricorda che la forma complessiva può essere simmetrica anche se non lo sono i confini quadrati. ad es. un output valido per[2, 1, 1, 1, 1, 4] è:

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

Allo stesso modo, un output valido per [1, 1, 2, 3, 5] è:

44444
44444
44444
44444
44444
33301
33322
33322

Appunti

  • L'elenco di input avrà sempre da 1 a 94 elementi.
  • Prendi l'input in modo ragionevole: stdin, riga di comando, file di testo, funzione arg. Può essere leggermente formattato per soddisfare le tue esigenze, ad esempio {1, 2, 3, 4}o[1 2 3 4] .
  • Uscita su stdout o simile. Qualsiasi quantità di spazi iniziali o finali o di nuove linee va bene purché la forma risultante abbia la linea di simmetria.
  • Una linea diagonale di simmetria non conta (altrimenti sarebbe super facile). Inoltre, deve essere una simmetria riflessiva, non rotazionale o di transizione.
  • Onestamente non sono sicuro di quanto sia difficile dal punto di vista computazionale. È possibile pubblicare risposte parziali che risolvono alcuni sottogruppi del problema (soprattutto se si desidera mostrare un algoritmo particolarmente intelligente). Questi non sono idonei a vincere.
    • Ad esempio, potresti supporre che l'input abbia sempre almeno una disposizione simmetrica (quindi elenchi come [1, 2, 3] non vengono mai inseriti).
    • Oppure, ad esempio, puoi prendere in considerazione solo le disposizioni in cui i contorni quadrati, nonché la forma complessiva, sono simmetrici. In questo caso,[1, 1, 2, 3, 5] avrebbe alcun output.
    • Se vuoi impazzire, potresti estendere l'idea a rettangoli o persino a poliomino .

punteggio

Il tuo punteggio è la dimensione del programma in byte . Vince il punteggio più basso. Tiebreaker risponde per prima.


2
Punti bonus per la risoluzione [2, 4, 6, 7, 8, 9, 11, 15, 16, 17, 18, 19, 24, 25, 27, 29, 33, 35, 37, 42, 50, 112], anche se poiché la domanda dà molta più libertà probabilmente ci sono altre soluzioni.
Sp3000,

Risposte:


4

Python 2, 460 452 437 byte

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)

Solo un po 'di golf per ora, ma ecco qualcosa per iniziare. Ho provato a usare execper le linee 10 e 12, ma per qualche motivo non me lo ha permesso.

Immettere l'elenco Ltramite STDIN, ad es [2, 1, 2, 2, 2]. Il programma prova semplicemente ogni possibilità di posizionare i quadrati in una sum(L) x sum(L)griglia.

Output del campione (righe vuote rimosse per compattezza):

[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)

Versione leggermente meno confusa (452 ​​byte):

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)

@Calvin'sHobbies Mi sono appena reso conto di aver dimenticato di eliminare righe e colonne vuote (il che avrebbe significato che anche la configurazione doveva essere simmetrica rispetto alla scheda ). [1, 1, 2, 3, 5]ora funziona bene.
Sp3000,

Ah. Pensavo che la forza bruta prendesse per sempre.
Calvin's Hobbies,

@Calvin'sHobbies Lo fa per schede più grandi, ma mettere ulteriori vincoli non fa che peggiorare: P
Sp3000

Penso che puoi salvare alcuni caratteri usando il trucco del rientro .
Calvin's Hobbies,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.