Bejeweled / match 3 게임에 움직임이 있는지 확인 7 개의 보석 색상은 각각 1에서 7까지의

배경

Bejeweled 및 유사한 게임에서 플레이어는 8×8 보석 그리드에서 인접한 보석 2 개 (대각선 없음)를 서로 바꿔서 같은 색상의 3 개를 연속으로 일치시켜야합니다. 보석은 수평 또는 수직으로 일치시킬 수 있습니다. 3 번 연속으로 움직일 수있는 움직임이 없을 때까지 게임 플레이는 계속됩니다.

태스크

목표는 Bejeweled 게임이 아직 끝나지 않았는지 여부를 결정하는 프로그램을 작성하는 것입니다. 다시 말해서, 연속으로 3 번 이상 움직일 수 있는지 확인해야합니다. 연속으로 3 개 이상의 보석이있을 수 있으며 여전히 유효합니다.

입력

프로그램은 표준 입력을 통해 Bejeweled 그리드의 8×8 표현을 수용해야합니다. 7 개의 보석 색상은 각각 1에서 7까지의 숫자로 표시됩니다. 각 줄에는 하나의 행이 포함되며 각각 8 자리로 구성된 8 개의 줄이 입력됩니다. 예제를 참조하십시오. 입력이 항상이 형식을 따르고 행에 세 개를 포함하지 않을 것이라고 가정 할 수 있습니다.

산출

그런 다음 프로그램은 (표준 출력으로) 출력 yes하거나 no하나 이상의 유효한 이동이 존재하는지 여부에 따라 연속으로 3 개 이상의 보석을 생성해야합니다. 프로그램은 yes또는 의 단일 인스턴스 이외의 것을 출력해서는 안됩니다 no.

규칙

프로그램은 외부 파일이나 리소스, 명령 줄 인수를 사용하거나 특정 파일 이름을 요구해서는 안됩니다. 소스 코드에서 바이트 수가 가장 적은 프로그램이 승리합니다.

입력:

12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656

산출: yes

입력:

35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465

산출: no

추가 테스트 사례는 아래 MT0의 답변을 참조하십시오 .



답변

원래 솔루션 : 자바 스크립트 – 261 255 228 227 개 179 153 문자

/(\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'

테스트에 문자열이 변수에 있다고 가정하면 s(이 함수 만들려면 f다음 추가 f=s=>한 후 대체 프롬프트에서 입력을 위해, 그렇지 않으면 코드 나의 시작 s과 함께 prompt()).

출력은 콘솔입니다.

3 솔루션 : JavaScript (ECMAScript 6)-178 자

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'

아래 의 두 번째 솔루션 (일부 구성에서 문자를 확인하기 위해 정규 표현식을 사용함)을 사용하여 정규 표현식을 사용하지 않고 동일한 구성에서 동일한 문자의 문자열을 확인하도록 다시 작업했습니다.

Base-36 문자열 "2313ab1b8a2a78188h9haj9j8iaiir9r"은 점검 할 오프셋 쌍을 제공합니다. 즉, 23i 번째 문자가 (i + 2) 번째 문자 및 (i + 3) 번째 문자 (정규 표현식과 동일 함 )와 동일한 경우 쌍으로 검사합니다. (.).\1\1-동일하지 않은 문자가 개행 문자가 아닌지 확인하기위한 몇 가지 추가 검사와 함께).

2 솔루션 : JavaScript (ECMAScript 6)-204 자

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'

Base-18 문자열에서 가져온 값 쌍을 사용하여 여러 정규식 (자세한 내용은 아래 참조)을 작성 10907160789879h8하고 OR모든 테스트를 수행합니다. 더 줄이기 위해 정규 표현식은 한 쌍이 다른 사람의 “반전”인 쌍으로 나옵니다 (행에서 3 행의 정규 표현식은 OP 상태로 가로 및 세로로 무시 함). 0088Base-18 문자열에 추가 하여 해당 테스트를 다시 추가하려는 경우 ).

설명

유효한 이동의 모든 가능한 구성을 다루는 16 개의 정규식으로 시작하십시오.

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
];

( 주 : 3에서 A-가로 행 (0 정규식 등에서 특정 요소를 뽑아 오기위한 ) 및 수직 (9)의 (일부 토륨 )이 일치하는 입력이 존재하지 않을 것이라는 OP 상태로서 부적합하다. )

입력에 대해 각각을 테스트하면 해당 구성의 유효한 이동을 찾을 수 있는지 여부가 결정됩니다.

그러나 정규식을 결합하여 다음 6 가지를 얻을 수 있습니다.

/(\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

그런 다음 단일 정규식으로 결합 할 수 있습니다.

/(\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/

입력에 대해 테스트해야합니다.

테스트 사례

다른 사람들이 유용하다고 생각할 수있는 일부 테스트 사례 (숫자 1-7 만 사용하는 입력 형식을 준수하지는 않지만 쉽게 수정되고 8×4 그리드 임)-모든 유효한 입력을 테스트하는 데 필요한 최소값이므로 ).

입력 문자열에서 위의 16 개의 정규식 중 하나와 일치하는 맵 형식입니다.

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
};

편집 1

\ds로 교체 .-6자를 저장합니다.

편집 2

교체 (?:.|\n)[\s\S](의해 제안 제거 추가적인 비 – 포착 기 및 업데이트 다시 참조 및 m-BUETTNER ) 및 예 / 아니오 출력했다.

편집 3

  • Base-18 문자열에서 개별 정규식을 작성하는 ECMAScript 6 솔루션을 추가했습니다.
  • m-buettner가 제안한대로 가로 3 줄에 대한 테스트를 제거했습니다 .

편집 4

다른 (더 짧은) 솔루션과 두 가지 더 일치하지 않는 테스트 사례가 추가되었습니다.

편집 5

  • 줄 바꿈을 숫자가 아닌 문자로 대체하여 원래 솔루션을 단축했습니다 ( VadimR에서 제안한 대로 ).

편집 6

  • VadimR에서 제안한 정규식 비트를 결합하여 원래 솔루션을 단축했습니다 .

답변

파이썬 383

단 한 줄의 파이썬!

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

* 음, 세미콜론이 있지만 파이썬에서는 여전히 사소하지 않습니다 (파이썬 원 라이너는 재미 있습니다! )


답변

Node.js-Naive 솔루션-905 바이트

글쎄, 아직 답변이 없으므로 Node.js에 정말 순진한 솔루션을 게시 할 것입니다.

가능한 모든 움직임을 거친 다음 결과 보드를 테스트하여 3 행이 있는지 확인합니다.

골프 (Google 클로저 컴파일러 사용) (! 0 및! 1과 같은 일부 해킹 된 것들; XOR 스왑으로 무엇을했는지조차 확실하지 않습니다)

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");

나는이 모든 것을 내 휴대 전화에 작성 했으며 테스트 할 시간이 없습니다. 당신이 어떤 버그를 발견하면 코멘트, 나중에 직접 확인하겠습니다.

사전 골프 인간 판독 가능 버전

// 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();

답변

펄, 114 96 95 93 92 87 86 85 바이트

+ 포함 -a0p

STDIN의 입력으로 실행하십시오.

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

이것은 단일 방향의 수평 정규식 솔루션과 회전을 결합합니다.

설명:

이 솔루션에서는 반복적으로 회전하고 다음 4 가지 테스트를 수행합니다.

/(.).\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

\C“모든 문자”는 어디에 있습니까 ( .이것은 개행 문자를 포함 하지 않습니다 ). 그것이 \C더 이상 사용되지 않고 경고로 이어지기 때문에 \H(수평이 아닌 공간) 대신 모든 숫자와 줄 바꿈을 캡처하기에 충분합니다.

4 회전 후 이것은 필요한 16 가지 테스트를 모두 수행했습니다.

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

답변

파이썬 3, 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])

임의로 큰 입력 크기를 처리하려면 8 행, 6 행의 5 및 9 행의 8을 변경하십시오. 또한 각 값이 무엇인지 상관하지 않으므로 값을 입력 할 수 있습니다.

absdefgh
sdkljahs
lsdfjasd
fjdhsdas
dkjhfasd
sdfhaskd
sdkfhkas
weriuwqe

그리고 반환 yes됩니다.

주석

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

답변

GNU sed 255 + 2 = 257B

나는 이것이 파이썬만큼 좋지 않을 것이라고 생각했지만 지금은 :-/ 오늘 인터넷에 접속하지 못했기 때문에 이것을 sed에서 해결하는 데 나 자신을 차지했습니다 :). -r 플래그를 사용하여 호출해야합니다. 즉, sed -rf command.sed < input점수에 2를 더했습니다.

: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

작동 방식 :

  1. 공백으로 구분 된 한 줄로 그리드를 읽습니다.
  2. 마더로드 정규 표현식을 사용하여 첫 번째 열에 일치하는 항목이 있는지 확인하십시오. * 예인 경우 전체 행을 ‘예'(프로그램 종료)로 바꾸십시오.
  3. 우리가 한 경우 각 열에서 첫 번째 문자를 제거하고 2로 이동하십시오.
  4. 우리가하지 않은 경우 (라인이 비어 있음) 전체 라인을 ‘no’로 바꿉니다.

답변

루비, 201 바이트

나는 정규식이나 무차별 대항 힘을 사용하지 않는이 위대한 도전에 대한 해결책을 보지 못해서 실망했습니다. STDIN에 입력됩니다.

핵심 비트 산술 알고리즘은 @leander의 Game Development Stack Exchange대한 환상적인 답변에서 파생됩니다 .

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"

루비 람다, 181 바이트

다음은 문자열을 가져 와서 true또는 반환하는 람다입니다 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}}}

repl.it에서 참조하십시오 : https://repl.it/ColJ/2

언 골프 및 설명

->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
    }
  }
}

코드는 숫자 “1”에서 “9”까지 반복됩니다. 각 반복에는 두 개의 개별 단계가 있습니다.

첫 번째 단계는 보드 변환 s.scan(n)입니다.이 코드 는 블록에서 ungolfed 코드로 볼 수 있습니다 . 이진수 문자열에서 일치하는 숫자를 1로, 다른 모든 숫자를 0으로 처리하여 보드를 각 행당 하나씩 8 개의 정수 배열로 변환합니다. 예를 들어, 행을 가져갑니다 12231123. 첫 번째 반복에서는 1000110010 진수 140 인 이진 문자열이됩니다 (모두 1은 —er, stay는 1이되고 다른 모든 숫자는 0이 됨). 두 번째 반복에서는 동일한 행이됩니다 01100010(모두 2는 2가되며 다른 모든 숫자는 0) 또는 10 진수 98이됩니다.

동시에 두 번째 변형을 수행합니다. 두 번째 변형은 첫 번째 변형과 동일하지만 보드가 90도 회전합니다. 이를 통해 가로 일치를 세로 일치와 동일한 논리로 사용할 수 있습니다. 간단하게하기 위해 두 보드를 처음에 0, 중간 (두 보드를 분리) 및 패딩을 위해 끝이있는 하나의 긴 보드로 연결합니다.

두 번째 단계는 each_cons(3).any?블록 에서 볼 수있는 가능한 일치 항목을 검색하는 것 입니다. 변환 된 행 (현재 8 비트 정수)은 비트 단위 산술을 사용하여 세 행 ( x , y , z )의 그룹에서 겹치게 (겹침) 검사됩니다 . 각 그룹은 y 행 에서 조각을 이동 하거나 x 또는 z 에서 조각을 y 로 이동하여 y 행 에서 일치시킬 수 있는지 확인합니다 . 원래 및 회전 된 보드의 행 앞뒤에 “행”이 없기 때문에 보드의 첫 번째 행이나 마지막 행에 있는지 확인할 필요가 없습니다.

일치하는 것이 없으면 다음 반복으로 계속됩니다.