퀸즈 퍼즐 확인


16

체스에 여왕이 무엇인지 모른다면 별 상관 없습니다. 그것은 단지 이름입니다 :)

여러분의 입력은 일정량의 여왕을 포함하는 임의의 너비와 높이 의 제곱 이됩니다. 입력 보드는 다음과 같습니다 (이 보드의 너비와 높이는 8입니다).

...Q....
......Q.
..Q.....
.......Q
.Q......
....Q...
Q.......
.....Q..

이 보드에는 8 명의 여왕이 있습니다. 만약 여기에 7, 1, 10이 있다면 보드는 유효하지 않을 것입니다.

여기서 우리 .는 빈 공간과 Q여왕을 위해 사용합니다. 또는 공백이 아닌 문자를 대신 사용할 수도 있습니다.

이 입력은 유효한 것으로 검증 될 수 있으며 정확한 값을 인쇄 (또는 리턴)해야합니다 (유효하지 않은 경우 거짓 값을 인쇄 (또는 리턴)해야 함). 퀸이 다른 열과 같은 행, 열, 대각선 또는 대각에 있지 않기 때문에 유효합니다 .

예 (괄호 안에 물건을 출력하지 마십시오) :

...Q....
......Q.
..Q.....
.......Q
.Q......
....Q...
Q.......
.....Q..

1

...Q.
Q....
.Q...
....Q
..Q..

0

Q.
Q.

0

..Q
...
.Q.

0 (this is 0 because there are only 2 queens on a 3x3 board)


..Q.
Q...
...Q
.Q..

1

Q

1 (this is valid, because the board is only 1x1, so there's no queen that can take another)

여왕이 다른 열과 같은 행, 열, 대각선 또는 대각에 있지 않은 경우 입력이 유효하다는 것을 강조하겠습니다 .

규칙

  • 빈 입력은받지 않습니다
  • 입력에 보드 영역의 제곱근보다 적은 여왕이 포함 된 경우 유효하지 않습니다.
  • 2x2 또는 3x3 보드에 유효한 솔루션은 없지만 너비와 높이가 자연수 인 다른 모든 크기의 사각형 보드에 대한 솔루션 이 있습니다.
  • 입력은 PPCG 규칙에 따라 임의의 합리적인 형식 일 수 있습니다
  • 입력은 항상 sqaure입니다
  • 예제에서 1과 0을 사용했지만 진실 또는 허위 값 (예 : Why yes, sir, that is indeed the caseWhy no, sir, that is not the case)을 사용할 수 있습니다.

이것이 이므로 가장 짧은 코드가 승리합니다!



1
겠습니까는 {(x, y, v)}v에서하는 것은 [., Q]유효한 입력 형식이 될?
PidgeyUsedGust

@DuctrTape 나는 그것이 의미가 있다고 생각하지 않습니다.
Okx

2
@Okx 즉, 좌표 및 값 목록을 입력으로 받는지 묻습니다. 예를 들면 다음과 같습니다 (0, 0, Q), (0, 1, .), (1, 0, Q), (1, 1, .). 세 번째 테스트 사례입니다.
Mego

줄 바꿈없이 문자열을 사용할 수 있습니까?
Titus

답변:


7

달팽이 , 14 바이트

&
o.,\Q!(z.,\Q

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

2D 의사 결정 문제에 대한 2D 패턴 일치 언어와 같은 것은 없습니다. :)

설명

&첫번째 라인 입력의 모든 가능한 위치에서 일치하도록 상기 제 라인 패턴을 요구하는 검색 모드 옵션이다. 이 경우 프로그램이 인쇄 1하고 그렇지 않으면 인쇄합니다 0.

패턴 자체 )는 끝에 암시 적이라는 점에 유의하십시오 .

o       ,, Move in any orthogonal direction (up, down, left or right).
.,\Q    ,, Make sure that there's a Q somewhere in that direction from the
        ,, starting position of the match.
!(      ,, After finding the Q, make sure that the following part _doesn't_ match:
  z     ,,   Move in any orthogonal or diagonal direction.
  .,\Q  ,,   Try to find another Q in a straight line.
)

이것이 부정적인 이유에서 시작하여 가장 쉬운 이유는 무엇입니까? 우리가 이미 찾은 Q것과 다른 직선 이 없음 을 Q확인함으로써 N 명의 여왕 이 없도록하십시오 (그렇지 않으면 한 행에서 두 개가 되려면 다른 여왕을 찾지 않고는이 여왕을 찾을 수 없습니다.) 그런 다음 첫 번째 부분은 어떤 위치에서든 직교 방향으로 도달 할 수있는 여왕이 있는지 확인하고 정확히 N 개의 여왕 이 있는지 확인하십시오 . 하나가 없으면 여왕이없는 행과 열이있을 것입니다. 이들의 교차점에서 시작하여 직교 방향으로 만 가면 여왕을 찾을 수 없습니다.


6

젤리 , 17 또는 15 바이트

ỴµUŒD;ŒD;ZVṀ;V=1Ṃ

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

용도 여왕과 ¹빈 공간. (이것은 대부분 입력을 문자열로 강제하기 때문에 입력을 배열로 사용하는 것을 금지 한 결과입니다 .Jelly에서는 문자열을 정수로 변환하는 것이 어렵습니다. 가장 쉬운 방법은 평가 중이며 1과 대신 대신 0을 "add 1"( ) 및 "add 0"( ¹)을 사용하면 여왕을 평가하여 목록에서 여왕을 계산할 수 있기 때문에 여러 합계 및 맵 명령을 생략 할 수 있습니다. 진실과 거짓 값은 젤리의 정상 1이며 0.

편집 : 입력을 행렬로 사용할 수 있도록이 답변을 작성한 이후 질문이 변경되었습니다. 이렇게하면 선행을 삭제하여 Ỵµ2 바이트를 절약 할 수 있습니다 . 또한 입력 형식을 평가 S하는 대신 합계를 사용하여보다 일반적인 것으로 변경할 수 V있지만 바이트를 절약한다고 생각하지 않으며이 펑키 형식과 비슷합니다.

설명

ỴµUŒD;ŒD;ZVṀ;V=1Ṃ
Ỵ                    Split on newlines.
 µ                   Set this value as the default for missing arguments.
     ;  ;            Concatenate the following three values:
  UŒD                - the antidiagonals;
      ŒD             - the diagonals;
         Z           - and the columns.
          V          Evaluate (i.e. count the queens on) all of those.
           Ṁ         Take the largest value among the results.
            ;V       Append the evaluation (i.e. queen count) of {each row}.
              =1     Compare each value to 1.
                Ṃ    Take the minimum (i.e. most falsey) result.

따라서 기본 개념은 각 대각선, 대각선 및 기둥에 최대 하나의 여왕이 있다는 것입니다. 그리고 각 줄에 정확히 하나의 여왕. 이러한 조건은 4 가지 종류의 라인 각각에 최대 1 개의 퀸이 있어야하며 보드의 측면 길이와 동일한 수의 퀸이 필요합니다.

덧붙여서, Jelly는 아마도 반 대각선을위한 내장을 가지고있을 수 있지만 AFAICT는 그것을 가지고 있지 않은 것 같습니다. 그래서 나는 보드를 반사하고 대각선을 취하기 위해 정착해야합니다.

또 다른 흥미로운 주 변화이다 =1ṂE(모두 동일하면) 일반화주지 않는다 N 도 받아들이 검사기 -queens N × N 보드 각 행, 열, 대각선 및 antidiagonal보다 더 포함 유전율 퀸과 기판을 정확하게 포함 kn 여왕. k 를 1로 제한 하면 실제로 2 바이트가 필요합니다.


규칙이 업데이트되었습니다. 이제 "PPCG 규칙에 따라 입력이 합당한 형식으로되어있을 수 있습니다".
Jonathan Allan

5

옥타브, 57 70 67 51 52 바이트

사용하여 1 바이트에 저장 flip하는 대신 rot90@LuisMendo에 감사하지만, 1 × 1 케이스에 버그를 발견

@(A)all(sum([A A' (d=@spdiags)(A) d(flip(A))],1)==1)

1은 Queen을 나타내고 0은 빈 공간을 나타내는 2 진 행렬로 입력을받습니다.

먼저 입력 행렬과 해당 조옮김을 연결하는 익명 함수를 만듭니다.

spdiags대각선이 열로 바뀌고 (필요에 따라 0으로 채워짐 ) 인수와 같은 수의 행을 가진 행렬을 만듭니다. 따라서 spdiags입력 행렬을 연결 하여 대각선 spdiags을 가져오고 행렬을 가로로 뒤집어 대각선 을 가져옵니다.

이제 연결된 행렬의 각 열의 합을 취하고 각 열이 정확히 1인지 확인하십시오.

ideone에서 샘플 실행 .


flip대신에 사용할 수 있다고 생각합니다rot90
Luis Mendo

@LuisMendo Yep, 그것도 효과가 있습니다. 감사!
비커

또한 피할 수 all()없습니까?
Luis Mendo

@LuisMendo Ugh ... 아마도 ... 아마도 ... 저녁 식사가 끝날 때까지 기다려야합니다;)
비커

4

MATL , 38 34 바이트

@beaker 덕분에 4 바이트가 줄었습니다 !

sG!sGt&n_w&:&XdsGP5M&Xdsv2<GnGzU=*

입력은 세미콜론을 행 구분 기호로 사용하여 0과 1로 구성된 2D 배열입니다.

이것은 1의 열 벡터를 진실로 출력하고 적어도 하나의 0을 거짓으로 포함하는 열 벡터를 출력합니다.

온라인으로 사용해보십시오! 바닥 글 코드는 if진실성 또는 허위 사실을 보여주기 위한 지점입니다.

또는 모든 테스트 사례를 확인하십시오 .

설명

s      % Input binary matrix implicitly. Sum of columns. Gives a row vector
G!     % Paste input again. Transpose
s      % Sum of columns (rows in the original matrix). Gives a row vector
G      % Paste input again
t&n    % Duplicate. Push number of rows and number of columns (will be equal)
_w     % Negate, flip
&:     % Binary range. Gives [-n -n+1 ... n] for input of size n×n
&Xd    % Get diagonals -n through n. This gives all diagonals as colums
s      % Sum of each column (diagonals of original matrix). Gives a row vector
GP     % Paste input again. Flip vertically
5M     % Push [-n -n+1 ... n] again
&Xd    % Get diagonals -n through n (anti-diagonals of original matrix)
s      % Sum of each column. Gives a row vector
v      % Concatenate everything into a column vector
2<     % True for elements that are less than 2
Gn     % Paste input again. Number of elements
Gz     % Paste input again. Number of nonzeros (i.e. of queens)
U      % Square
=      % True if equal
*      % Mutiply, element-wise

이진 행렬을 입력으로 사용할 수 있으므로 이제 2 바이트를 절약 할 수 있습니다.
beaker

2

J , 37 바이트

(+/&,=#)*1=[:>./+//.,+//.&|.,+/,+/&|:

부울 매트릭스를 인수로 사용하는 익명 함수 트레인.

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

( +/&,래블은 =동일 #행의 집계)

* 그리고 (조명 시간)

1하나 는 최대치 =와 같다[:>./

+//.대각선 ,과 (에 catenated에 불이 켜져)

+/합계 /.대각선 &|.반대 ,

+/에 걸쳐 합계 ,

+/합계 &|:전치


2

SnakeEx , 67 바이트

m:({q<>}({q<R>}[{q<RF>}{n<RF>}].)*{e<>}<R>)%{4}
e:.$
q:_*Q_*$
n:_+$

_대신 사용.입력 . 진실에 대해서는 1 개 이상의 일치를, 거짓에 대해서는 0을 반환합니다. 헤더의 링크에서 온라인 통역사를 찾을 수 있습니다.

설명

SnakeEx는 2-D 패턴 매칭 챌린지 의 언어입니다 . 그것은 그리드 일치하는 물건 주위를 이동하는 "뱀"을 정의합니다. 뱀은 다른 뱀을 생성하여 언어를 매우 강력하게 만듭니다.

이 프로그램을 아래에서 위로 보자.

n:_+$

이것은 n하나 이상의 밑줄과 일치 하는 뱀 을 정의한 다음 그리드의 가장자리를 정의합니다. 이것은 8 가지 기본 방향 중 하나 일 수 있습니다. 방향은 뱀이 생성 될 때 결정됩니다.

q:_*Q_*$

n위와 유사하게 , 이것은 q밑줄, 단일 Q, 밑줄 및 그리드의 가장자리와 일치하는 뱀으로 정의 됩니다 . 다시 말해, 열이 하나 뿐인 행 / 열 / 대각선입니다.

e:.$

e 한 캐릭터와 그리드의 가장자리와 일치하는 뱀입니다.

m:({q<>}({q<R>}[{q<RF>}{n<RF>}].)*{e<>}<R>)%{4}

메인 뱀 m 은이 빌딩 블록을 사용하여 전체 보드를 확인합니다. 개념적으로, 그것은 그리드의 바깥 쪽 가장자리를 돌며 다른 뱀을 스폰하여 모든 열과 행에 정확히 하나의 여왕이 있고 모든 대각선에 최대 하나의 여왕이 있는지 확인합니다. 생성 된 뱀 중 하나라도 일치하지 않으면 전체 일치가 실패합니다. 그것을 분해하자.

  • ( )%{4}괄호 안에있는 내용을 각면마다 한 번씩 4 번 실행합니다. (다음에서 왼쪽 위 모서리에서 시작하여 오른쪽으로 이동하는 특정 측면 (예 : 그리드의 위쪽 가장자리)을 그리는 것이 도움이됩니다.)
  • {q<>}q메인 뱀이 움직이는 것과 같은 방향으로 뱀을 낳습니다 . 이것은 현재 모서리가 "정확히 하나의 여왕"규칙을 충족하는지 확인합니다. 스폰 된 스네이크는 메인 스네이크의 일치 포인터를 움직이지 않으므로 여전히 가장자리의 시작 부분에 있습니다.
  • ( )* 괄호 안에있는 항목 중 0 개 이상과 일치합니다.
  • {q<R>}q뱀이 주 뱀의 방향에서 오른쪽으로 회전 합니다 . (예를 들어 메인 뱀이 위쪽 가장자리를 따라 오른쪽으로 움직이면이 뱀은 아래쪽으로 이동합니다.) 각 열 / 행을 확인합니다.
  • [ ] 괄호 안의 옵션 중 하나와 일치합니다.
    • {q<RF>}급부상는 q뱀 45 개도 (즉 우측으로 설정 Right 및 F주요 뱀의 방향에서 orward을). q대각선 정확히 퀸이 포함 된 경우 뱀과 일치합니다.
    • {n<RF>}n대신 뱀을 낳습니다 . n대각선이 더 왕비가없는 경우에 뱀과 일치합니다.
  • . 일치 포인터를 앞으로 이동하여 모든 문자와 일치합니다.
  • 가능한 한 많은 수평 및 대각선을 확인한 후 스폰하여 가장자리에 있는지 확인합니다 {e<>} .
  • 마지막으로 <R>메인 뱀을 오른쪽 으로 돌리고 다음 가장자리에 맞출 준비를하십시오.

이상한 것들

  • 일치하는 외부 코너에서 시작되도록 프로그램에는 아무것도 없습니다. 사실, 진지한 테스트 사례는 여러 개의 일치 항목을 생성하며, 일부는 내부에서 시작됩니다. 그럼에도 불구하고, 내가 시도한 거짓 사례 중 어느 것도 거짓 긍정을 생성하지 않았습니다.
  • 언어 사양을 올바르게 읽으면 X대신 (대각선 방향으로 분기) 를 사용할 수 있어야합니다 RF. 불행히도, 온라인 통역사는 이것이 구문 오류라고 말했습니다. 나는 또한 *(모든 방향으로 분기) 시도했지만 통역사가 중단되었습니다.
  • 이론적으로, _*Q?_*$대각선에서 "최대 1 명의 여왕"을 일치시키기 위해 작동해야하지만 통역사가 중단되었습니다. 내 생각에 빈 일치 가능성이 문제를 일으킨다는 것입니다.

2

루비, 120 바이트

문자열로 입력해야하는 원래 사양을 기반으로하는 Lambda 함수

->s{t=k=0
a=[]
s.bytes{|i|i>65&&(a.map{|j|t&&=((k-j)**4).imag!=0};a<<k)
k=i<11?k.real+1:k+?i.to_c}
t&&~a.size**2>s.size}

Q를 복소수로 변환하고 서로 뺍니다. 두 퀸의 좌표 간의 차이가 수평, 수직 또는 대각선 인 경우, 4 차 거듭 제곱으로 높이를 올리면 실수가되고 배열이 유효하지 않습니다.

테스트 프로그램에서 언 골프

f=->s{                                 #Take input as string argument.
  t=k=0                                #k=coordinate of character. t=0 (truthy in ruby.)
  a=[]                                 #Empty array for storing coordinates.
  s.bytes{                             #Iterate through all characters as bytes.
    |i|i>65&&(                         #If alphabetical, compare the current value of k to the contents of a
      a.map{|j|t&&=((k-j)**4).imag!=0} #If k-j is horizontal, vertical or diagonal, (k-j)**4 will be real and t will be false
      a<<k)                            #Add the new value of k to the end of a.
    k=i<11?k.real+1:k+?i.to_c          #If not a newline, increment the imaginary part of k. If a newline, set imaginary to 0 and increment real
  }                                    #s.size should be a*a + a newlines. ~a.size = -1-a.size, so ~a.size**2 = (a.size+1)**2
t&&~a.size**2>s.size}                  #compare a.size with s.size and AND the result with t. Return value. 


p f["...Q....
......Q.
..Q.....
.......Q
.Q......
....Q...
Q.......
.....Q.."]

p f["...Q.
Q....
.Q...
....Q
..Q.."]

p f["Q.
Q."]

p f["..Q
...
.Q."]

p f["..Q.
Q...
...Q
.Q.."]

p f["Q"]

2

파이썬 (3) , 232 (200) 155 바이트

d=1
f=input()
Q=[]
for i in f:d=[0,d][i.count('Q')==1];Q+=[(len(Q),i.index('Q'))]
print[0,d][sum(k[1]==i[1]or sum(k)==sum(i)for k in Q for i in Q)==len(Q)]

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

입력 사양의 변화를 감지 한 @beaker 덕분에 -32 바이트; 파이썬 3에서 2로 언어를 변경하여 input문자열 배열 또는 문자 배열로 입력하는 데 사용할 수 있습니다.

@Leaky Nun 덕분에 -45 바이트


도움이된다면 입력 요구 사항이 완화되었습니다.
beaker

@beaker 알았어, 고마워 대신 입력을 문자열 배열로 사용합니다. 지적 해 주셔서 감사합니다!
HyperNeutrino


1

자바 스크립트 (ES6), 115 바이트

a=>!a.some((b,i)=>b.some((q,j)=>q&&h[i]|v[j]|d[i+j]|e[i-j]|!(h[i]=v[j]=d[i+j]=e[i-j]=1))|!h[i],h=[],v=[],d=[],e=[])

언 골프 드 :

function queens(arr) {
    horiz = [];
    vert = [];
    diag = [];
    anti = [];
    for (i = 0; i < arr.length; i++) {
        for (j = 0; j < arr.length; j++) {
            if (arr[i][j]) { // if there is a queen...
                if (horiz[i]) return false; // not already on the same row
                if (vert[j]) return false; // or column
                if (diag[i + j]) return false; // or diagonal
                if (anti[i - j]) return false; // or antidiagonal
                horiz[i] = vert[j] = diag[i + j] = anti[i - j] = true; // mark it
            }
        }
        if (!horiz[i]) return false; // fail if no queen in this row
    }
    return true;
}

0

루비, 155 바이트

->x{(y=x.map{|r|(i=r.index ?Q)==r.rindex(?Q)?i:p or-2}).zip(y.rotate).map.with_index{|n,i|n.max-n.min==1&&i<y.size-1?-2:n[0]}.inject(:+)*2==(s=x.size)*~-s}

이것은 끔찍한 일이므로 아래에 골프 버전이 약간 적습니다.

->x{
    (y=x.map{|r|(i=r.index ?Q)==r.rindex(?Q)?i:p or-2})
    .zip(y.rotate)
    .map.with_index{|n,i|n.max-n.min==1&&i<y.size-1?-2:n[0]}
    .inject(:+)*2==(s=x.size)*~-s
}

이것은 동일한 코드이지만 무슨 일이 일어나고 있는지 구분하기위한 줄 바꿈이 있습니다.

코드 tself는 문자열 배열을 취하는 익명의 람다 함수입니다.x 형식 ) 입니다.["..Q", "Q..", ".Q."] .

첫 번째 줄은 각 문자열을 해당 문자열의 Q 문자 색인에 매핑합니다. Q 문자가 없으면 -2 1 로 대체됩니다 . 이 새로운 인덱스 배열은 변수에 할당됩니다y .

다음 줄은이 인덱스 배열을 1만큼 오프셋하여 회전시킵니다 (회전). 이로 인해 연속 인덱스 쌍이 배열됩니다.

다음 줄은 특히 복잡합니다. 각 인덱스 쌍을 통과하고 큰 값에서 작은 값을 뺍니다. 이것이 1이면 (그리고 우리는 마지막 쌍이 아닙니다 2 경우 같은 대각선에 2 개의 퀸이 있고 -2 값이 삽입됩니다. 그렇지 않으면 문자열에서 퀸의 원래 색인이 삽입됩니다 .

마지막 줄은 각각에 대한 모든 색인을 요약하고 그것이 n-1에 대한 삼각형 숫자인지 확인합니다. 여기서 n은 사각형의 너비 (또는 높이)입니다.

1 : -1은 내가 갔지만 0과는 거리가 1이므로 대각선을 확인하는 데 어려움이 있습니다. 최종 합계를 잘못 만드는 것이 부정적인 점이 중요합니다. 9와 같은 높은 숫자 (한 자리 숫자)에 대해 생각했지만 잘못된 확인을 초래하지 않을 것이라고 확신 할 수 없습니다.
2 : 보드는 둥글 지 않지만 루비의 rotate배열 함수는 그렇지 않습니다. 마지막 쌍이 다르면 중요하지 않습니다. 대각선이 아닙니다.


0

PHP, 137143 바이트

Neil의 솔루션에서 영감을 얻은

for($n=1+strlen($s=$argv[1])**.5|0;($c=$s[$p])&&!(Q==$c&&$v[$x=$p%$n]++|$h[$x=$p/$n]++|$d[$y-$x]++|$a[$y+$x]++);$p++);echo$n-1==count($a)&&!$c;

첫 번째 명령 행 인수에서 입력을받습니다. 로 실행하십시오 -r. 단일 바이트 줄 바꿈이 필요합니다.
실제로 0줄 바꿈을 제외한 모든 문자를 사용할 수 있습니다 .
true ( 1) 또는 false (빈 문자열)를 인쇄합니다 .

고장

for($n=1+strlen($s=$argv[1])**.5|0; // copy input to $s, $n=size+1 (for the linebreak)
    ($c=$s[$p])&&!(                 // loop through characters
        Q==$c&&                         // if queen: test and increment lines
            $v[$x=$p%$n]++|$h[$x=$p/$n]++|$d[$y-$x]++|$a[$y+$x]++
    );                                  // break if a line had been marked before
    $p++);
echo$n-1==count($a)             // print result: true for $n-1(=size) marks
    &&!$c;                      // and loop has finished

0

파이썬 (3) , 185 (176) 175 172 171 바이트

lambda x,c=lambda x:x.count("Q")==1:all([*map(c,x+[[l[i]for l in x]for i in range(len(x[0]))])])*~any(map(lambda s:"Q%sQ"%(s*".")in"".join(x),[len(x[0]),len(x[0])-2]))==-1

문자열 목록을 입력으로 사용하는 익명 함수

파이썬 2 , 175 바이트

lambda x:all([a.count("Q")==1for a in x]+[[l[i]for l in x].count("Q")==1for i in range(len(x[0]))]+[all(map(lambda s:"Q%sQ"%(s*".")not in"".join(x),[len(x[0]),len(x[0])-2]))])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.