Bejeweled / match 3 게임에 움직임이 있는지 확인


20

배경

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

태스크

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

입력

프로그램은 표준 입력을 통해 Bejeweled 그리드의 8x8 표현을 수용해야합니다. 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의 답변을 참조하십시오 .


그것은 단지 행 또는 열입니까?
TheDoctor

@TheDoctor 열도. "행에서 3 개"라는 문구를 사용하면 가로 또는 세로 방향으로 줄을 정렬해야합니다.
bdr9

@ bdr9 당신은 그것을 편집하고 싶을 수도 있습니다
John Dvorak

@JanDvorak 님.
bdr9

행에서 4+ 이상이 허용되는 경우 편집 할 수도 있습니다.
Justin

답변:


12

원래 솔루션 : 자바 스크립트 - 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 만 사용하는 입력 형식을 준수하지는 않지만 쉽게 수정되고 8x4 그리드 임)-모든 유효한 입력을 테스트하는 데 필요한 최소값이므로 ).

입력 문자열에서 위의 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에서 제안한 정규식 비트를 결합하여 원래 솔루션을 단축했습니다 .

1
좋은 해결책! 정규식이 작동한다고 생각하지 않았습니다. ?'yes':'no'요구 사항에 있고 다른 사람이 사용하기 때문에 공정성을 위해 캐릭터 수에 포함하십시오 .
bdr9

추가 테스트 사례에 감사드립니다. 다른 사람들이 볼 수 있도록 답변 링크를 추가했습니다.
bdr9

우와 정규식 +1
DankMemes 13:01에

H-mm, .줄 바꿈을 포함한 모든 문자와 일치하도록 JS에 수정자가 없습니까? Perl을 사용하면 결합 된 regexp는 129 바이트 문자열 (게으르고 Regexp :: Assemble로 컴파일 됨)이므로 전체 Perl 프로그램은 약 150 바이트입니다.
user2846289

1
감사합니다 @VadimR하지만 당신은 더욱 교체 갈 수 .{8}|.{9}.{8,9}.{7}|.{8}.{7,8}
MT0

3

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

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


3
이해할 수없는 이해에 대한 찬성 :)
alexander-brett

2

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

Hah 나는 실제로 첫 번째 게시물을 10 분 놓쳤다. 나는 좀이 생각처럼 ...
DankMemes

아, 내가 사용한 것과 똑같은 방법 (순진하지만 작은 코드!). 나보다 훨씬 더 설명적인 것으로 +1
KSab

더 효율적인 알고리즘이 있는지 궁금합니다.
DankMemes

2

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

1

파이썬 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

1

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'로 바꿉니다.

1

루비, 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 행 에서 일치시킬 수 있는지 확인합니다 . 원래 및 회전 된 보드의 행 앞뒤에 "행"이 없기 때문에 보드의 첫 번째 행이나 마지막 행에 있는지 확인할 필요가 없습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.