Risolvi Grid-Tangram


22

Il Tangram è un puzzle di dissezione composto da sette forme: cinque triangoli di dimensioni diverse, un parallelogramma e un quadrato. Data una forma, l'obiettivo è ricreare la forma usando tutti i pezzi e senza sovrapposizioni. Esistono ovviamente infiniti modi per disporre questo insieme di pezzi sull'aereo. Un sottoinsieme interessante sono i

Tangram di griglia

Possiamo disegnare il quadrato Tangram "standard" in un quadrato più grande che è suddiviso da una griglia in 16 quadrati più piccoli. I tangram di griglia sono solo forme costituite dai pezzi del tangram, in modo tale che tutti i vertici dei pezzi si trovano sui punti della griglia.

Questi sono i tipi di puzzle Tangram che vogliamo prendere in considerazione in questa sfida, poiché sono probabilmente più facili da gestire rispetto a quelli più generali.

Come nota a margine: i matematici cinesi Chuan-Chin Hsiung e Fu Traing Wang hanno dimostrato nel 1942 che ci sono solo 13 tangram convessi. Inizialmente hanno mostrato che il problema può essere ridotto a tangrams a griglia, e quindi hanno usato alcuni argomenti combinatori e geometrici. Questi sono tutti quei 13:

Sfida

Dato un tangram di griglia risolvibile, emettere una dissezione del tangram di griglia nei sette pezzi di tangram.

IO

Un tangram è dato come un'immagine in bianco e nero (la forma è in nero, lo sfondo in bianco), con entrambi i lati multipli di 50px. La griglia ha una larghezza di esattamente 50 px. Le linee della griglia sono parallele ai lati dell'immagine.

EDIT: l'immagine può essere accettata come input e restituita come output in qualsiasi formato di immagine raster conveniente come PNG, TIFF, PBM ecc. Ma è accettabile una rappresentazione come array binario 2d o stringa o matrice.

L'output dovrebbe avere di nuovo le stesse dimensioni e dovrebbe avere di nuovo la stessa forma, ma con ogni pezzo di un colore diverso, o in alternativa con linee bianche che separano tutti i pezzi. Vale la pena notare che il quadrangolo non rettangolare può essere capovolto.

I pixel sul bordo dei pezzi non devono corrispondere esattamente a quelli sulla forma, anche se ci sono effetti di aliasing o altri fuzz questo va ancora bene.

Esempio di input e output:

Esempi:

Possibili soluzioni:


l'elaborazione delle immagini è un ostacolo del tutto inutile in questa sfida. Lo troverei molto più attraente se avessi specificato l'input come un piccolo array binario.
Sparr,

1
Come ho detto, questo è stato discusso quando era nella sandbox. Ma dubito che aggiunga molti byte, poiché l'attività stessa è molto più difficile.
flawr,

3
Sono stato una delle persone a raccomandare che l'input e l'output fossero come sono, e ho fatto questa raccomandazione perché questo è, a mio avviso, il modo più naturale e appropriato per presentare una sfida Tangram. Qualsiasi forma di input / output richiederebbe un numero significativo di byte, quindi non penso che sia davvero un problema qui.
El'endia Starman,

1
Sono d'accordo con Elendia. L'unico problema con l'I / O grafico è che potrebbe limitare i linguaggi che non dispongono di funzionalità grafiche. Detto questo, PBM e PGM sono così vicini all'arte ASCII che non ci sono problemi reali, SE è il caso che le persone siano a conoscenza di tali formati. en.wikipedia.org/wiki/Netpbm_format
Level River St

1
@LevelRiverSt Questo è un buon punto, penso che sarebbe totalmente accettabile usare quei formati o persino un array / stringa 2d di zero e uno.
flawr

Risposte:


31

BBC BASIC, 570 514 490 byte ASCII

Scarica l'interprete su http://www.bbcbasic.co.uk/bbcwin/download.html

435 byte tokenizzati

Il programma completo visualizza un input dallo L.bmpschermo, quindi lo modifica per trovare una soluzione.

*DISPLAY L
t=PI/8q=FNa(1)
DEFFNa(n)IFn=7END
LOCALz,j,p,i,c,s,x,y,m,u,v
F.z=0TO99u=z MOD10*100v=z DIV10*100ORIGINu,v
F.j=0TO12S.4p=0F.i=j+3TOj+9S.2c=9*COS(i*t)s=9*SIN(i*t)p=p*4-(POINT(c,s)<>0)*2-(POINT(9*c,9*s)<>0)N.
m=n:IFn=5A.(43A.p)=0p=0m=7
IF(ASCM."??O|(C",n)-64A.p)=0THEN
F.i=-1TO0GCOL0,-i*n:c=99*COS(j*t)s=99*SIN(j*t)y=402/3^m MOD3-1MOVE-c-s*y,c*y-s:x=n<3MOVEc*x-s*x,s*x+c*x:x=2778/3^m MOD3-1y=5775/3^m MOD3-1PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y:IFi q=FNa(n+1)ORIGINu,v
N.
ENDIF
N.N.=0

Spiegazione

Si noti che nella BBC di base una distanza di 1 pixel = 2 unità, quindi la griglia di 50x50 pixel diventa una griglia di 100x100.

Usiamo una funzione ricorsiva per posizionare i 2 triangoli grandi, triangolo medio, quadrato e parallelogramma nella forma. La forma precedente nell'elenco viene disegnata prima che venga effettuata la successiva chiamata ricorsiva. se una chiamata ricorsiva ritorna senza trovare una soluzione, la forma precedente viene sovrascritta in nero e viene tentata una nuova posizione della forma precedente.

Una volta disegnate queste cinque forme, posizionare i due piccoli triangoli è solo una formalità. È necessario disegnarne uno, tuttavia, per distinguerli se condividono un vantaggio comune. Coloriamo solo uno dei due piccoli triangoli. L'altro è lasciato in nero naturale.

Si tenta di posizionare ciascuna forma su diverse coordinate x, y e in 4 diverse rotazioni. Per verificare se c'è spazio libero per disegnare una forma, usiamo il modello qui sotto, con angoli di 45 gradi. Le rotazioni sono fatte attorno agli *e 8 pixel testati sono in 2 semicerchi di raggio 9 e 81 unità e cadono su linee radianti a multipli dispari di 22,5 gradi rispetto agli assi xe y.

Per un triangolo grande tutti e 8 gli spazi devono essere chiari. Per altre forme, solo alcune delle celle devono essere chiare, quindi viene applicata una maschera.

+----+----   Shape             Mask HGFEDCBA Mask decimal 
|\ E/|\G /  
| \/F|H\/    1,2. Large triangle    11111111    -1
|C/\ | /     3. Med triangle        00001111    15
|/ D\|/      4. Square              00111100    60
+----*       5. Parallelogram       11101000   -24
|\ B/        6. Small triangle      00000011     3
|A\/         7. Parallogr reversed  00101011    43
| /          Note: reversed parallelogram is checked/drawn at recursion depth n=5
|/           with a special check, but the coordinates are encoded as m=7.  

Una volta stabilito che una forma si adatta, deve essere disegnata. Se è un triangolo con cui è tracciato PLOT 85, se è un parallelogramma, il numero è 32 più alto (si noti che ai PLOTfini consideriamo un quadrato un parallelogramma speciale). In entrambi i casi devono essere indicati 3 vertici consecutivi. Il secondo vertice è l'origine della forma (segnata *nella tabella sopra) tranne nel caso del triangolo grande, dove (prima della rotazione) è -1,-1.Gli altri 2 vertici possono avere coordinate xey -1,0 or 1che sono estratte dalla base 3 numeri codificati, quindi ridimensionati di 99 e ruotati secondo necessità mediante trasformazione con ce s.

Codice Ungolfed

  *DISPLAY L
  t=PI/8                                          :REM Constant 22.5 degrees.
  q=FNa(1)                                        :REM Call function, return dummy value to q
  END                                             :REM End the program gracefully if no solution. Absent in golfed version.

  DEFFNa(n)                                       :REM Recursive function to place shapes.
  IFn=7END                                        :REM If n=7 solution found, end program.
  LOCALk,z,j,p,i,c,s,x,y,m,u,v                    :REM declare local variables for function.
  k=ASCMID$("??O|(C",n)-64                        :REM Bitmasks for big tri, big tri, med tri, sq, normal paralellogram, small tri.
  FORz=0TO99                                      :REM For each point on the grid
    u=z MOD10*100:v=z DIV10*100                   :REM calculate its x and y coordinates relative to bottom left of screen
    ORIGINu,v                                     :REM and set the origin to this point.
    FORj=0TO12STEP4                               :REM For each rotation 0,90,180,270deg
      p=0                                         :REM assume no non-black pixels found
      FORi=j+3TOj+9STEP2                          :REM test angles of 3,5,7,9 times 22.5 deg anticlockwise from right x axis.
        c=9*COS(i*t)                             :REM Coords of test points at radius ll
        s=9*SIN(i*t)
        p*=4                                      :REM Leftshift any existing data in p
        p-=(POINT(c,s)<>0)*2+(POINT(9*c,9*s)<>0)  :REM and check pixels at radius 11 and 99.
      NEXT
      m=n                                         :REM The index of the shape to plot normally corresponds with recursion depth n.
      IF n=5 AND (43ANDp)=0 p=0:m=7               :REM If n=5 check if a reverse parallelogram is possible (mask 43). If so, clear p and change m to 7.
      REM                                         :REM Check p against mask k, if the shape fits then...
      IF (k ANDp)=0 THEN
        FOR i=-1 TO 0                               :REM draw the shape in colour, and if deeper recursions prove unsuccesful, redraw it in black.
          GCOL0,-i*n                                :REM Colour is equal to n.
          c=99*COS(j*t)                             :REM Set parameters c and s for scaling by 99
          s=99*SIN(j*t)                             :REM and rotation by 0,90,180 or 270 as appropriate.
          x=-1                                      :REM For vertex 1, x=-1 always.
          y=402/3^m MOD3-1                          :REM Lookup y value for vertex 1.
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=n<3                                     :REM For vertex 2, coords are 0,0 except for large triangle where they are -1,-1
          y=x                                       :REM in BBC BASIC, TRUE=-1
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=2778/3^m MOD3-1                         :REM Lookup x and y value for vertex 3.
          y=5775/3^m MOD3-1                         :REM PLOT85 uses last 2 points + specified point to make triangle, PLOT85+32 makes paralelogram (or square.)
          PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y      :REM Use c and s to transform the vertex and draw shape.
          IFi q=FNa(n+1):ORIGINu,v                  :REM If i=-1 recurse to next level. If it fails, reset the origin before replotting this level's shape in black.
        NEXT
      ENDIF
    NEXT
  NEXT
  =0                                                :REM Dummy value to return from function

Produzione

Questo è un montaggio delle soluzioni trovate dal programma per i casi di test. L'uso di 99 anziché 100 per motivi di golf lascia delle piccole lacune nere. Poiché le forme vengono ridisegnate durante le ricerche, in alcuni casi possono essere necessari alcuni secondi, ed è piuttosto affascinante da guardare.

inserisci qui la descrizione dell'immagine


4
Wow, sono impressionato. Ora mi piacerebbe vederne un video in azione! =)
flawr
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.