Erkennen Sie eine Rebe


31

Hintergrund

Ich habe ein paar alte und körnige Schwarzweißbilder. Einige von ihnen stellen Weinreben dar, die an einer Wand klettern, andere nicht - Ihre Aufgabe ist es, sie für mich zu klassifizieren.

Ein- und Ausgabe

Ihre Eingabe ist ein rechteckiges 2D-Array von Bits A , das in einem beliebigen geeigneten Format angegeben wird. Es wird nicht leer sein, aber es kann nicht garantiert werden, dass es sowohl Nullen als auch Einsen enthält. Das Array zeigt eine Rebe, wenn die folgenden Bedingungen erfüllt sind:

  • Die unterste Reihe von A enthält mindestens eine 1. Dies sind die Wurzeln der Rebe.
  • Jede 1 in A ist mit der unteren Reihe durch einen Pfad von 1s verbunden, der nur nach links, rechts und unten verläuft (nicht nach oben und nicht diagonal). Diese Wege sind die Zweige der Rebe.

Ihre Ausgabe ist ein konsistenter Wahrheitswert, wenn die Eingabe eine Rebe darstellt, und ansonsten ein konsistenter falscher Wert.

Beispiele

Dieses Array zeigt eine Rebe:

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

Diese Eingabe stellt keine Rebe dar, da sich in der Mitte des rechten Randes eine 1 befindet, die nicht durch einen Zweig mit den Wurzeln verbunden ist:

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

Das Array all-0 stellt niemals eine Rebe dar, das Array all-1 jedoch immer.

Regeln und Wertung

Sie können ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig.

Testfälle

Wahrheitseingaben:

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

Falsche Eingaben:

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
Wusste nicht, dass Wein nicht nach unten wachsen kann, hatte eine gute Idee, verbundene Komponenten eines Graphen zu verwenden, seufz ...
Swish

@swish Das bedeutet nur, dass das Entfernen jeder Zeile der Reihe nach weiterhin zu einem Diagramm führen muss, das mit einer Linie von 1 am unteren Rand verbunden ist.
Neil

Antworten:


26

Schnecken , 25 19 17 Bytes

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

Probieren Sie es online!

Erläuterung

Snails ist eine von Regex inspirierte 2D-Pattern-Matching-Sprache, die ursprünglich für unsere 2D-Pattern-Matching-Sprachdesign-Herausforderung entwickelt wurde .

Die &Hersteller versuchen das Muster von jeder möglichen Startposition aus und drucken es, 0oder 1je nachdem, ob das Muster in einem von ihnen fehlschlägt oder in allen übereinstimmt.

Jetzt können Schnecken mit impliziten Klammern arbeiten, daher ist das Muster eine Abkürzung für Folgendes:

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

Das ,verhält sich wie ein *in Regex (dh null oder mehrmals übereinstimmen), wohingegen +das gleiche wie in Regex (ein oder mehrmals übereinstimmen) ist. Also fangen wir damit an, \0zso oft wie nötig abzugleichen, was einem einzelnen entspricht 0und erlauben es dann der Schnecke, ihre Richtung willkürlich mit zurückzusetzen z. Dies erlaubt Nullen in der Eingabe, vorausgesetzt, eine gültige Weinstockzelle kann an einer anderen Stelle gefunden werden.

Dann stimmen wir mit mindestens einem überein \1dlr, der mit einem einzelnen übereinstimmt, 1und lassen dann die Schnecke ihre Richtung entweder nach unten, links oder rechts zurücksetzen. Beachten Sie, dass 1wir nur diesen Teil abgleichen , wenn die Zelle, bei der wir begonnen haben, ein enthält . Grundsätzlich kann die Schnecke einen Weinstock von einem Ast bis zu den Wurzeln durchqueren.

Schließlich müssen wir sicherstellen, dass wir den Boden erreicht haben, indem wir nach einer Zelle außerhalb der Grenzen ( ~) unten ( d) suchen .


1
Ich bin angenehm überrascht, dass irgendjemand der Dokumentation folgen konnte :)
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))

Hinweis: Aufgrund der Einschränkungen des Integer-Typs können nur Reben mit einer Breite von bis zu 31 Zeichen verwendet werden. Erläuterung: Jede Zeile wird mit der benachbarten Zeile bitweise UND-verknüpft, um die Verbindungspunkte zu bestimmen. Anschließend wird die Zeile mit der gFunktion rekursiv horizontal erweitert, bis sie nicht mehr erweitert werden kann. Wenn beispielsweise zwei benachbarte Reihen sind , 1110111und 1011100dann werden die Verbindungspunkte sind , 1010100und dies wird dann ausgebaut 1110110und dann 1110111das feststellt , dann , dass die Reihe verbunden ist. Wenn die gFunktion fehlschlägt, wird Null zurückgegeben, wodurch auch alle nachfolgenden gFunktionen fehlschlagen. Das Ergebnis ist dann falsch. Wenn die gFunktion erfolgreich ist, gibt sie die neue Zeile zurück, die dann durch die weitergegeben wird reduce, um die nächste Zeile zu testen.

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

Ich werde davon ausgehen, dass 31 Zeichen breit genug sind, und dieser Ansatz ist gültig.
Zgarb

2

Python 2, 254 Bytes

Keine Bibliotheken

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

Beachten Sie, dass die Einrückungen der zweiten und dritten Ebene mit Tabulatoren in der Byteanzahl gebildet werden.

Probieren Sie es online aus


1

Wolfram - 254

Verbringen Sie etwas Zeit damit, diese Arbeit zu erledigen, also lasse ich sie einfach hier:

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&]]{}
)

Grundsätzlich konstruiere ich ein Gitterdiagramm mit nach oben gerichteten Kanten, entferne Scheitelpunkte, die 0s entsprechen, und überprüfe, ob die unteren Scheitelpunktkomponenten alle Scheitelpunkte enthalten. Lächerlich, ich weiß ...


2
Warum ist das nicht konkurrierend?
Downgoat

1
Gegenwärtig würden wir dies als "keine Antwort" betrachten, da es nicht golfen wird. Wenn Sie einfach unnötige Leerzeichen entfernen und eine Byteanzahl hinzufügen, sehe ich keinen Grund, warum dies nicht konkurrierend sein sollte.
Alex A.

0

Python + NumPy 204 202 195 Bytes

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:])

Erwartet Aein 2D Numpy Array.

Nimmt die Matrix auf, füllt null Spalten links und rechts auf und glättet die Matrix. sist eine Schablone, die auf das linke, rechte und untere Element zeigt. Die Schleife prüft jedes Element mit Ausnahme der letzten Zeile, ob es sich 1um ein Element handelt 1, und gibt Falseansonsten mindestens eine seiner Schablonen zurück . Überprüfen Sie anschließend, ob die letzte Zeile eine enthält 1.

Zwei Testfälle für Sie:

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<0ist kürzer alsFalse

Edit2: flatist eine gute Alternative flatten()und Verwendung von Tabulatoren für die zweite Absicht in der Schleife

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.