연결 4 : 가짜를 발견!


35

은행은 무너졌고 모든 지역 마피아 깡패는 특이한 알리바이를 가지고 있습니다. 조사를 돕기 위해 압류 된 모든 Connect 4 보드의 유효성을 검사하는 프로그램을 작성하여 해당 위치가 실제로 유효한 Connect 4 게임의 위치이며 급히 정리되지 않았는지 확인해야합니다. 경찰이 문을 두 드리 자마자

연결 사에 대한 규칙 : 플레이어 R와는 Y7x6 그리드의 컬럼에 자신의 색깔의 타일을 드롭 회전에 걸릴. 플레이어가 타일을 열에 떨어 뜨리면 해당 열에서 채워지지 않은 가장 낮은 위치를 차지하기 위해 떨어집니다. 플레이어가 보드에 자신의 색깔로 된 4 개의 타일을 수평, 수직 또는 대각선으로 달리면 승리하고 게임이 즉시 종료됩니다.

예를 들어 ( R시작시) 다음은 불가능한 Connect 4 위치입니다.

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | |
| | |Y| | | | |
|R| |Y| | | | |

프로그램이나 기능은 Connect 4 보드를 가져 와서

  • 위치가 불가능 함을 나타내는 잘못된 값
  • 그 위치에 이르는 움직임의 하나의 가능한 시퀀스 (나타내는 1~7에서 일련의 숫자는 열 번호가 17왼쪽에서 오른쪽으로, 및 서열 있도록 112, 예를 들어, 컬럼의 적색 이동을 나타내는 1황색 이동 한 후, 열 1에서 빨간색으로 이동 2). 솔루션에서 지정하는 한 원하는 경우 1234567 이외의 열 번호를 선택할 수 있습니다. 다른 형식으로 목록을 반환하려면; 예를 들어 배열 [2, 4, 3, 1, 1, 3]로 이동하면 움직임이 무엇인지 쉽게 알 수있는 한 괜찮습니다.

당신은 이외의 문자 사용을 포함한 모든 합리적인 형식으로 보드 선택하여 읽을 수 있습니다 RY선수에 대한,하지만 먼저 진행하는 플레이어를 지정해야합니다. 두 명의 플레이어가있는 보드는 항상 6x7이라고 가정 할 수 있습니다.

귀하가받는 직책은 최소한 물리적으로 표준 Connect 4 보드에서 만들 수 있다고 가정 할 수 있습니다. 즉, '부동'조각이 없을 것입니다. 보드가 비어 있지 않다고 가정 할 수 있습니다.

이것은 코드 골프이므로 최단 답변이 이깁니다. 표준 허점이 적용됩니다.

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | --> 1234567 (one possible answer)
| | | | | | | |
|R|Y|R|Y|R|Y|R|

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | | --> false
| | |Y| | | | |
|R| |Y| | | | |

| | | | | | | |
| | |Y| | | | |
| | |R| | | | |
| | |Y| | | | | --> 323333 (only possible answer)
| | |R| | | | |
| |Y|R| | | | |

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> false (this is the position arising after
| |Y|Y|Y|Y| | |     the moves 11223344, but using those moves
| |R|R|R|R| | |     the game would have ended once R made a 4)

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> 2134231211 (among other possibilities)
|R|R|Y| | | | |
|Y|R|R|Y| | | |

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> false (for example, 21342312117 does not
|R|R|Y| | | | |     work, because Y has already made a diagonal 4)
|Y|R|R|Y| | |R|

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> 112244553 or similar
|Y|Y| |Y|Y| | |
|R|R|R|R|R| | |

요한은 호기심으로 비-브 루트 포스 알고리즘이 존재하는지 알고 있습니까?
요나

답변:


9

젤리 , 57 바이트

ŒṪŒ!µ0ịŒṬ¬a³ZU,Ɗ;ŒD$€Ẏṡ€4Ḅo1%15;Ḋ€ṢṚ$Ƒƙ$Ȧȧœị³$2R¤ṁ$ƑµƇṪṪ€

0채워지지 않고 , 1먼저 2재생 하고, 두 번째로 재생 되는 행렬을 가져옵니다 . 가짜로 식별 된 경우 비어있는 1- 색인 열 목록을 생성합니다.

온라인으로 사용해보십시오! (7 분 이상 7 분 이상 실행하기에는 너무 비효율적 임)

노트 :

  1. "부동"조각이없는 것으로 가정합니다 ( ZṠṢ€Ƒȧ+6 바이트 를 앞에 붙여서 수정 )
  2. 빈 보드가 가짜라고 가정

11

자바 스크립트 (ES6)  202 194 187  183 바이트

빨강의 경우 , 노랑의 경우 , 비어있는 경우 의 행렬로 입력을 받습니다. 색인이없는 0 개의 문자열 (또는 솔루션이없는 경우 빈 문자열)을 반환합니다. 레즈는 게임을 시작합니다.240

m=>(p=[...'5555555'],g=(c,s=o='')=>/2|4/.test(m)?['',0,2,4].some(n=>m.join``.match(`(1|3)(.{1${n}}\\1){3}`))?o:p.map((y,x)=>m[m[y][x]--^c||p[g(c^6,s+x,p[x]--),x]++,y][x]++)&&o:o=s)(2)

온라인으로 사용해보십시오!

어떻게?

재귀 함수 는 입력 행렬에서 와 모두 과 으로 대체하려고 시도합니다 .g2413

그렇게하는 동안 모든 짝수 값이 사라질 때까지 (예 : 한 쪽이 이기면 마지막 이동이어야 함) 4 개의 연속 홀수 값이 실행되지 않습니다.

각 열 에 대해 사용 가능한 다음 슬롯 의 행 는 저장됩니다 .yxp[x]

댓글

m => (                            // m[] = input matrix
  p = [...'5555555'],             // p[] = next row for each column
  g = (c,                         // g = recursive function taking c = color,
          s = o = '') =>          //     s = current solution, o = final output
    /2|4/.test(m) ?               // if the matrix still contains at least a 2 or a 4:
      ['', 0, 2, 4]               //   see if we have four consecutive 1's or 3's
      .some(n =>                  //   by testing the four possible directions
        m.join``                  //   on the joined matrix, using
        .match(                   //   a regular expression where the number of characters
          `(1|3)(.{1${n}}\\1){3}` //   between each occurrence is either 1, 10, 12 or 14
        )                         //   (horizontal, diagonal, vertical, anti-diagonal)
      ) ?                         //   if we have a match:
        o                         //     abort and just return the current value of o
      :                           //   else:
        p.map((y, x) =>           //     for each cell at (x, y = p[x]):
          m[                      // 
            m[y][x]--             //       decrement the value of the cell
            ^ c ||                //       compare the original value with c
            p[                    //       if they're equal:
              g(                  //         do a recursive call with:
                c ^ 6,            //           the other color
                s + x,            //           the updated solution
                p[x]--            //           the updated row for this column
              ),                  //         end of recursive call
              x                   //         then:
            ]++,                  //         restore p[x]
            y                     //         and restore m[y][x]
          ][x]++                  //         to their initial values
        ) && o                    //     end of map(); yield o
    :                             // else:
      o = s                       //   we've found a solution: copy s to o
)(2)                              // initial call to g() with c = 2

참고 "빈 보드가 입력으로 제공되지 않는다고 가정 할 수 있습니까?" -우리가 이것을 처리해야한다면 코드를 조정해야합니다.
Jonathan Allan

내가 왜 모르는 f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [0,2,2,0,2,2,0], [1,1,1,1,1,1,1] ])종료로 0 하고 f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])진실해야합니다
나우 Fouilleul

@NahuelFouilleul 신고 해 주셔서 감사합니다. 이 테스트 사례를 추가 한 코드 추가를 수정했습니다.
Arnauld

2

파이썬 2 , 295 285 바이트

def f(a):
 if 1-any(a):return[]
 p=sum(map(len,a))%2
 for i in R(7):
	if a[i][-1:]==`p`:
	 b=a[:];b[i]=b[i][:-1];L=f(b)
	 if L>1>(`1-p`*4in','.join([J((u[j]+' '*14)[n-j]for j in R(7))for n in R(12)for u in[b,b[::-1]]]+b+map(J,zip(*[r+' '*7for r in b])))):return L+[i]
R=range;J=''.join

온라인으로 사용해보십시오!

Jo King 에게 -10 thx .

입력은 열을 나타내는 문자열 목록입니다. 빨강은 '1', 노랑은 '0'으로 표시됩니다. 문자열은 ''로 채워지지 않습니다. 따라서 (falsey) 사례 :

| | | | | | | |
| | | | | | | |
|Y| | | | | | |
|R|Y| | | | | |
|R|R|Y| | | | |
|Y|R|R|Y| | |R|

다음과 같이 입력됩니다 :

[
  '0110',
  '110',
  '10',
  '0',
  '',
  '',
  '1'
]

출력은 보드를 만들 수있는 0 인덱스의 열 인덱스 목록입니다. 또는 None유효하지 않은 경우.

빈 보드를 유효한 것으로 수락합니다 ( []대신 빈 목록을 반환 None).

이 접근 방식은 마지막 이동에서 첫 번째 이동으로 재귀 적입니다. 총 이동 수의 패리티에 따라 마지막 빨간색 이동 또는 마지막 노란색 이동을 제거합니다 (또는 불가능한 경우 실패). 결과 보드를 확인하여 상대에게 4in-a-row가 있는지 확인하십시오 (이 경우 게임이 이미 중지 되었기 때문에 실패). 그렇지 않으면 보드가 비워 질 때까지 반복합니다 (유효 함).

4 행 코드는 가장 부드럽습니다. 행렬의 모든 대각선 문자열은 다음에 b의해 생성됩니다.

[
    ''.join(
        (u[j]+' '*14)[n-j] for j in range(7)
    )
    for u in[b,b[::-1]]for n in range(12) 
]

먼저 '하향 경사'대각선을 나열한 다음 '상향 경사'대각선을 나열합니다.

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