Quale tetromino è questo?


54

Dato un unsigned interi a 16 bit N , il vostro compito è quello di determinare se la sua rappresentazione binaria mappato all'interno di una matrice 4x4 viene trovata una corrispondenza forma tetromino , in caso affermativo, quale forma è.

Matrice

Ogni bit di N è mappato all'interno di una matrice 4x4, da sinistra a destra e dall'alto verso il basso, a partire da quella più significativa.

Esempio :

N = 17600
binary representation: 0100010011000000
matrix: [ [ 0, 1, 0, 0 ],
          [ 0, 1, 0, 0 ],
          [ 1, 1, 0, 0 ],
          [ 0, 0, 0, 0 ] ]

Forme Tetromino

Forme di base

Esistono 7 forme di tetromino, identificate dalle lettere O , I , S , Z , L , J e T :

tetrominoes

Rotazioni e traduzioni

Se una forma viene tradotta e / o ruotata all'interno della matrice 4x4, viene comunque considerata una valida variazione dello stesso tetromino. Ad esempio, 17600, 1136, 2272 e 1604 dovrebbero essere identificati come J tetrominoes:

esempi J validi

Non avvolgere!

Tuttavia, le forme non possono avvolgersi o spostarsi oltre i confini della matrice. Ad esempio, 568 688 dovrebbero essere identificati come J tetrominoes (per non parlare di qualsiasi altra forma):

esempi J non validi

Chiarimenti e regole

  • Puoi prendere l'input come numero intero o direttamente come 16 cifre binarie in qualsiasi formato ragionevole, come un array 2D, un array piatto o una stringa delimitata.
  • Si garantisce che l'ingresso sia un numero intero a 16 bit senza segno (o la sua rappresentazione equivalente come matrice o stringa).
  • Quando viene identificata una forma valida, è necessario stampare o restituire la lettera che identifica la forma, in lettere minuscole o maiuscole.
  • Se non viene identificata alcuna forma, è necessario stampare o restituire un valore che non corrisponde a nessuna lettera tetromino. Puoi anche scegliere di non restituire nulla.
  • Per essere considerata valida, la matrice deve contenere la forma esatta del tetromino senza ulteriori celle (vedere 1911 e 34953 nei casi di test).
  • Questo è , quindi vince la risposta più breve in byte!

Casi test

È possibile seguire questo collegamento per ottenere i casi di test come array 2D.

0      -> false
50     -> false
51     -> 'O'
1911   -> false
15     -> 'I'
34952  -> 'I'
34953  -> false
1122   -> 'S'
3168   -> 'Z'
785    -> 'L'
1136   -> 'J'
568    -> false
688    -> false
35968  -> 'T'
19520  -> 'T'

È interessante notare che stavo lavorando su un problema estremamente simile l'altro giorno prima che mi distrassi creando una tecnica per utilizzare le catene di funzioni func1 . func2 . func3in JS: P
ETHproductions

Posso prendere input come le quattro righe unite 0, ad esempio 1111011110111101111per 65535?
ETHproductions

@ETHproductions Sembra perfetto. Ho modificato la sfida con un formato di input leggermente rilassato.
Arnauld,

3
I: 15,240,3840,4369,8738,17476,34952,61440J: 71,113,142,226,275,550,802,1100,1136,1604,1808,2272,3208,3616,4400,8800,12832,17600,18176,25664,28928,36352,51328,57856L: 23,46,116,232,368,547,736,785,1094,1570,1856,2188,3140,3712,5888,8752,11776,12560,17504,25120,29696,35008,50240,59392O: 51,102,204,816,1632,3264,13056,26112,52224S: 54,108,561,864,1122,1728,2244,8976,13824,17952,27648,35904T: 39,78,114,228,305,562,610,624,1124,1220,1248,1824,2248,3648,4880,8992,9760,9984,17984,19520,19968,29184,35968,58368Z:99,198,306,612,1224,1584,3168,4896,9792,19584,25344,50688
Engineer Toast

^ Generato usando la risposta di Python 3 di Lynn perché aveva formati di input / output convenienti.
ingegnere Toast il

Risposte:


6

Gelatina ,  54 43 42  41 byte

-1 byte grazie a Erik the Outgolfer (sposta trasposizione all'interno di una catena ripetuta)

T€FṀ⁸ṙ€Zµ⁺F
ZU$3СǀḄṂ“çc3Ð6'G‘i’ị“¥Çıƭ⁵»

Un link monadica prendendo una matrice 2D di interi ( 1s e 0s) e restituendo una lettera minuscola oiszljtper il rispettivo tetromino o wse non valido.

Provalo online! o vedi la suite di test .

Vedi anche questo programma che elenca tutti i 1820 possibili array binari 2D con esattamente quattro bit impostati insieme alle loro uscite, ordinati per tali uscite.

Come?

Questo prima prende tutte e quattro le rotazioni dell'input. Quindi sposta i bit impostati di ciascuno il più a destra e quindi il più in basso possibile e converte i risultati in numeri binari. Quindi cerca il risultato minimo in un elenco del minimo di tali rappresentazioni di ciascun tetromino valido e utilizza il risultato decrementato per indicizzare le due parole del dizionario concatenate zoist+ jowl, producendo wquando non è stata trovata alcuna corrispondenza.

T€FṀ⁸ṙ€Zµ⁺F - Link 1, shift set bits right & then down : list of lists of bits          
        µ⁺  - perform the following twice, 1st with x=input, then with x=result of that):
T€          -   truthy indexes of €ach
  F         -   flatten into a single list
   Ṁ        -   maximum (the index of the right-most bit)
    ⁸       -   chain's left argument, x
     ṙ€     -   rotate €ach left by that amount
       Z    -   transpose the result
          F - flatten (avoids an € in the main link moving this into here)

ZU$3СǀḄṂ“çc3Ð6'G‘i’ị“¥Çıƭ⁵» - Main link: list of lists of bits (the integers 0 or 1)
   3С                        - repeat this 3 times collecting the 4 results:
  $                           -   last two links as a monad:
Z                             -     transpose
 U                            -     upend (reverse each) -- net effect rotate 90° CW
      Ç€                      - call the last link as a monad for €ach
        Ḅ                     - convert from binary (vectorises)
         Ṃ                    - minimum (of the four results)
          “çc3Ð6'G‘           - code-page indexes = [23,99,51,15,54,39,71]
                              -   ...the minimal such results for l,z,o,i,s,t,j shapes
                   i          - 1-based index of minimum in there or 0 if not found
                    ’         - decrement
                      “¥Çıƭ⁵» - compressed words: "zoist"+"jowl" = "zoistjowl"
                     ị        - index into (1 indexed & modular, so -1 yields 'w',
                              -             0 yields 'l', 1 yields 'z', ...)

Metodo precedente (54 byte)

Fœr0Ḅ“çc3Ðñ'G‘i
;Z$Ḅ©f“¦µ½¿Æ‘ȯ®¬S>2ȧZU$3СǀṀ’ị“¥Çıƭ⁵»

Un link monadica prendendo una matrice 2D di interi ( 1s e 0s) e restituendo una lettera minuscola oiszljtper il rispettivo tetromino o wse non valido.

Provalo online!

Questo controlla che ci siano almeno tre righe vuote (righe + colonne) e che alcuni schemi di bit non siano presenti in nessuna riga (in particolare i numeri 5,9,10,11 e 13), questi insieme assicurano che il passo successivo non produrrà falsi positivi. Quindi si appiattisce e quindi sposta a terra il numero binario (rimuovendo gli zeri finali prima della conversione) di ciascuna delle quattro rotazioni e cerca il risultato minimo in un elenco di numeri, usando il risultato decrementato per indicizzare le due parole del dizionario concatenate zoist+ jowl, cedendo wquando non è stata trovata alcuna corrispondenza.


E sapevo che c'era un modo migliore dell'hardcoding ...
Erik the Outgolfer

a proposito penso che questo codice dipenda da una coincidenza (perché, beh, zoistjowlnormalmente non andrebbe bene per una stringa altrimenti: p)
Erik the Outgolfer

Cosa intendi con "dipende da una coincidenza"? (la ricerca nel dizionario salva ...Ṁị“LZOISTJWcomunque solo un byte )
Jonathan Allan il

Hmm ... sì, sapevo che non sarebbe durato a lungo ... a proposito, penso che tu mi abbia rubato ZU$3С: p
Erik the Outgolfer,

Ieri stavo provando a fare lo stesso metodo dopo aver inviato il precedente ma penso di essere un po 'stanco.
Jonathan Allan,

28

Python 3 , 124 byte

def f(n):
 while n&4369<n/n:n>>=1
 while n&15<1:n>>=4
 return'TJLZSIO'["rēȣc63ıGtIJȱᄑ@'̢̑@@@@Ȳq".index(chr(n))%7]

Provalo online!

Si aspetta un numero intero n che rappresenti una matrice binaria 4 × 4. Lancia se non viene trovato nessun tetromino.

La linea 2 fa scorrere la forma verso destra fino a quando 1 è nella colonna più a destra. (4369 è 0001 0001 0001 0001in binario.) La linea 3 abbassa la forma fino a quando un 1 è nella riga inferiore. Insieme questo gira ad esempio:

    0 1 0 0        0 0 0 0
    1 1 1 0  into  0 0 0 0
    0 0 0 0        0 0 1 0
    0 0 0 0        0 1 1 1

Quindi cerchiamo l'indice di nin questo elenco:

 [114  275  547   99   54   15   51
  305   71  116  306  561 4369   64
   39  802  785   64   64   64   64
  562  113   23]
#   T    J    L    Z    S    I    O

Ogni colonna di indici equivalente modulo 7 corrisponde a una forma tetromino. 64 ( @) viene utilizzato come valore di riempimento poiché nnon può essere 64 a questo punto nel codice.

NB. Viene generata un'eccezione per l'input 0elaborando n/ninvece di 1.


Perché la tua stringa binaria funziona? Ho avuto problemi con quello in Python 3, vedi commenti codegolf.stackexchange.com/a/85201/53667
Karl Napf,

Python utilizza UTF-8 come codifica predefinita per il codice sorgente e per l'output del testo. Ma i file PPM non vengono letti in UTF-8. Quando si esegue print("ÿ"), i byte che vengono scritti sono c3 bf 0a, e non ff 0a, e le curve di immagine di PPM in spazzatura.
Lynn,

8

APL (Dyalog) , 95 94 93 89 87 byte

-2 grazie a Zacharý

Richiede il ⎕IO←0valore predefinito su molti sistemi. Prende la matrice booleana (di qualsiasi forma!) Come argomento. Non restituisce nulla se il numero di bit specificato non è quattro e una riga vuota se i quattro bit indicati non formano un tetromino.

{4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K2J),(⍳3)⊖¨⊂J1,⍪K31)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}

Provalo online!

Funziona creando tutte e quattro le rotazioni dell'input, quindi cercando ciascun tetromino in ciascuna rotazione.

{... } funzione anonima in cui l'argomento è rappresentato da :

,⍵ ravel (appiattire) l'argomento

+/ sommalo

4= è quattro uguale a quello?

: in tal caso, allora (altrimenti non restituisce nulla):

  ⍳4 primi quattro d ndices; [0,1,2,3]

  ⍵∘{...  applica la seguente funzione su ciascuna, usando l'input come argomento sinistro fisso

    l'argomento sinistro, cioè l'input

   ⊢⍺ cedere che (separa da )

   ⌽∘⍉⍣⍵ specchiare e trasporre (cioè ruotare di 90 °) volte

  (... )∘.⍷ "prodotto" esterno, ma usando Trova *, del seguente elenco e delle rotazioni:

   3↑1 prendi tre elementi da uno, riempiendo di zeri; [1,0,0]

   K← conservare quello come K

    tabella (trasforma in colonna vettore); [[1],[0],[0]]

   1, anteporre uno; [[1,1],[1,0],[1,0]]( "J")

   J← conservare come J

   (... )⊖¨⊂ ruota l'intera J verticalmente, ciascuno dei seguenti passi:

    ⍳3 primi tre ɩ ntegers;[0,1,2]

   abbiamo [[[1,1],[1,0],[1,0]],[[1,0],[1,0],[1,1]],[[1,0],[1,1],[1,0]]]("J", "L," T ")

   (... ), anteporre il seguente elenco:

    2⊖J ruotare di Jdue gradini in verticale; [[1,0],[1,1],[1,0]]( "T")

    K⌽ ruotare le righe di quella rispettivamente di 1, 0 e 0 passi; [[0,1],[1,1],[1,0]]( "Z")

    0 1⌽¨⊂ ruotare l'intero array in verticale, nessuna volta e una volta; [[[0,1],[1,1],[1,0]],[[1,0],[1,1],[0,1]]] ("Z", "S")

    (... ), anteporre il seguente elenco:

     (2 2)4⍴¨1 rimodellare uno in ciascuno di una matrice 2 × 2 e un elenco di 4 elementi; [[[1,1],[1,1]],[1,1,1,1]]("O", "I")

  1∊¨ per ciascuno, uno è un membro?

  ∨/ riduzione OR orizzontale (ovvero attraverso rotazioni; un valore booleano per ogni forma)

  'OIZSLJT'/⍨ usalo per filtrare la stringa

* Trova restituisce una matrice booleana della stessa forma del suo argomento destro, con quelli che indicano l'angolo in alto a sinistra di tutti i sottoarray identici all'argomento a sinistra.


Funzionerebbe? {4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K⌽2⊖J),(⍳3)⊖¨⊂J←1,⍪K←3↑1)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}
Zacharý,

@ Zacharý Sì, grazie, fatto.
Adám,

7

JavaScript (ES6), 242 212 172 164 byte

x=>[...'OISZLJT'].filter((z,y)=>x.match(`^0*(${'99,33825|15,51|2145,195|561,2115|57,1059|135,71|1073'.split`,`[y].replace(/\d+/g,C=x=>x?x%2+C(x>>1)+x%2:'|')})0*$`))

Doveva essere solo per far rotolare la palla, ma sono un po 'in ritardo per quello ¯ \ _ (ツ) _ / ¯

Prende una stringa di bit, con le righe separate da 0s (che '0001000110001000000'rappresenta 0001 0011 0010 0000) e restituisce una matrice contenente il carattere che rappresenta il tetromino o una matrice che non contiene nulla.

Funziona controllando ogni rotazione di tetromino per vedere se l'ingresso in qualsiasi punto contiene il tetromino, circondato interamente da zero su entrambi i lati. Ogni tetromino è rappresentato da uno o più numeri binari:

0 0 0 0   -> 0000 0110 1100 0000
0 1 1 0   -> 0000001100110000000
1 1 0 0   -> 110011
0 0 0 0   -> 51

0 1 0 0   -> 0100 0110 0010 0000
0 1 1 0   -> 0100001100001000000
0 0 1 0   -> 100001100001
0 0 0 0   -> 2145

Quindi per verificare se l'input contiene un S tetromino, controlliamo semplicemente se contiene la rappresentazione binaria di uno 51o 2145, con solo 0s su entrambi i lati.

Alcuni dei tetromini hanno 4 orientamenti. Se guardi le rappresentazioni binarie di queste, ognuna ha 2 rappresentazioni che sono semplicemente lo specchio delle altre due. Per risparmiare spazio, la rappresentazione binaria viene costruita avanti e indietro simultaneamente con la Cfunzione ricorsiva , permettendoci di inserire solo due degli orientamenti e avere gli altri due impliciti.


Approccio alternativo con charcodes:

x=>[...'OISZLJT'].filter((z,y)=>x.match(`^0*(${[...'÷,êÿ,óî,ûÝ,ëúüÏ,çöïþ,ßýíÞ'.split`,`[y]].map(c=>(C=n=>n?'1e'+(n%4+2)%5-0+C(n>>2):'')(c.charCodeAt())).join`|`})0*$`))

3

Retina , 125 byte

s`(.*1){5}.*

{s`.*1111.*
I
s`.*111(.{2,4})1.*
$.1
T`234`\LTJ
s`.*11(.{2,4})11.*
$.1
T`2-90`S\OZ4-9
s`.*4.*

O#$`.
$.%`
O#$^`

Provalo online! Il collegamento include casi di test più un'intestazione per convertire da numeri interi a una matrice 4 × 4. Spiegazione:

s`(.*1){5}.*

Elimina l'input se contiene 5 1s.

{s`.*1111.*
I

Controllare tutte le rotazioni dell'ingresso (vedi sotto). Se l'input contiene quattro 1s consecutivi , è un I.

s`.*111(.{2,4})1.*
$.1
T`234`\LTJ

Se contiene tre 1s consecutive più una 1sulla riga successiva sotto una delle tre, quindi mappare il numero di caratteri intermedi sulla lettera del risultato appropriata.

s`.*11(.{2,4})11.*
$.1

Allo stesso modo per due adiacenti 1adiacenti a due adiacenti 1sulla riga successiva.

T`2-90`S\OZ4-9

Ma tieni anche conto del numero di rotazioni usando le 0s altrimenti inutilizzate .

s`.*4.*

E rinunciare se sono state eseguite troppe rotazioni.

O#$`.
$.%`
O#$^`

Trasporre e invertire l'array, ruotandolo in tal modo.


3

MATL , 60 byte

Itt6tIl7tl7H15vHe"4:"G@X!HYa]4$v@BIthYaEqY+4=aa]v'OSZLJTI'w)

L'input è un array binario 4 × 4 (matrice), che utilizza ;come separatore di riga. Ouput è una lettera o vuota per nessun tetromino.

Provalo online! Oppure verifica tutti i casi di test (l'output ha un punto aggiunto per consentire di identificare un risultato vuoto).

Spiegazione

Il codice crea 4 rotazioni dell'array di input 4 × 4 con incrementi di 90 gradi. Ogni array ruotato è riempito con 2 zeri su e giù, che lo trasforma in un array 8 × 4. I 4 array sono concatenati verticalmente in un array 32 × 4. Le quattro matrici ruotate all'interno di questa matrice concatenata sono "isolate" grazie allo zero padding.

Ciascuno dei 7 possibili pattern viene testato per vedere se è presente nell'array 32 × 4. A questo scopo viene utilizzato un loop. Ogni modello è definito da due numeri, che espressi in binario danno la maschera 0/1 appropriata. Ad esempio, numeri 3, 6definire la forma "S".

I 7 set di 2 numeri sono disposti in una matrice 2 × 7, da cui il loop selezionerà ogni colonna in sequenza. La matrice viene definita spingendo tutti i numeri nello stack, contatenandoli in un vettore e rimodellandoli in una matrice a 2 righe. Poiché la forma "I" è definita dal numero 15 seguito da 0, mettendolo alla fine consente di riempire implicitamente lo 0 con la funzione di rimodellamento.

La maschera viene quindi riempita con 3 zeri nelle quattro direzioni. Ciò è necessario in modo da rilevare valori indesiderati nell'input.

Per vedere se la maschera è presente nell'array 32 × 4, quest'ultima viene trasformata in forma bipolare (cioè −1/1 invece di 0/1) e contorta con la maschera. Poiché la maschera ne ha 4, la corrispondenza si verifica se una voce nel risultato della convoluzione è uguale a 4.

Alla fine del ciclo, sono stati ottenuti 7 risultati falsi / veri, al massimo uno dei quali è vero. Viene utilizzato per indicizzare in una stringa contenente le possibili lettere di output.


3

Gelatina , 53 byte

ZL0ẋW⁸tZµ⁺ZU$3С“©©“œ“Ç¿“¦©¦“ƽ‘;Uḃ2$’¤iЀṀị“÷¶Ė¡µỵỤ»

Provalo online!

Programma completo. Prende un 4x4. Stampa mse non un tetromino, altrimenti stampa in minuscolo.


È legale prendere una serie di matrici di bit? Ciò mi farebbe risparmiare 40 byte
ETHproductions

@ETHproductions È possibile accettare input come numero intero o direttamente come un array 2D di cifre binarie 4x4 o un array piatto di 16 cifre binarie.
Erik the Outgolfer,

Huh, mi serve proprio per sfogliare la domanda ...
ETHproductions

1

Perl 5 , 197 + 1 (-p) = 198 byte

s/(0000)*$//;1while s/(...)0(...)0(...)0(...)0/0${1}0${2}0${3}0${4}/;$_={51,O,15,I,4369,I,54,S,561,S,99,Z,306,Z,547,L,23,L,785,L,116,L,275,J,113,J,802,J,71,J,114,T,562,T,39,T,609,T}->{oct("0b".$_)}

Provalo online!

Accetta una stringa a 16 bit come input. Non emette nulla se l'input non è un singolo tetromino.

Come?

Le due sostituzioni "spostano" la forma di input nell'angolo in basso a destra. La stringa di bit risultante viene convertita in un numero intero, quindi controllata in un hash di numeri interi validi.


1

APL (Dyalog) , 66 byte

{'TIOJSLZ-'[(¯51 144 64,,∘+⍨12J96 ¯48J64)⍳×/(+/-4×⊢)⍵/,0j1⊥¨⍳4 4]}

Provalo online!

L'arg è un vettore booleano.

Calcola le distanze segnate dei punti verso il loro centro di gravità come numeri complessi (la parte reale e quella immaginaria sono ∆x, ∆y) e moltiplica i numeri complessi insieme. Questo risulta essere un invariante abbastanza buono da distinguere tra i tetromini.


Metodo interessante.
Arnauld,
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.