Riconosci una vite


31

sfondo

Ho un sacco di vecchie e sgranate immagini in bianco e nero. Alcuni raffigurano viti che si arrampicano su un muro, altri no: il tuo compito è classificarli per me.

Ingresso e uscita

Il tuo input è un array 2D rettangolare di bit A , fornito in qualsiasi formato conveniente. Non sarà vuoto, ma non è garantito che contenga sia 0 che 1. L'array raffigura una vite se le seguenti condizioni sono valide:

  • La fila inferiore di A contiene almeno un 1. Queste sono le radici della vite.
  • Ogni 1 in A è collegato alla riga inferiore da un percorso di 1 s che va solo a sinistra, a destra e in basso (non in alto e non in diagonale). Questi percorsi sono i rami della vite.

L'output è un valore di verità coerente se l'input rappresenta una vite e un valore di falsa coerente in caso contrario.

Esempi

Questa matrice raffigura una vite:

0 0 1 0 0 1
0 1 1 0 0 1
0 1 0 1 1 1
1 1 0 1 0 1
0 1 1 1 0 1
0 0 1 0 1 1

Questo input non raffigura una vite, poiché c'è un 1 al centro del bordo destro che non è collegato alle radici da un ramo:

0 0 0 1 1 0
0 1 0 1 1 1
0 1 0 1 0 1
0 1 1 1 1 0
0 0 1 1 0 1

L'array all-0 non raffigura mai una vite, ma l'array all-1 lo fa sempre.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Casi test

Ingressi sinceri:

1

0
1
1

01
11

0000
0111
1100
1001

1111
1111
1111
1111

001001
011001
010111
110101
011101
001011

1011011
1001001
1111111
0100000
0111111
1111001
1001111
1111101

0000000
0011100
0010100
0011100
0001000
1111111
0001000
0011100
0010100
0010100

Ingressi falsi:

0

1
0

10
01

000
000
000

011
110
000

111111
000000
101011
111001

010010
001000
000010
110001

001100
111111
110101
010011
111011

000110
010111
010101
011110
001101

11000000
10110001
10011111
11110001
01100011
00110110
01101100
01100001
01111111

1
Non rendersi conto che non può crescere vite verso il basso, ha avuto una bella idea utilizzando componenti connesse di un grafo, sigh ...
swish

@swish Tutto ciò significa che la rimozione di ogni riga a sua volta deve continuare a generare un grafico collegato a una linea di 1 in fondo.
Neil,

Risposte:


26

Lumache , 25 19 17 byte

&
\0z),(\1dlr)+d~

Provalo online!

Spiegazione

Snails è un linguaggio di abbinamento di motivi 2D ispirato a regex, che è stato originariamente sviluppato per la nostra sfida di progettazione del linguaggio di abbinamento di motivi 2D .

Questo &fa sì che le lumache provino il motivo da ogni possibile posizione di partenza e stampa 0o a 1seconda che il motivo non riesca in uno di essi o corrisponda in tutti.

Ora le lumache possono funzionare con parentesi implicite, quindi il modello è abbreviato per quanto segue:

(\0z),(\1dlr)+d~

Si ,comporta come un *regex (cioè corrisponde a zero o più volte), mentre +è uguale a regex (corrisponde una o più volte). Quindi iniziamo abbinando tutte \0zle volte che è necessario, che corrisponde a un singolo 0e quindi consente alla lumaca di ripristinare arbitrariamente la sua direzione z. Ciò consente zeri nell'input, a condizione che una cella di vite valida possa essere trovata altrove.

Quindi ne abbiniamo almeno uno \1dlr, che corrisponde a un singolo 1e quindi consente alla lumaca di ripristinare la sua direzione verso il basso, a sinistra o a destra. Nota che se la cella in cui abbiamo iniziato contiene un, 1allora corrisponderemo solo a questa parte. In pratica consente alla lumaca di attraversare una vite da un ramo fino alle radici.

Infine, dobbiamo assicurarci di aver raggiunto il suolo cercando una cella fuori limite ( ~) sotto ( d).


1
Sono piacevolmente sorpreso dal fatto che qualcuno sia stato in grado di seguire la documentazione :)
feersum

3

JavaScript (ES6), 135 byte

s=>s.replace(/^[^1]*\n/,``).split`
`.map(s=>+`0b${s}`).reverse(g=(n,m,o=(m<<1|m|m>>1)&n)=>n-m?o-m&&g(n,o):n).reduce((m,n,i)=>g(n,n&m))

Nota: a causa delle limitazioni del tipo intero, funziona solo per viti con una lunghezza massima di 31 caratteri. Spiegazione: Ogni riga è AND bit a bit con la riga adiacente per determinare i punti di connessione, quindi la gfunzione viene utilizzata per espandere ricorsivamente la riga in orizzontale fino a quando non può più espandersi. Ad esempio, se due righe adiacenti sono 1110111e 1011100quindi i punti di connessione sono 1010100e questo viene quindi espanso 1110110e quindi 1110111che rileva che la riga è connessa. Se la gfunzione ha esito negativo, viene restituito zero, il che provoca ganche il fallimento di tutte le funzioni successive e il risultato viene quindi errato. Se la gfunzione ha esito positivo, restituisce la nuova riga che viene quindi propagata attraverso il reducetest della riga successiva.

s=>s.replace(/^[^1]*\n/,``)         Remove irrelevant leading "blank" rows
    .split`\n`                      Split into lines
    .map(s=>+`0b${s}`)              Convert into binary
    .reverse(                       Process from bottom to top
     g=(n,m,o=(m<<1|m|m>>1)&n)=>     Expand row horizontally
      n-m?o-m&&g(n,o):n)             Check whether rows are connected
    .reduce((m,n,i)=>g(n,n&m))      Check all rows

Dirò che 31 caratteri sono abbastanza larghi e questo approccio è valido.
Zgarb,

2

Python 2, 254 byte

Nessuna biblioteca

def f(A,r=0,c=-1):
 B=A[r];R=len(A)-1;C=len(B);i=1 in A[R]
 if c<0:
    for j in range(R*C+C):
        if A[j/C][j%C]:i&=f(A,j/C,j%C)
    return i&1
 _=B[c];B[c]=0;i=_&(r==R)
 if _:
    if c>0:i|=f(A,r,c-1)
    if r<R:i|=f(A,r+1,c)
    if c<C-1:i|=f(A,r,c+1)
 B[c]=_;return i

Si noti che i rientri di secondo e terzo livello sono formati da schede nel conteggio dei byte.

Provalo online


1

Wolfram - 254

Dedica un po 'di tempo a farlo funzionare, quindi lo lascerò qui:

f[s_]:=(
v=Characters@StringSplit@s;
{h,w}=Dimensions@v;
g=GridGraph@{w,h};
r=First/@Position[Flatten@v,"0"];
g=VertexDelete[Graph[VertexList@g,
EdgeList@g/.x_y_/;Abs[x-y]>1yx],r];
v=VertexList@g;
v≠{}∧v~Complement~VertexOutComponent[g,Select[v,#>w h-w&]]{}
)

Fondamentalmente costruisco un grafico a griglia con i bordi diretti rivolti verso l'alto, rimuovo i vertici che corrispondono a 0, controllo che i componenti del vertice inferiore contengano tutti i vertici. Ridicolo, lo so ...


2
Perché questo non è in competizione?
Downgoat,

1
Attualmente considereremmo questa "non una risposta" poiché non è giocata a golf. Se rimuovi semplicemente gli spazi bianchi non necessari e aggiungi un numero di byte, non vedo alcun motivo per cui questo dovrebbe essere non competitivo.
Alex A.

0

Python + NumPy 204 202 195 byte

from numpy import*
def f(A):
 r,c=A.shape
 z,s=zeros((r,1)),array([0,2,c+3])
 B=hstack((z,A,z)).flat
 for i in range(1,(r-1)*(c+2)):
    if B[i]and not any(B[s]):return 1<0
    s+=1
 return any(B[i:])

Si aspetta Ache sia una matrice numpy 2D.

Prende la matrice, posiziona zero colonne a sinistra e a destra e appiattisce la matrice. sè uno stencil che punta all'elemento sinistro, destro e inferiore. Il ciclo controlla ogni elemento tranne l'ultima riga se è 1e almeno uno dei suoi stencil 1, Falsealtrimenti restituisce . Successivamente, controlla se l'ultima riga ne contiene 1.

Due prove per te:

I1 = '001001\n011001\n010111\n110101\n011101\n001011'
A1 = array([int(c) for c in I1.replace('\n','')]).reshape(6,6)
print f(A1) #True

I2 = '001100\n111111\n110101\n010011\n111011'
A2 = array([int(c) for c in I2.replace('\n','')]).reshape(5,6)
print f(A2) #False

Edit1: 1<0 è più corto diFalse

Edit2: flatè una valida alternativa flatten()e l'uso dei tabulatori per la seconda intenzione nel ciclo

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.