Bestimmen Sie, ob in einem Bejeweled- / Match-3-Spiel ein Zug vorhanden ist


20

Hintergrund

In Bejeweled- und ähnlichen Spielen muss der Spieler zwei benachbarte Edelsteine ​​(keine Diagonalen) in einem 8x8-Raster von Edelsteinen tauschen, um drei gleiche Farben in einer Reihe zu finden. Die Edelsteine ​​können horizontal oder vertikal angepasst werden. Das Spiel wird fortgesetzt, bis es keinen Zug mehr gibt, der in drei aufeinanderfolgenden Zügen ausgeführt werden kann. Zu diesem Zeitpunkt ist das Spiel beendet.

Aufgabe

Ziel ist es, ein Programm zu schreiben, das feststellt, ob ein Bejeweled-Spiel noch nicht beendet ist. Mit anderen Worten, es muss überprüft werden, ob es einen möglichen Zug gibt, der mindestens drei in einer Reihe macht. Es können mehr als drei Edelsteine ​​hintereinander sein und es ist immer noch ein gültiger Zug.

Eingang

Ihr Programm muss über die Standardeingabe eine 8x8-Darstellung eines Bejeweled-Gitters akzeptieren. Jede der sieben Schmucksteinfarben wird durch eine Ziffer von 1 bis 7 dargestellt. Jede Zeile enthält eine Zeile, und es werden 8 Zeilen mit jeweils 8 Ziffern eingegeben. Siehe die Beispiele. Sie können davon ausgehen, dass die Eingabe immer diesem Format folgt und niemals bereits drei hintereinander enthält.

Ausgabe

Das Programm muss dann (auf Standardausgabe) ausgeben yesoder noabhängig davon, ob mindestens ein gültiger Zug vorhanden ist oder nicht, der drei oder mehr Edelsteine ​​in einer Reihe ergeben würde. Ihr Programm darf nichts anderes als eine einzelne Instanz von entweder yesoder ausgeben no.

Regeln

Ihr Programm darf keine externen Dateien oder Ressourcen oder Befehlszeilenargumente verwenden oder einen bestimmten Dateinamen erfordern. Das Programm mit der geringsten Anzahl von Bytes im Quellcode gewinnt.

Beispiele

Eingang:

12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656

Ausgabe: yes

Eingang:

35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465

Ausgabe: no

Weitere Testfälle finden Sie in der Antwort von MT0 unten .


Sind es nur Zeilen oder auch Spalten?
TheDoctor

@TheDoctor Columns auch. Wenn ich die Phrase "drei in einer Reihe" benutze, meine ich, dass sie in einer horizontalen oder vertikalen Richtung ausgerichtet werden müssen.
bdr9

@ bdr9 Vielleicht möchten Sie das in
John Dvorak

@ JanDvorak Fertig.
bdr9

Vielleicht möchten Sie auch bearbeiten, wenn 4+ in einer Reihe zulässig ist.
Justin

Antworten:


12

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, ffügen Sie f=s=>sie am Anfang des Codes hinzu oder nehmen Sie andernfalls die Eingabe von einer Eingabeaufforderung und ersetzen Sie sie sdurch 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 23fü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 ORdie 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 0088der 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 \ds 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 ).

1
Schöne lösung! Ich hätte nicht gedacht, dass Regex funktionieren könnte. Bitte gib die ?'yes':'no'Anzahl deiner Charaktere an, um Fairness zu gewährleisten, da sie in den Anforderungen enthalten ist und von allen anderen verwendet wird.
bdr9

Vielen Dank für die zusätzlichen Testfälle. Ich habe einen Link zu Ihrer Antwort hinzugefügt, damit andere Personen sie sehen können.
bdr9

Whoa. +1 für Regex
DankMemes

H-mm, kein Modifikator in JS für .Zeichen, einschließlich Zeilenvorschub? In Perl besteht die kombinierte Regexp aus einer Zeichenfolge von nur 129 Byte (was ich, da ich faul bin, mit Regexp :: Assemble kompiliert habe ), sodass das gesamte Perl-Programm ungefähr 150 Byte umfasst.
user2846289

1
@VadimR Danke, aber Sie können noch weiter .{8}|.{9}mit .{8,9}und .{7}|.{8}mit ersetzen.{7,8}
MT0

3

Python 383

Nur eine einzige * Zeile Python!

a=[list(l)for l in raw_input().split('\n')];z=any;e=enumerate;c=lambda b:z(all(p==b[y+v][x+u]for(u,v)in o)for y,r in e(b[:-2])for x,p in e(r[:-2])for o in [[(0,1),(0,2)],[(1,0),(2,0)]]);print z(c([[q if(i,j)==(m,n)else a[m][n]if(i,j)==(y+1,x+1)else p for j,p in e(r)]for i,r in e(a)])for y,t in e(a[1:-1])for x,q in e(t[1:-1])for n,m in((x+u,y+v)for u,v in[(1,0),(1,2),(0,1),(2,1)]))

* Nun, mit Semikolons, aber das ist in Python immer noch nicht trivial (Python-Einzeiler machen Spaß! )


3
Für unverständliches Verständnis upvoted :)
Alexander-Brett

2

Node.js - Naive Lösung - 905 Byte

Nun, noch keine Antworten, also werde ich eine wirklich naive Lösung in Node.js posten

Es durchläuft jede mögliche Bewegung und testet dann das resultierende Brett, um festzustellen, ob es 3 in einer Reihe gibt.

Golfen (mit Google Closure Compiler) (einige hacky Sachen drin wie! 0 und! 1; ich bin mir nicht mal sicher, was es mit meinem XOR-Swap gemacht hat)

Array.prototype.a=function(){for(var f=[],d=0;d<this.length;d++)f[d]=this[d].a?this[d].a():this[d];return f};for(var a=[],b=0;8>b;b++)a[b]=[];for(b=2;b<process.argv.length;b++)for(var c=process.argv[b].split(""),e=0;e<c.length;e++)a[b-2][e]=parseInt(c[e],10);function h(){for(var d=l,f=0;f<d.length-2;f++)for(var g=0;g<d[f].length-2;g++){var k=d[f][g];if(k==d[f+1][g]&&k==d[f+2][g]||k==d[f][g+1]&&k==d[f][g+2])return!0}return!1}function m(){console.log("yes");process.exit()}for(b=0;b<a.length;b++)for(e=0;e<a[b].length;e++){var l=a.a();0!=b&&(l[b-1][e]^=l[b][e],l[b][e]^=l[b-1][e],l[b-1][e]^=l[b][e],h()&&m(),l=a.a());b!=a.length-1&&(l[b+1][e]^=l[b][e],l[b][e]^=l[b+1][e],l[b+1][e]^=l[b][e],h()&&m(),l=a.a());0!=e&&(l[b][e-1]^=l[b][e],l[b][e]^=l[b][e-1],l[b][e-1]^=l[b][e],h()&&m(),l=a.a());e!=a[b].length-1&&(l[b][e+1]^=l[b][e],l[b][e]^=l[b][e+1],l[b][e+1]^=l[b][e],h()&&m(),l=a.a())}console.log("no");

Beachten Sie, dass ich das alles auf meinem Handy geschrieben habe und keine Zeit habe, es zu testen oder so. Kommentar, wenn Sie Fehler sehen, werde ich es später selbst überprüfen.

Die für Menschen lesbare Version vor dem Golf

// set it up
Array.prototype.clone = function() {
    var arr = [];
    for( var i = 0; i < this.length; i++ ) {
        if( this[i].clone ) {
             arr[i] = this[i].clone();
        } else {
             arr[i] = this[i];
        }
    }
};
var board=[];
for(var i=0;i<8;i++)board[i]=[];
for(var i=2;i<process.argv.length;i++){
    var row=process.argv[i].split("");
    for(var j=0;j<row.length;j++)board[i-2][j]=parseInt(row[j], 10);
}
// function to test
function testBoard(arr){
    for(var i=0;i<arr.length-2;i++){
        for(var j=0;j<arr[i].length-2;j++){
            var val=arr[i][j];
            if(val==arr[i+1][j] && val==arr[i+2][j])return true;
            if(val==arr[i][j+1] && val==arr[i][j+2])return true;
        }
    }
    return false;
}
// functions to exit
function yay(){console.log("yes");process.exit();}
function nay(){console.log("no");}
// super slow naive solution time
for(var i=0;i<board.length;i++){
    for(var j=0;j<board[i].length;j++){
        var newboard=board.clone();
        if(i!=0){
            newboard[i-1][j]=newboard[i-1][j]^newboard[i][j];// whoa, it's a
            newboard[i][j]=newboard[i-1][j]^newboard[i][j];  // cool algorithm
            newboard[i-1][j]=newboard[i-1][j]^newboard[i][j];// at least this 
                                                             // isn't all naive
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(i!=board.length-1){
            newboard[i+1][j]=newboard[i+1][j]^newboard[i][j];
            newboard[i][j]=newboard[i+1][j]^newboard[i][j];
            newboard[i+1][j]=newboard[i+1][j]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(j!=0){
            newboard[i][j-1]=newboard[i][j-1]^newboard[i][j];
            newboard[i][j]=newboard[i][j-1]^newboard[i][j];
            newboard[i][j-1]=newboard[i][j-1]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(j!=board[i].length-1){
            newboard[i][j+1]=newboard[i][j+1]^newboard[i][j];
            newboard[i][j]=newboard[i][j+1]^newboard[i][j];
            newboard[i][j+1]=newboard[i][j+1]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
    }
}
nay();

Hah, ich habe den ersten Post tatsächlich um 10 Minuten verpasst. Ich mag das aber irgendwie ...
DankMemes

Ah, genau dieselbe Methode, die ich verwendet habe (naiver, aber kleiner Code!). +1 für viel
aussagekräftiger

Ich frage mich, ob es einen effizienteren Algorithmus gibt ...
DankMemes

2

Perl, 114 96 95 93 92 87 86 85 Bytes

Beinhaltet + für -a0p

Führen Sie mit der Eingabe auf STDIN aus:

bejeweled.pl
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
^D

bejeweled.pl:

#!/usr/bin/perl -a0p
$i/s%.%chop$F[$i++&7]%eg>3|/(.)((.|\H{6}|\H{9})\1|\H{7}\1.)\1/||redo;$_=$1?yes:n.o

Dies kombiniert eine horizontale Regex-Lösung in einer Richtung mit Rotationen

Erläuterung:

In dieser Lösung werde ich wiederholt drehen und die folgenden 4 Tests durchführen:

/(.).\1\1/,      // 3-in-a-row horizontally after left-most shifts right
/(.)\C{9}\1\1/,  // 3-in-a-row horizontally after left-most shifts down
/(.)\C{7}\1.\1/, // 3-in-a-row horizontally after middle shifts down
/(.)\C{6}\1\1/,  // 3-in-a-row horizontally after right-most shifts down

Wo \Cist "ein beliebiges Zeichen" (anders als .Newline). Abgesehen davon, dass dies \Cveraltet ist und zu Warnungen führt, verwende ich\H stattdessen (nicht horizontales Leerzeichen), was gut genug ist, um alle Ziffern und Zeilenumbrüche zu erfassen.

Nach 4 Umdrehungen hat dies alle 16 erforderlichen Tests durchgeführt

-p                            Read lines from STDIN, print $_ at the end
-0                            No line ending => slurp ALL of STDIN
-a                            Split $_ into @F. Since there are no spaces
                              on the rows this means each element of @F is
                              1 row

    s%.%chop$F[$i++&7]%eg     Replace each row by the removed last column
                              This is therefore a left rotation. Very short
                              but at the cost of using @F. To make sure that
                              @F gets refilled from $_ each time I won't be
                              able to use while, until, eval or do$0 for the
                              loops but have to use redo. That costs a few
                              bytes but less than having to do my own split
$i/                      >3   The previous regex replacement always
                              returns 64 and each time through the loop $i is
                              increased by 64. So if this division reaches
                              4 all rotations have been done

/(.)((.|\H{6}|\H{9})\1|\H{7}\1.)\1/ This is the 4 regexes mentioned above
  ||redo                      Stop the loop if the regex matches or we
                              rotated 4 times
$_=$1?yes:n.o                If the regex matched $1 will be one of the
                              color digits (which cannot be 0) and this will
                              assign "yes" to $_. If the regex didn't match
                              in 4 times $1 will get its value from the last
                              succesful regex in scope which will be the one
                              from the rotation, but that one doesn't have
                              any () so $1 will be unset. So in case there
                              is no move $_ will be set to "no" (which needs
                              to be constructed because "no" is a keyword)

1

Python3, 314B

import itertools as T,copy
r=[]
K=range(8)
J=[list(input())for w in K]
P=T.product
f=lambda A:["yes"for b in[A[m][n:]for m,n in P(K,K[:6])]if b[0]==b[1]==b[2]]
for i,j,x in P(K,K,[0,1]):
 t=j+1-x
 if i+x<8and t<8:B=copy.deepcopy(J);B[i][j],B[i+x][t]=B[i+x][t],B[i][j];r+=f(B)+f(list(zip(*B)))
r+=["no"]
print(r[0])

Ändern Sie die 8, die 5 in Zeile 6 und die 8 in Zeile 9, um beliebig große Eingabegrößen zu verarbeiten. ist es auch egal, was jeder Wert ist, also können Sie ihn füttern:

absdefgh
sdkljahs
lsdfjasd
fjdhsdas
dkjhfasd
sdfhaskd
sdkfhkas
weriuwqe

und es wird zurückkehren yes.

Anmerkungen

import itertools as T,copy 
            # itertools.product is going to save us lots of for loops
r=[]        # result
K=range(8)  # we can use range(8) everywhere, so this saves more than the usual R=range
J=[list(input())for w in K] 
            # input handling: keep everything as a length-1 string to avoid map(int,input())
P=T.product
f=lambda A:["yes"for b in[A[m][n:]for m,n in P(K,K[:6])]if b[0]==b[1]==b[2]] 
            # check the condition horiontally only. K[:6] is the same as range(5)
            # A[m][n:n+3] would be neater, but not actually needed
for i,j,x in P(K,K,[0,1]): 
            # <3 itertools.product! 3 for-loops without it.
            # NB we're only going right and downwards
 t=j+1-x
 if i+x<8and t<8: 
            # don't want out-of-bounds errors at the edges
  B=copy.deepcopy(J) 
            # preserve the reference array
  B[i][j],B[i+x][t]=B[i+x][t],B[i][j] 
            # do the switch
  r+=f(B)+f(list(zip(*B))) 
            # do the test. you could end up with lots of 'yes's in r.
            # zip(*B) takes the transpose, so that f checks the columns too
r+=["no"]   # happens to ensure that r is nonempty
print(r[0]) # only prints no if r was empty before the last line

1

GNU sed 255 + 2 = 257B

Ich dachte, dass dies nicht so gut wie Python sein würde, aber es ist jetzt: - / Ich war heute ohne Internetzugang, also habe ich mich damit beschäftigt, dies in sed zu lösen :). Muss mit dem -r-Flag aufgerufen werden, dh sed -rf command.sed < inputich habe 2 zu meiner Punktzahl hinzugefügt.

:a
$!N
s/\n/ /g
ta
:b
/^((\w)(\w\2\2|\2\w\2|\w\2\w* \w\2|\2\w* \w\w\2|\w* (\2\w* \w* \2|\w* \2\w* \2|\w\2\2|\w\2\w* \2|\2\w* \w\2|\w\2\w* \w\2))|\w((\w)(\w* \6\w\6|\6\w* \6|\w* (\6\w \w\6|\w\6\w* \6|\6\w* \6))|\w(\w)\w* \9\9))/c\yes
s/\w(\w*)/\1/g
tb
c\no

Wie es funktioniert:

  1. Lesen Sie das Raster in eine einzelne Zeile mit durch Leerzeichen getrennten Zeichen
  2. Verwenden Sie den Motherload-Regex, um herauszufinden, ob in der ersten Spalte * eine Übereinstimmung vorliegt. Wenn ja, tauschen Sie die gesamte Zeile gegen "ja" aus (Beenden des Programms).
  3. Entferne das erste Zeichen aus jeder Spalte und gehe zu 2, wenn wir das getan haben
  4. Wenn wir es nicht getan haben (die Zeile ist leer), ersetzen Sie die gesamte Zeile mit 'nein'

1

Ruby, 201 Bytes

Ich war enttäuscht, keine Lösungen für diese großartige Herausforderung zu sehen, die weder Regex noch rohe Gewalt anwenden (obwohl diese großartig sind), also schrieb ich eine. Es werden Eingaben über STDIN vorgenommen.

Der bitweise arithmetische Kernalgorithmus leitet sich aus dieser fantastischen Antwort von @leander auf Game Development Stack Exchange ab.

s=$<.read
$><<(?1..?9).any?{|n|a=[0]*19
s.scan(n){i=$`.size
a[i/9+1]+=2**(i%9)
a[i%9+10]+=2**(i/9)}
a.each_cons(3).any?{|x,y,z|q=y&y<<1
l=q<<1
q>>=2
y&(l<<1|q>>1)|(q|l|(y&y<<2)>>1)&(x|z)>0}}?"yes":"no"

Ruby Lambda, 181 Bytes

Hier ist es als Lambda, das eine Zeichenfolge nimmt und zurückgibt trueoder false:

->s{(?1..?9).any?{|n|a=[0]*19
s.scan(n){i=$`.size
a[i/9+1]+=2**(i%9)
a[i%9+10]+=2**(i/9)}
a.each_cons(3).any?{|x,y,z|q=y&y<<1
l=q<<1
q>>=2
y&(l<<1|q>>1)|(q|l|(y&y<<2)>>1)&(x|z)>0}}}

Siehe es auf repl.it: https://repl.it/ColJ/2

Ungolfed & Erklärung

->s{
  (?1..?9).any? {|n|
    a = [0] * 19

    s.scan(n) {
      i = $`.size
      a[i/9+1] += 2**(i%9)
      a[i%9+10] += 2**(i/9)
    }

    a.each_cons(3).any? {|x,y,z|
      q = y & y << 1
      l = q << 1
      q >>= 2
      y & (l << 1 | q >> 1) |
        (q | l | (y & y << 2) >> 1) &
        (x | z) > 0
    }
  }
}

Der Code durchläuft die Ziffern "1" bis "9". Jede Iteration hat zwei diskrete Schritte:

Der erste Schritt ist die Board-Transformation, die Sie im s.scan(n)Block im ungolfed Code sehen können. Es wandelt die Karte in ein Array von 8 Ganzzahlen um, eine für jede Zeile, indem übereinstimmende Ziffern als 1 und alle anderen als 0 in einer binären Zeichenfolge behandelt werden. Nehmen Sie zum Beispiel die Reihe 12231123. In der ersten Iteration wird dies die Binärzeichenfolge 10001100(alle Einsen werden zu - äh, bleiben - Einsen und alle anderen Ziffern werden zu Nullen). Dies ist die Dezimalzahl 140. In der zweiten Iteration wird dieselbe Zeile 01100010(alle Zweisen werden zu Zweisen und Alle anderen Ziffern werden zu Nullen oder zu Dezimalzahlen von 98.

Gleichzeitig wird eine zweite Transformation ausgeführt, die mit der ersten identisch ist, wobei jedoch die Platine um 90 Grad gedreht wird. Auf diese Weise können wir die gleiche Logik für horizontale und vertikale Übereinstimmungen verwenden. Der Einfachheit halber werden die beiden Karten zu einer einzigen langen Karte mit einer Null am Anfang, in der Mitte (um die beiden Karten zu trennen) und dem Ende zum Auffüllen zusammengefügt.

Der zweite Schritt ist die Suche nach möglichen Übereinstimmungen, die Sie im each_cons(3).any?Block sehen können. Die transformierten Zeilen (die jetzt 8-Bit-Ganzzahlen sind) werden in (überlappenden) Gruppen von drei Zeilen ( x , y , z ) unter Verwendung von bitweiser Arithmetik überprüft . Jede Gruppe wird überprüft, um festzustellen, ob eine Übereinstimmung in Reihe y hergestellt werden kann , entweder durch Verschieben eines Stücks in Reihe y oder durch Verschieben eines Stücks in y von x oder z . Da vor und nach der ursprünglichen und der gedrehten Brettreihe eine Null "Reihe" vorhanden ist, müssen wir nicht prüfen, ob wir in der ersten oder letzten Reihe eines Brettes sind.

Wenn keine Übereinstimmungen gefunden wurden, wird mit der nächsten Iteration fortgefahren.

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.