Ursprüngliche Lösung: JavaScript - 261 255 228 227 179 153 Zeichen
/(\d)(\1(\d|.{6}|.{9})|(\d|.{6}|.{9})\1|.{7}\1(.|.{9})|(.|.{9})\1.{7}|(.{7,9}|.{17})\1.{8}|.{8}\1(.{7,9}|.{17}))\1/.test(s.replace(/\n/g,'A'))?'yes':'no'
Angenommen, die zu testende Zeichenfolge befindet sich in der Variablen s
(um sie zu einer Funktion zu machen, f
fügen Sie f=s=>
sie am Anfang des Codes hinzu oder nehmen Sie andernfalls die Eingabe von einer Eingabeaufforderung und ersetzen Sie sie s
durch prompt()
).
Ausgänge ist an die Konsole.
3 rd Lösung: JavaScript (ECMAScript 6) - 178 Zeichen
p=x=>parseInt(x,36);for(t="2313ab1b8a2a78188h9haj9j8iaiir9r",i=v=0;s[i];i++)for(j=0;t[j];v|=s[i]==s[i+a]&s[i]==s[i+b]&i%9<8&(b>3|(i+b-a)%9<8))a=p(t[j++]),b=p(t[j++]);v?'yes':'no'
Ich habe die zweite Lösung (die reguläre Ausdrücke verwendet, um in bestimmten Konfigurationen nach Zeichen zu suchen) verwendet und sie überarbeitet, um nur die Zeichenfolge auf identische Zeichen in denselben Konfigurationen zu überprüfen, ohne reguläre Ausdrücke zu verwenden.
Die Base-36-Zeichenfolge "2313ab1b8a2a78188h9haj9j8iaiir9r"
gibt zu überprüfende Versatzpaare an, dh das Paar 23
führt zu der Prüfung, ob i te Zeichen mit dem (i + 2) -ten Zeichen und dem (i + 3) -ten Zeichen (das Äquivalent des regulären Ausdrucks ) identisch ist (.).\1\1
- mit einigen zusätzlichen Überprüfungen, um sicherzustellen, dass das nicht identische Zeichen kein Zeilenvorschub ist).
2 nd Lösung: JavaScript (ECMAScript 6) - 204 Zeichen
p=x=>parseInt(x,18);g=a=>a?a>1?"(.|\\n){"+a+"}":".":"";f=(x,a,b)=>RegExp("(.)"+g(a)+"\\1"+g(b)+"\\1").test(x);for(t="10907160789879h8",i=v=0;t[i];v|=f(s,x,y)||f(s,y,x))x=p(t[i++]),y=p(t[i++]);v?'yes':'no'
Erstellt mehrere reguläre Ausdrücke (siehe unten für weitere Details) unter Verwendung von Wertepaaren aus der Base-18-Zeichenfolge 10907160789879h8
und führt OR
die Tests durch. Um es weiter zu reduzieren, können Sie feststellen, dass die regulären Ausdrücke paarweise vorkommen, wobei einer der "umgekehrten" Ausdrücke des anderen ist. wenn Sie diese Tests wieder in den Anhang 0088
der Base-18-Zeichenfolge einfügen möchten ).
Erläuterung
Beginnen Sie mit 16 regulären Ausdrücken, die alle möglichen Konfigurationen gültiger Züge abdecken:
REs=[
/(\d)\1\1/, // 3-in-a-row horizontally
/(\d).\1\1/, // 3-in-a-row horizontally after left-most shifts right
/(\d)\1.\1/, // 3-in-a-row horizontally after right-most shifts left
/(\d)(?:.|\n){9}\1\1/, // 3-in-a-row horizontally after left-most shifts down
/(\d)(?:.|\n){7}\1.\1/, // 3-in-a-row horizontally after middle shifts down
/(\d)(?:.|\n){6}\1\1/, // 3-in-a-row horizontally after right-most shifts down
/(\d)\1(?:.|\n){6}\1/, // 3-in-a-row horizontally after left-most shifts up
/(\d).\1(?:.|\n){7}\1/, // 3-in-a-row horizontally after middle shifts up
/(\d)\1(?:.|\n){9}\1/, // 3-in-a-row horizontally after right-most shifts up
/(\d)(?:.|\n){7,9}\1(?:.|\n){8}\1/, // 3-in-a-row vertically (with optional top shifting left or right)
/(\d)(?:.|\n){7}\1(?:.|\n){9}\1/, // 3-in-a-row vertically after middle shifts right
/(\d)(?:.|\n){9}\1(?:.|\n){7}\1/, // 3-in-a-row vertically after middle shifts left
/(\d)(?:.|\n){8}\1(?:.|\n){7}\1/, // 3-in-a-row vertically after bottom shifts right
/(\d)(?:.|\n){8}\1(?:.|\n){9}\1/, // 3-in-a-row vertically after bottom shifts left
/(\d)(?:.|\n){17}\1(?:.|\n){8}\1/, // 3-in-a-row vertically after top shifts down
/(\d)(?:.|\n){8}\1(?:.|\n){17}\1/, // 3-in-a-row vertically after bottom shifts up
];
( Anmerkung: der regexs für 3-in-einer-Reihe horizontal (0 - ten ) und vertikal (Teil der 9 th ) ist irrelevant , da die Zustände OP dass diese zusammenpassenden Eingänge nie vorhanden sein. )
Wenn Sie jeden dieser Parameter anhand der Eingabe testen, wird festgestellt, ob ein gültiger Zug dieser Konfiguration gefunden werden kann.
Die regulären Ausdrücke können jedoch zu folgenden 6 kombiniert werden:
/(\d)(?:.|(?:.|\n){9}|(?:.|\n){6})?\1\1/ // Tests 0,1,3,5
/(\d)\1(?:.|(?:.|\n){9}|(?:.|\n){6})?\1/ // Tests 0,2,6,8
/(\d)(?:.|\n){7}\1(?:.|(?:.|\n){9})\1/ // Tests 4,10
/(\d)(?:.|(?:.|\n){9})\1(?:.|\n){7}\1/ // Tests 7,11
/(\d)(?:(?:.|\n){7,9}|(?:.|\n){17})\1(?:.|\n){8}\1/ // Tests 9,14
/(\d)(?:.|\n){8}\1(?:(?:.|\n){7,9}|(?:.|\n){17})\1/ // Tests 9a,12,13,15
Diese können dann zu einem einzigen regulären Ausdruck kombiniert werden:
/(\d)(?:.|(?:.|\n){9}|(?:.|\n){6})?\1\1|(\d)\2(?:.|(?:.|\n){9}|(?:.|\n){6})?\2|(\d)(?:.|\n){7}\3(?:.|(?:.|\n){9})\3|(\d)(?:.|(?:.|\n){9})\4(?:.|\n){7}\4|(\d)(?:(?:.|\n){7,9}|(?:.|\n){17})\5(?:.|\n){8}\5|(\d)(?:.|\n){8}\6(?:(?:.|\n){7,9}|(?:.|\n){17})\6/
Welche muss nur gegen den Eingang getestet werden.
Testfälle
Einige Testfälle, die für andere nützlich sein könnten (entspricht nicht dem Eingabeformat, nur die Ziffern 1-7 zu verwenden, ist aber leicht zu korrigieren und nur ein 8x4-Raster), da dies das Minimum ist, das für einen Test aller gültigen Eingaben erforderlich ist ).
Im Format einer Zuordnung von Eingabezeichenfolge zu dem der 16 regulären Ausdrücke darüber entspricht.
Tests={
"12345678\n34567812\n56781234\n78123456": -1, // No Match
"12345678\n34969912\n56781234\n78123456": 1, // 3-in-a-row horizontally after left-most shifts right
"12345678\n34567812\n59989234\n78123456": 2, // 3-in-a-row horizontally after right-most shifts left
"12345978\n34567899\n56781234\n78123456": 3, // 3-in-a-row horizontally after left-most shifts down
"12345978\n34569892\n56781234\n78123456": 4, // 3-in-a-row horizontally after middle shifts down
"12345678\n34967812\n99781234\n78123456": 5, // 3-in-a-row horizontally after right-most shifts down
"12399678\n34967812\n56781234\n78123456": 6, // 3-in-a-row horizontally after left-most shifts up
"12345678\n34597912\n56789234\n78123456": 7, // 3-in-a-row horizontally after middle shifts up
"12345998\n34567819\n56781234\n78123456": 8, // 3-in-a-row horizontally after right-most shifts up
"12945678\n34597812\n56791234\n78123456": 9, // 3-in-a-row vertically after top shifts right
"12349678\n34597812\n56791234\n78123456": 9, // 3-in-a-row vertically after top shifts left
"12345978\n34569812\n56781934\n78123456": 10, // 3-in-a-row vertically after middle shifts right
"92345678\n39567812\n96781234\n78123456": 11, // 3-in-a-row vertically after middle shifts left
"12945678\n34967812\n59781234\n78123456": 12, // 3-in-a-row vertically after bottom shifts right
"12349678\n34569812\n56781934\n78123456": 13, // 3-in-a-row vertically after bottom shifts left
"12395678\n34567812\n56791234\n78193456": 14, // 3-in-a-row vertically after top shifts down
"12345698\n34567892\n56781234\n78123496": 15, // 3-in-a-row vertically after bottom shifts up
"12345678\n34567899\n96781234\n78123456": -1, // No match - Matches (.)\1.\1 but not 3 in a row
"12345679\n99567812\n56781234\n78123456": -1, // No match - Matches (.).\1\1 but not 3 in a row
};
Bearbeiten 1
Ersetzen Sie \d
s durch .
- Speichert 6 Zeichen.
Bearbeiten 2
Ersetzen Sie (?:.|\n)
mit [\s\S]
und entfernt zusätzliche nicht-einfangenden Gruppen und aktualisiert Rückverweise (wie vorgeschlagen m-Buettner ) und in Ja / Nein - Ausgang hinzugefügt.
Bearbeiten 3
- Die ECMAScript 6-Lösung wurde hinzugefügt, um die einzelnen regulären Ausdrücke aus einer Base-18-Zeichenfolge zu erstellen.
- Die Tests für 3-in-eine-Reihe wurden horizontal entfernt (wie von m-buettner vorgeschlagen ).
Bearbeiten 4
Eine weitere (kürzere) Lösung und zwei weitere nicht übereinstimmende Testfälle wurden hinzugefügt.
Bearbeiten 5
- Verkürzte ursprüngliche Lösung durch Ersetzen von Zeilenumbrüchen durch ein nicht numerisches Zeichen (wie von VadimR vorgeschlagen ).
Bearbeiten 6
- Verkürzte ursprüngliche Lösung durch Kombinieren von Bits des regulären Ausdrucks (wie von VadimR vorgeschlagen ).