Impronta digitale invariante di rotazione


15

Immagina di avere un po 'di poliomino e vorremmo identificarli in modo univoco, tuttavia i polominomi possono essere ruotati, quindi l'hash ciecamente non ci darà la stessa impronta digitale per un pezzo e una sua rotazione (in generale).

Ad esempio se abbiamo il L-tetromino

x
x
xx

vorremmo che avesse la stessa impronta digitale di uno di questi:

         xx
  x       x      xxx
xxx  ,    x  or  x

Nota: consentiamo solo rotazioni sul piano (cioè sono polominomi unilaterali) e quindi il seguente poliomino sarebbe diverso:

 x
 x
xx 

Sfida

Il compito per questa sfida è di attuare un fingerprinting funzione / programma che prende un m×n booleana / 0,1 matrice -valued / lista di liste / string / .. che codifica per una polyomino e restituisce una stringa - l'impronta digitale di un polyomino . L'impronta digitale deve essere uguale per tutte le possibili rotazioni (in generale 4).

Input Output

  • m≥1 e (es. nessun poliomino vuoto)n≥1
  • hai la certezza che sono il più piccoli possibile (cioè tutti gli sono tagliati per adattarsi a em,n0mn
  • sei garantito che l'input è
    • semplicemente connesso
    • non ha buchi
  • l'output deve essere una stringa che è la stessa per ogni possibile rotazione di un poliomino

Esempi

Ecco alcune classi di equivalenza, per ogni classe l'impronta digitale deve essere la stessa e per ogni due poliomi di due classi distinte devono differire.

Le rotazioni del L-tetromino dall'esempio:

[[1,0],[1,0],[1,1]]
[[0,0,1],[1,1,1]]
[[1,1],[0,1],[0,1]]
[[1,1,1],[1,0,0]]

Il J-tetromino:

[[0,1],[0,1],[1,1]]
[[1,1,1],[0,0,1]]
[[1,1],[1,0],[1,0]]
[[1,0,0],[1,1,1]]

L'unità poliomino:

[[1]]

Una barra :5×1

[[1,1,1,1,1]]
[[1],[1],[1],[1],[1]]

Un angolo :2×2

[[1,1],[1,0]]
[[1,0],[1,1]]
[[0,1],[1,1]]
[[1,1],[0,1]]

W-pentamino:

[[1,0,0],[1,1,0],[0,1,1]]
[[0,0,1],[0,1,1],[1,1,0]]
[[1,1,0],[0,1,1],[0,0,1]]
[[0,1,1],[1,1,0],[1,0,0]]


Se eseguo sempre l'output ""(stringa vuota), ho soddisfatto tutti i requisiti?
— Daniel Wagner,

@DanielWagner: "[..] per due polominomi di due classi distinte [le impronte digitali] devono differire " - quindi no, ciò non sarebbe valido.
— ბიმო

L'output di tutte le possibili rotazioni di un array, sistemato in modo coerente, è valido? Esempio
— Shaggy,

1
@Shaggy: Sì, soddisferebbe tutti i criteri.
— ბიმო

Risposte:


7

Python 2 , 48 byte

f=lambda l,z=5:z and max(l,f(zip(*l)[::-1],z-1))

Provalo online!

Prende la più grande delle quattro rotazioni in termini di confronto delle liste. Basato sulla soluzione di FlipTack .

Il codice utilizza la capacità di Python 2 di confrontare oggetti di diversi tipi. Il valore del caso base di 0è innocuo maxperché è più piccolo di qualsiasi elenco. Inoltre, zipproduce un elenco di tuple mentre l'input è un elenco di elenchi, ma le tuple sono più grandi degli elenchi, quindi l'elenco di elenchi di input non è mai un contendente. Questo è il motivo per cui ruotiamo 5 volte anziché 4, in modo da tornare a una versione semplificata dell'elenco iniziale. (Anche prendere un elenco di tuple funzionerebbe, se questa è una forma di input consentita.)


4

Python 3 , 63 byte

def f(m):M=[];exec("m=[*zip(*m[::-1])];M+=m,;"*4);return min(M)

Provalo online!

Trova la rotazione con il minimo lessicale e lo stampa.

Un form lambda arriva allo stesso numero di byte:

lambda m,M=[]:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M[-4:])

Provalo online!


Riscrivere come lambdapuò portarti a 58 lambda m,M=[]:exec("m=[*zip(*m[::-1])];M+=m,;"*4)or min(M).. Funziona perché execritorna sempre None.
— nedla2004,

@ nedla2004 Che può essere eseguito una sola volta, quindi diventa instabile poiché Mè già popolato ...
— FlipTack

@ nedla2004 ... ma tenendo conto del problema con M[-4:]puoi arrivare allo stesso numero di byte.
— FlipTack

Vedo, il test che stavo usando stava solo controllando gli input con lo stesso "hash", quindi non mi sono mai imbattuto in quello. Ha senso.
— nedla2004,

2

Gelatina , 5 byte

ZU$ƬṂ

Provalo online!

Programma completo.

Genera semplicemente tutte le rotazioni possibili e seleziona il minimo lessicografico.

Si noti che gli elenchi singleton non sono inclusi []nell'output. Non importa, dato che l'unico caso in cui esistessero elenchi singleton nell'input sarebbe una linea verticale (inclusa l'unità poliomino), che è la stessa di una linea orizzontale con le stesse dimensioni (dove quelle non sono avvolte ). L'unico caso in cui []non esiste neanche l'esterno è l'unità poliomino.


quando ho letto la sfida sapevo che sarebbe successo :)
— ngn

2

Pulito , 136 byte

import StdEnv,Data.List
r=reverse;t=transpose;f=flatten
$l=[if((a==b)==(c==d))'x''X'\\a<-f l&b<-f(r(map r l))&c<-f(r(t l))&d<-f(t(r l))]

Provalo online!

Include verificatore di test.


2

K (ngn / k) , 16 byte

{a@*<a:3{+|x}\x}

Provalo online!

min di rotazioni

{ } funzione con argomento x

{+|x}ruotare, ovvero reverse ( |) e transpose ( +)

3{ }\applicare 3 volte preservando risultati intermedi; questo restituisce un elenco delle 4 rotazioni

a: assegnato a a

< ascend (calcola la permutazione in ordine crescente)

* primo

a@indice acon quello


1

Japt -g, 6 byte

4Æ=zÃñ

Provalo

           :Implicit input of 2d-array U
4Æ         :Map the range [0,4)
   z       :  Rotate U 90 degrees
  =        :  Reassign to U
    Ã      :End map
     ñ     :Sort
           :Implicit output of first element

La -gbandiera è necessaria? Ordinamento dovrebbe significare che tutte le rotazioni iniziali finiscono con lo stesso elenco in modo che l'elenco completo funzioni perfettamente come l'impronta digitale a meno che non mi manchi qualcosa.
— Kamil Drakari,

@KamilDrakari, potresti aver ragione, come ho detto, non sono sicuro di aver compreso appieno la sfida. Nessun danno lasciandolo dentro, tuttavia, non costa alcun byte.
— Shaggy,

@KamilDrakari: non è necessario, ma non è dannoso, in quanto non viene conteggiato ai fini del conteggio.
— ბიმო

1

J , 16 byte

-2 byte grazie a Shaggy

[:/:~|.@|:^:(<4)

Provalo online!

J , 18 byte

0{[:/:~|.@|:^:(<4)

Provalo online!

Restituisce il primo elemento nell'elenco delle rotazioni ordinate lessicograficamente del poliomino.

Spiegazione:

            ^:(<4)  - do the verb on the left 4 times, storing all the steps
       |.@|:        - tranpose and reverse
    /:~             - sort up the 4 matrices
  [:                - cap the fork
0{                  - take the first matrix  

@Shaggy Grazie!
— Galen Ivanov

0

05AB1E , 10 8 byte

3FÂø})Σ˜

-2 byte grazie a @Shaggy .

Provalo online o verifica tutti i casi di test .

Spiegazione:

3F  }       # Loop 3 times
  Â         #  Bifurcate (short for Duplicate & Reverse) the top of the stack
            #  (which is the input-matrix implicitly the first iteration)
   ø        #  Transpose: swap rows/columns
     )      # After the loop, wrap everything on the stack in a list
      Σ˜    # Sort this list of matrices by their flattened array (and output implicitly)

NOTA: prendendo il minimo con ßo Wsi appiattirà implicitamente, quindi verrà emesso 0. E l'ordinamento con {non sembra funzionare per un elenco di matrici, motivo per cui Σ˜invece lo uso .


1
@Shaggy Grazie! :) In tal caso, gli ultimi due byte possono essere rimossi, poiché }viene fatto implicitamente se non viene seguito da nulla.
— Kevin Cruijssen il

1
Oggi ho imparato qualcosa su 05AB1E! :) È lo stesso in Japt.
— Shaggy,
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.