지뢰 찾기 보드 확인


33

목표는 완성 된 지뢰 찾기 보드가 유효한지 확인하는 것입니다. 즉, 각 숫자는 대각선을 포함하여 인접한 셀의 올바른 광산 수입니다. 보드가 감겨 있지 않습니다.

평소같이 함수 또는 프로그램을 제공해야하며 바이트 단위의 가장 짧은 코드가 우선합니다.

지뢰 찾기 를 생성 , 해결완전히 구현 하기위한 과거 과제도 참조하십시오 .

입력:

다음과 같은 단일 문자열 : 02X2 13X2 X211.

  • 지뢰 찾기 보드의 행은 공백으로 구분됩니다. 위의 내용은 3x4 보드를 나타냅니다.

    02X2
    13X2
    X211

  • 각 셀은 문자 X광산에 대한, 또는 숫자 0를 통해 8.

  • 모든 행의 길이는 같습니다.

  • 행이 3 개 이상, 열이 3 개 이상 있습니다.

  • 입력이 공백으로 시작하거나 끝나지 않지만 원하는 경우 끝에 줄 바꿈을 포함시킬 수 있습니다.

산출:

올바른 보드에서 일관된 Truthy 및 잘못된 보드에서 일관된 Falsey 값. 일관된 은 모든 Truthy 출력이 동일하고 모든 Falsey 출력이 동일 함을 의미합니다.

테스트 사례

각 줄은 별도의 테스트 사례입니다.

True:

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX

False:

02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX

당신은 아마 일관된 falsy 출력이 ;-) 일관된 truthy 출력 달라야합니다 지정해야합니다
존 드보락

@JanDvorak 그것은 각각 Truthy와 Falsey라는 것을 암시해야합니다.
xnor

실제로는 아닙니다. "truthy"와 "falsy"는 사용자가 정의 할 수있는 레이블입니다. 나는 그들이 우리가 사용하는 언어에서 실제로 진실하거나 거짓이라는 제한을 볼 수 없습니다. 그것들을 구별해야 할 수있는 유일한 단어는 "표시"동사입니다. 나는 그것이 스펙으로 계산되는지 확실하지 않습니다 (그러나 여전히 표준 허점으로 금지되어 있습니다).
John Dvorak

4
@JanDvorak 'truthy'와 'falsy'는 기본적으로 bool로 입력 할 때 true 또는 false로 평가되는 것을 설명하는 데 잘못 사용되지 않는 경우 실제로 다소 일반적인 용어입니다. 예를 들어 0은 일반적으로 거짓이고 1은 일반적으로 진실입니다.
KSab

1
@JanDvorak 아니요, Truthy / Falsey는 정확 / 잘못된 정보와 일치해야합니다.
xnor

답변:


11

파이썬 (2), 132 (129) 128

def f(s):w=s.find(' ');E=dict(enumerate(s));return all(E[i]in' X'+`sum(E.get(i+d/3*~w+d%3+w,5)>'O'for d in range(9))`for i in E)

나는 enumerate골프에 사용하고 심지어 사용range 같은 프로그램의 다른 곳 했습니다. 분명히 뭔가 잘못되었습니다.

편집 : dict(enumerate(s))대신 반복 enumerate(s)하므로 enumerate두 번 호출 할 필요가 없습니다.


의 영리한 사용 ~! 범위를 벗어난 색인 작업을 올바르게 수행하는 사전.
xnor

@xnor ~운영자 에 대한 귀하의 의견은 아이러니하게도 한 번만 사용하면 분명히 똑같은 일을 할 수 있습니다. 나는 사전 부분이 재미 있다고 생각했다.
feersum

9

피스, 43

Jhxzd!f-@zT+" X"`sm/:+*JNztd+d2\Xm+T*kJU3Uz

여기에서 시도 하십시오 .

설명:

  • Jhxzd: 이것은 입력 + 1에서 첫 번째 공간의 위치입니다. ( z입력에서 d공간입니다.) 보드의 세로로 인접한 셀 사이의 입력에서 분리입니다.
  • !f: 이것은 !필터 ( f) 의 논리적 아님 ( ) True이며, 시퀀스의 모든 요소에 대해 표현식이 허위 인 경우에만 해당됩니다.
  • -@zT: T입력 에서 위치 (람다 변수)에 있는 문자를 가져 와서 다음 과 같은 모양을 제거하십시오.
  • +" X": 공백, X 및
  • `: Repr of
  • sm:지도의 합
  • / \X:의 "X"수
  • :+*JNz상기 입력의 슬라이스 접두사 J더미 문자
  • td+d2: d-1에서 d + 2로.
  • m+T*kJU3: [T, T + J, T + 2 * J]에서 d의 경우.
  • UzT in range(len(input)).

7
Downvoters : 왜 downvotes입니까?
isaacg

7

APL (NARS2000) (74)

{~0∊(G>9)∨G=(⍴G)↑{+/∊9<⍵∘⌷¨G∘.⊖(G←2-⍳3)∘.⌽⊂Z}¨⍳⍴Z←G↑⍨2+⍴G←¯1+⎕D⍳⊃⍵⊂⍨⍵≠' '}

⎕ML로 설정된 경우 Dyalog APL에서도 작동3 .

설명:

  • ⊃⍵⊂⍨⍵≠' ': 공백으로 분할 하고 목록을 사용하여 행렬을 형성하십시오.
  • G←¯1+⎕D⍳: ⎕D각 값 의 인덱스를 찾아 1을 빼고에 저장하십시오 G. ( ⎕D숫자가 포함되며, 숫자가 아닌 숫자는로 바뀝니다 10).
  • Z←G↑⍨2+⍴G: 줄 바꿈을 처리하기 위해 행렬의 가장자리에 두 줄과 0의 열을 추가하십시오.
  • {... }¨⍳⍴Z:의 각 위치에 대해 해당 위치 Z의 무어 인근에있는 폭탄의 양을 찾으십시오.
    • G∘.⊖(G←2-⍳3)∘.⌽⊂Z: Z좌, 우, 상, 하, 좌, 우, 좌, 우로 회전 합니다.
    • ⍵∘⌷¨: 이들 각각에 대해 회전 된 각 행렬에서 요소를 찾습니다.
    • +/∊9<: 9보다 많은 요소 수를 세십시오 (이것은 폭탄의 양입니다).
  • (⍴G)↑: 추가 된 0을 다시 제거
  • G=: 각 요소 G가 해당 위치를 둘러싸고있는 폭탄의 양과 같은지 확인하십시오 ( 폭탄이 아닌 모든 사각형에 해당해야 함).
  • (G>9)∨: 요소 가 폭탄 G보다 높은지 확인하십시오 9.
  • ~0∊: 1결과 행렬에 0이 포함되지 않은 경우 (= 모든 사각형은 폭탄이거나 올바른 숫자 임) 0반환합니다.

바이트 나 문자를 세었습니까? 바이트 수를 세어야합니다.
Tim S.

5
@TimS .: 1 바이트 APL 인코딩이 많이 있습니다 .
marinus

5

C #을 321 320 305

bool s(string B){var L=B.Split(' ').Select(s=>' '+s+' ').ToList();var b=new string(' ',L[0].Length);L.Insert(0,b);L.Add(b);Func<int,int,IEnumerable<int>>E=Enumerable.Range;return E(1,b.Length-2).All(x=>E(1,L.Count-2).All(y=>L[y][x]=='X'||L[y][x]-'0'==E(x-1,3).Sum(X=>E(y-1,3).Sum(Y=>L[Y][X]=='X'?1:0))));}

먼저 골프를 타보십시오. C #이 이상적인 언어는 아닙니다.

인스턴스 메소드 작성이 허용되기를 바랍니다. 그렇지 않으면에 다른 7자를 추가하십시오 static.

간격 :

bool s(string B) {
    var L = B.Split(' ').Select(s => ' ' + s + ' ').ToList();
    var b = new string(' ', L[0].Length);
    L.Insert(0, b);
    L.Add(b);
    Func<int, int, IEnumerable<int>> E = Enumerable.Range;
    return E(1, b.Length - 2).All(x =>
        E(1, L.Count - 2).All(y =>
            L[y][x] == 'X' ||
            L[y][x] - '0' == E(x - 1, 3).Sum(X =>
                E(y - 1, 3).Sum(Y =>
                  L[Y][X] == 'X' ? 1 : 0))));
}

Linq를 사용하면 for 루프에 비해 약간의 공간이 절약되지만 디버깅하기가 더 어렵습니다.

char => int빼서 변환 하는 것과 같은 몇 가지를 배웠습니다 '0'.

공백으로 보드를 채우는 것이 더 간단 해 보였으므로 반복하는 것이 더 쉬울 것입니다.


1
당신은 대체 단지 수 없습니다 -'0'와 함께 -48. 나를 위해
Roman Gräf

5

파이썬 2, 121

def f(B):n=B.find(' ')+1;R=range(len(B));print all(B[I]in' X'+`sum(2>I%n-i%n>-2<I/n-i/n<2<B[i]>'W'for i in R)`for I in R)

이것은 feersum의 답변에 크게 영감을 받았습니다 . 하루의 순서는 과도합니다. 셀의 9 개 이웃에서 광산을 확인하는 대신 모든 단일 셀에서 이웃 광산인지 확인하십시오.

우리는이 세포는 이웃에있는 경우 확인 2>r>-2<c<2, 어디 rc에 해당 셀의 행과 열 차이가 있습니다 {r,c}<{-1,0,1}. 이 좌표는 셀 인덱스로부터 계산 Ii같이 c=I%n-i%n하고 r=I/n-i/n. 목록 목록과 같은 2D 객체로 변환하는 것보다 문자열로 직접 색인을 생성하고 행과 열을 추출하는 것이 더 효율적입니다. 광산 수표는 다음 B[i]>'W'과 같습니다.B[i]=='X' .

를 사용하면 두 개의 중첩 루프를 지원하지 않는 반복자 객체를 반환한다는 점을 제외하고 enumerate못생긴 두 문자를 저장했을 range(len(B))것입니다.


n에 대해 음의 계수가 작동해야한다고 생각합니다. 그런 다음 사용할 수 있습니다 ~B.find.
feersum

@feersum 불행하게도, /그것은 마이너스를 반올림하기 때문에 엉망이됩니다 .
xnor

4

파이썬 2, 140

s=input();w=s.index(' ')+1
print all(c in'X 'or(int(c)==sum(s[max(0,a-1):max(0,a+2)].count('X')for a in[i-w,i,i+w]))for i,c in enumerate(s))

4

자바 스크립트 (ES6) 135 133 125 122

f=s=>s.split(" ")[e="every"]((l,i,a)=>[...l][e]((c,j)=>!(-[-1,0,k=1][e]((y,m,q)=>q[e](x=>k+=(a[i+y]||0)[j+x]=="X"))-c+k)))

함수에 문자열로 입력을 제공하십시오.

f("XX4X2 5X6X4 XX6XX 4XX54 2X4XX");

자세한 내용은 아래 이전 버전을 참조하십시오. 새 버전은 for루프를 every호출로 대체하고 대신 변수 e="every"를 사용하여 수행 someArray[e](...)합니다.someArray.every(...) .

또한, 카운터는 k지금에 인덱싱 1때문에 것을 k+=...유지하기 위해, 표현은 항상 truthy입니다 every루프 실행. 우리 는 연산에 의해 반환 된 결과 (숫자에 의해 강제되는 ) 를 1빼서 그 여분 을 제거합니다 .true1every[-1,0,k=1][e](...)


구 버전:

f=s=>s.split(" ").every((l,i,a)=>[...l].every((c,j)=>{q=[-1,k=0,1];for(y of q)for(x of q)k+=(a[i+y]||0)[j+x]=="X";return c=="X"||k==c}))

공백과 주석이있는 코드 :

f=s=>s.split(" ")                 // split on spaces
      .every((l,i,a)=>             // for every line
                                   //     l: line string, i: line number, a: whole array
          [...l].every((c,j)=>{    // for every character
                                   //     c: character, j: index in string
              q=[-1,k=0,1];        // define counter k=0 and q=[-1,0,1]
              for(y of q)          // use q to loop adjacent spaces
                  for(x of q)

                      k+=              // add the following boolean to k:

                          (a[i+y]      //   from line number i+y...
                                 ||0)  //   (or a dummy zero, to prevent lookups on undefined)
                          [j+x]        //   ...get index j+x from the above value...
                                =="X"; //   ...and compare it to "X"

              return !(k-c)     // after the loop, this character passed if
                                // the char equals the number of counted X's (so k-c is 0)
                                // or it is an X itself (so `k-c` is NaN)
          })
      )

JavaScript every배열 메소드는 콜백을 가져와 콜백을 배열의 모든 요소에 적용합니다. 콜백이 잘못된 값을 every반환 하면 호출이를 반환합니다 false.

JS의 부울은 추가의 일부일 때 1 또는 0으로 강제됩니다. 각 주변 공간에 대해 값을 비교 한 부울 결과를 "추가" X한 다음 해당 값을 k표현식 의 카운터 에 추가합니다 k += (... == "X"). 따라서로 계산 하고로 계산 하기 때문에 k주변 X의 개수를 포함 합니다.true1false0


c=="X"try 대신에 !c/1엄청난 양의 바이트 쌍을 절약 할 수 있습니다! 실패하면을 시도하십시오 !!c/1. 추론은 즉 'X'/1 => NaN, 그리고 NaNfalsie입니다. 당신 c=='X'은 아닌지 확인하려고, 왜 확인하지 false?
Ismael Miguel

@IsmaelMiguel이 평가는와 동일하지만 (!c)/1불행히도 도움이되지 않습니다. 에 대한 괄호가 필요합니다. !(c/1)비용은 2입니다. 또한 0/1잘못된 입력이므로 잘못된 입력 " 0X"의 결과가 잘못됩니다 true. 여전히 제로를 존중하면서 할 수있는 최선의 방법은 두 조건을 부정 문구로 결합하는 것입니다 !(+c+1&&k-c).하지만 이미 가지고있는 것과 같은 길이입니다.
apillers

하지만 내가 그것에 대해 생각을 취득하기위한 @IsmaelMiguel 감사합니다 - 나는 것을 깨달았다 !(k-1-c)시험 두 조건 때문에 만약 k일치 c(마이너스 1 오프셋), 후 부정이 수 0사실, 그리고 만약 c숫자, 우리가 얻을하지 않습니다 NaN및 부정 또한 true입니다.
apillers

정말 배가 고 ry어요! 초기 코드부터 10 바이트를 먹었습니다! 나는 당신이 생각해 낸 해결책을 정말로 좋아합니다. 솔루션 +1!
Ismael Miguel

3

CJam, 70 65 63 바이트

1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI

이것은 골프를 많이 할 수 있습니다.

부여 1유효한 보드 및 0잘못된 보드.

테스트 사례

{-1:W;
1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI
}6*]N*

입력

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX
02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX

산출

1
1
1
0
0
0

여기에서 온라인으로 사용해보십시오


3

자바 스크립트 (ES6) 98

일부 를 사용 하여 문자열의 각 문자에 함수를 적용합니다.
이 함수는

  • 비어 있으면 false
  • 'X'인 경우 NaN ( 'X'와 같이 숫자가 아닌 문자에서 값을 반복적으로 빼면 NaN이 나타납니다)
  • 올바른 숫자의 'X'가 있으면 숫자 값 0, 그렇지 않으면 0
    이 아닙니다 . 내부 검사는 forEach 보다 짧기 때문에 map을 사용하여 수행 됩니다.

일부 는 실패한 검사를 의미하는 첫 번째 진실 값 (이 경우 0이 아님)에서 true를 반환합니다. 결과는 더 인식 가능한 참 / 거짓을주기 위해 부정된다.

F=v=>![...v].some(
  (x,p)=>x!=' '&&[1,-1,l=v.search(' '),-l,++l,-l,++l,-l].map(q=>x-=v[p+q]=='X')|x
)

FireFox / FireBug 콘솔에서 테스트

;["02X2 13X2 X212","XXXX XXXX X7XX XXXX","XX5X2 5X6X4 XX6XX 4XX54 2X5XX"
,"02X2 13X2 X211","XXXX XXXX XXXX XXXX","XX4X2 5X6X4 XX6XX 4XX54 2X4XX","111 1X1 111"]
.forEach(t => console.log(t, F(t)))

산출

02X2 13X2 X212 false
XXXX XXXX X7XX XXXX false
XX5X2 5X6X4 XX6XX 4XX54 2X5XX false
02X2 13X2 X211 true
XXXX XXXX XXXX XXXX true
XX4X2 5X6X4 XX6XX 4XX54 2X4XX true
111 1X1 111 true

1

R, 156 자

a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])

가독성을 위해 들여 쓰기, 공백 및 줄 바꿈을 사용합니다.

a = b = do.call(rbind,strsplit(scan(,""),"")) #Reads stdin and turn into a matrix
for(i in 1:nrow(a)) #Ugly, ugly loop
    for(j in 1:ncol(a))
        b[i,j] = sum(a[abs(i-row(a))<2 & abs(j-col(a))<2]=="X")
v = a!="X"
all(b[v]==a[v])

예 :

> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX4X2 5X6X4 XX6XX 4XX54 2X4XX
6: 
Read 5 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XXXX XXXX XXXX XXXX
5: 
Read 4 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX5X2 5X6X4 XX6XX 4XX54 2X5XX
6: 
Read 5 items
[1] FALSE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.