스도쿠 솔루션 생성 CHECKER


21

스도쿠 솔루션 생성 CHECKER

여기 스도쿠 솔버 (Sudoku SOLVERS)가 있지만 인간적으로 가능한 작은 코드 체커 (code-golf) 솔루션을 만들고 싶습니다.

  • 유효한 항목은 9x9 배열을 인수로 사용하거나 (참조에 의해 전달되고, 명령 행에 직렬화되거나 취하려고 함) 최종 그리드에 9 개의 9 행인 입력 파일을 승인 할 수 있습니다. . 아래 입력 예를 참조하십시오.

  • 유효한 입력은 10 진수 (1-9) 여야합니다.

  • 0이 아닌 결과를 반환하거나, 오류를 인쇄하거나, 또는 둘 다를 사용하여 누락되거나 비어 있거나 추가로 숫자가 아닌 위치 또는 숫자가 1-9가 아닌 위치는 유효하지 않은 입력으로 거부되어야합니다.

  • 프로그램은 각 숫자가 열당 한 번, 줄당 한 번, 3x3 하위 표당 한 번 나타나는지 테스트해야합니다. 통과하면 "0"을 반환하고, 그렇지 않으면 0이 아닌 결과를 반환합니다.

  • 외부 자원 (웹 사이트 등)의 사용은 피해야합니다.

  • 솔루션이 독립형 프로그램 인 경우, "Pass"또는 "Fail"에 대해 각각 "0"또는 0이 아닌 종료 상태로 종료하거나 인쇄하는 것이 정상입니다.

가장 작은 답변이 이길 수 있습니다!

입력 예 :

c 배열 :

int input[9][9]={{1,2,3,4,5,6,7,8,9},
                 {4,5,6,7,8,9,1,2,3},
                 {7,8,9,1,2,3,4,5,6},
                 {2,3,1,5,6,4,8,9,7},
                 {5,6,4,8,9,7,2,3,1},
                 {8,9,7,2,3,1,5,6,4},
                 {3,1,2,6,4,5,9,7,8},
                 {6,4,5,9,7,8,3,1,2},
                 {9,7,8,3,1,2,6,4,5}
                };

파일:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

9 개의 하위 그리드 :

+---+---+---+
|123|456|789|
|456|789|123|
|789|123|456|
+---+---+---+
|231|564|897|
|564|897|231|
|897|231|564|
+---+---+---+
|312|645|978|
|645|978|312|
|978|312|645|
+---+---+---+

답변:


5

GolfScript, 39 자

.zip.{3/}%zip{~}%3/{[]*}%++{$10,1>=!},,

배열 배열을 입력으로 사용하고 ( 온라인 예제 참조 ) 0유효한 그리드 인 경우 출력 합니다.

코드에 대한 간단한 설명

.zip         # Copy the input array and transpose it
.{3/}%       # Split each line into 3 blocks
zip{~}%      # Transpose these blocks
3/{[]*}%     # Do the same for the lines themselves and join again
++           # Make one large list of 27 9-element arrays 
             # (9 for rows, 9 for columns, 9 for blocks)
{$10,1>=!},  # From those 27 select the ones which are not a permutation of [1 2 3 ... 9]
             #   $      -> sort
             #   10,1>  -> [1 2 3 ... 9]
             #   =!     -> not equal
,            # Count after filtering

나는 당신의 코드의 0이 아닌 출력이 그냥 1또는 보다 더 의미있는 것을 좋아한다-1
David Wilkins

나는 당신의 대답을 정말로 좋아했지만 결국 골프 스크립트 솔루션을 사용하지 않기로 결정했습니다. 나는 당신이 이해하기를 정말로 희망합니다
David Wilkins

2
@DavidWilkins 사실 이해가 안됩니다-당신은 규칙을 만들었고 (!) GolfScript가 허용되지 않았다고 말하지 않았습니다.
Howard

당신의 요점은 전적으로 유효합니다 ... 사실 나는 당신의 대답을 선택하지 않는 것을 정당화 할 것이 없습니다. 잘 연주
David Wilkins

10

파이썬, 103

나는 스도쿠가 싫어.

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

e=enumerate;print 243-len(set((a,t)for(i,r)in e(b)for(j,t)in e(r)for a in e([i,j,i/3*3+j/3]*(0<t<10))))

작동 방식 : 각 행, 열 및 블록은 1에서 9까지의 각 숫자를 가져야합니다. 따라서 각 0 <= i, j < 9i,j은 block에 3*floor(i/3) + floor(j/3)있습니다. 따라서 충족해야 할 요구 사항은 243 개입니다. 각 요구 사항 을 0에서 8 사이의 숫자 이며, 행, 열 또는 블록을 나타내는 0, 1 또는 2 의 튜플 ((item index,item type number),symbol)로 각각 항목 입니다.item indexitem type numbersymbolb[i][j]

편집 : 실수로 유효한 항목을 확인하지 않았습니다. 이제 해


0솔루션이 아닌 경우 프로그램이 출력되어야합니다True
David Wilkins

@DavidWilkins는 어떤 이상한 요구 사항입니다. 결정된.
부스비

당신은 당신이 당신의 답을 시작한 방식에 대한 표를 얻습니다 : D
Teun Pronk

9

APL (46)

{∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵}

이것은 9x9 행렬을 취합니다. 예제는 다음과 같이 TryAPL에 입력 할 수 있습니다.

     sudoku ← ↑(1 2 3 4 5 6 7 8 9)(4 5 6 7 8 9 1 2 3)(7 8 9 1 2 3 4 5 6)(2 3 1 5 6 4 8 9 7)(5 6 4 8 9 7 2 3 1)(8 9 7 2 3 1 5 6 4)(3 1 2 6 4 5 9 7 8)(6 4 5 9 7 8 3 1 2)(9 7 8 3 1 2 6 4 5)
     {∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵} sudoku
1

설명:

  • ↓⍉⍵:의 열을 얻을 ,
  • ↓⍵:의 행을 얻을 ,
  • 3/3⌿3 3⍴Z←⍳9: 숫자를 포함하는 3x3 행렬을 만듭니다. 19 3x3 만든 다음 각 숫자를 양방향으로 3 번 반복 1하여 9각 그룹 을 나타내는 숫자 가 포함 된 9x9 행렬을 제공합니다 .
  • Z∘.=: 각 번호 19주어진 그룹에 대한 비트 마스크를 만들어,
  • /∘(,⍵)¨: 마스크 와 각각 하여의 그룹을 제공합니다 .
  • ∊∘Z¨: 각 하위 배열에 대해 숫자가 포함되어 있는지 확인하십시오. 19 .
  • ∧/,↑:이 and모든 숫자 의 논리 를 함께 취하십시오 .

+1 니스! 그러나 3 × 3 그룹은 더 골프를 칠 수 있습니다. 예를 들어 이것은 ↓9 9⍴1 3 2⍉3 3 9⍴⍵동일 /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9하지만 상당히 짧습니다. 나는 더 짧은 공식이 있다고 확신합니다.
Tobia

또한 행렬을 1 차원으로 연결하고 마지막에 단일 분할을 수행 할 수 있습니다.↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

버그가 있습니다 :이 코드 ∊∘Z¨는 각 하위 배열 (행, 열 또는 블록)이 1에서 9까지의 숫자로만 구성되어 있는지 테스트합니다. 모든 숫자가 표시되는지 테스트하지는 않습니다. Z∘.∊Z의 모든 숫자가 모든 하위 배열에 포함되어 있는지 테스트하는 것과 같은 작업을 수행해야합니다 .
Tobia

그리고 이것은 ∧/,↑단축 될 수 있습니다 ∧/∊. 다 끝났어요! ;-)
Tobia

매우 콤팩트하지만, 바로 볼 수있는 중요한 포인트를 놓쳤습니다.If it passes, return "0" and if not, return a non-zero result.
David Wilkins

5

Java / C # -183 / 180181 / 178 173/170 바이트

boolean s(int[][]a){int x=0,y,j;int[]u=new int[27];for(;x<(y=9);x++)while(y>0){j=1<<a[x][--y];u[x]|=j;u[y+9]|=j;u[x/3+y/3*3+18]|=j;}for(x=0;x<27;)y+=u[x++];return y==27603;}

(변경 booleanbool C 번호)

형식화 :

boolean s(int[][] a){
    int x=0, y, j;
    int[] u=new int[27];
    for(;x<(y=9);x++)
        while(y>0){
            j=1<<a[x][--y];
            u[x]|=j;
            u[y+9]|=j;
            u[x/3+y/3*3+18]|=j;
        }

    for(x=0;x<27;)
        y+=u[x++];

    return y==27603;
}

이 방법은 배열을 만듭니다 u 는 9 개의 행, 열 및 사각형에있는 숫자를 나타내는 27 비트 마스크 을 .

그런 다음 모든 셀을 반복하여 작업을 수행합니다. 1 << a[x][y] 하여 숫자를 나타내는 비트 마스크를 만들고 해당 열, 행 및 사각형 비트 마스크를 OR하는 비트 마스크를 만드는 을 합니다.

그런 다음 27 비트 마스크를 모두 반복하여 최대 27594까지 추가합니다 (1022 * 9, 1022는 모든 숫자 1-9의 비트 마스크 임). (참고y 이중 루프 다음에 이미 9가 포함되어 있기 때문에 27603으로 끝납니다.)

편집 : 실수로 %3 더 이상 필요하지 않습니다.

편집 2 : Bryce Wagner의 의견에서 영감을 받아 코드가 약간 압축되었습니다.


C # 149 문자에서 거의 동일한 알고리즘 (하지만 Linq가 허용되는 경우에만 해당) : bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y (y> 0) {j = 1 << a [x + 9 *-y]; u [x] | = j; u [y + 9] | = j; u [x / 3 = 9)) + y / 3 * 3 + 18] | = j;} 반환 u.Sum () == 27594;}
브라이스 바그너

@BryceWagner Linq는 실제로 유용합니다. 그러나 내 솔루션은 C #이 나중에 생각할 때 (원래 게시물에서도 언급되지 않았 음) Java의 경우 우선 순위가 낮습니다. 또한 시작하기 전에 압축하기 위해 1 차원 배열을 사용했습니다 (예에서는 2 차원 배열을 사용하므로). 그럼에도 불구하고 코드에서 몇 바이트를 더 줄일 수있는 방법에 대한 아이디어를주었습니다. :)
Smallhacker

3

파이썬 = 196

가장 골프는 아니지만 아이디어가 있습니다. 세트는 매우 유용합니다.

판:

b = [[1,2,3,4,5,6,7,8,9],
     [4,5,6,7,8,9,1,2,3],
     [7,8,9,1,2,3,4,5,6],
     [2,3,1,5,6,4,8,9,7],
     [5,6,4,8,9,7,2,3,1],
     [8,9,7,2,3,1,5,6,4],
     [3,1,2,6,4,5,9,7,8],
     [6,4,5,9,7,8,3,1,2],
     [9,7,8,3,1,2,6,4,5]]

프로그램:

n={1,2,3,4,5,6,7,8,9};z=0
for r in b:
 if set(r)!=n:z=1
for i in zip(*b):
 if set(i)!=n:z=1
for i in (0,3,6):
 for j in (0,3,6):
  k=j+3
  if set(b[i][j:k]+b[i+1][j:k]+b[i+2][j:k])!=n:z=1
print(z)

s / {1,2,3,4,5,6,7,8,9} / set (range (1,10)) / 3자를 저장합니다.
MatrixFrog

Python 3.5에서는을 사용할 수 n={*range(1,10)}있지만 도전보다 새로운 것입니다. 대신 set(range(1,10))MatrixFrog가 말한대로 사용하십시오 .
mbomb007

3

Java- 385306328260 문자

편집 : 나는 대답 완전한 프로그램이어야 한다는 지시를 어리석게 잘못 읽었습니다 . 그것은 유효한 함수 일 수 있기 때문에 함수로 다시 작성하고 최소화했으며 솔루션 소개를 염두에두고 다시 작성했습니다.

따라서 나 자신에게 도전으로 가장 작은 Java 솔루션 검사기를 만들려고한다고 생각했습니다.

이것을 달성하기 위해 스도쿠 퍼즐이 자바 다차원 배열로 전달 될 것이라고 가정합니다.

s(new int[][] {
    {1,2,3,4,5,6,7,8,9},
    {4,5,6,7,8,9,1,2,3},
    {7,8,9,1,2,3,4,5,6},
    {2,3,1,5,6,4,8,9,7},
    {5,6,4,8,9,7,2,3,1},
    {8,9,7,2,3,1,5,6,4},
    {3,1,2,6,4,5,9,7,8},
    {6,4,5,9,7,8,3,1,2},
    {9,7,8,3,1,2,6,4,5}});

그런 다음 유효한 솔버가 있는데, 유효한 솔루션이면 "0", 그렇지 않으면 "1"을 반환합니다.

완전 골프 :

int s(int[][] s){int i=0,j,k=1;long[] f=new long[9];long r=0L,c=r,g=r,z=45L,q=r;for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}for(;i<9;i++){for(j=0;j<9;){k=s[i][j];r+=k*f[i];c+=k*f[j];g+=k*f[j++/3+3*(i/3)];q+=5*f[k-1];}}return (r==z&&c==z&&g==z&&q==z)?0:1;}

읽을 수있는 :

    int s(int[][] s) {
        int i=0,j,k=1;
        long[] f=new long[9]; 
        long r=0L,c=r,g=r,z=45L,q=r;
        for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}
        for(;i<9;i++) {
            for (j=0;j<9;) {
                k=s[i][j];
                r+=k*f[i];
                c+=k*f[j];
                g+=k*f[j++/3+3*(i/3)];
                q+=5*f[k-1];
            }
        }
        return (r==z&&c==z&&g==z&&q==z)?0:1;
    }

어떻게 작동합니까? 나는 기본적으로 각 숫자에서 충분한 해상도로 내 자신의 숫자를 작성합니다. 단지 퍼즐을 한 번 통과 한 후 세 개의 숫자 비교 만하면됩니다. 이 문제에 대해베이스 49를 선택했지만 45보다 큰베이스이면 충분합니다.

(희망스럽게) 분명한 예 : 스도쿠 퍼즐의 모든 "행"은 기본 -49 숫자의 한 자릿수라고 상상해보십시오. 우리는 단순화를 위해 기본 49 숫자의 각 숫자를 벡터에서 기본 10 숫자로 표시합니다. 따라서 모든 행이 "정확한"경우 다음과 같은 base-49 숫자 (base-10 벡터)가 필요합니다.

(45,45,45,45,45,45,45,45,45)

또는 단일 10 진수로 변환 : 1526637748041045

모든 열에 대해 유사한 논리를 따르고 "하위 그리드"에 대해 동일한 논리를 따르십시오. 최종 분석에서이 "이상적인 숫자"와 다른 값은 퍼즐 솔루션이 유효하지 않음을 의미합니다.

모든 5 취약점 및 기타 관련 문제를 해결하기 위해 편집 : 모든 퍼즐에 각 숫자 중 9 개가 있어야한다는 아이디어를 기반으로 네 번째 기본 49 숫자를 추가합니다. 따라서, 나는 숫자의 색인을 나타내는 10 진수의 숫자가 나타날 때마다 49 자리 숫자의 각 숫자에 5를 추가합니다. 예를 들어, 10 9 및 9 8, 9 7, 8 6 및 9가있는 경우 오버플로를 처리하기 위해 10을 기준으로하는 10의 10 벡터로 기본 49 숫자를 얻습니다.

(1, 1, 45, 45, 40, 45, 45, 45, 45, 45)

"이상적인"base-49 숫자와 비교할 때 실패합니다.

내 솔루션은 가능한 한 반복 및 비교를 피하기 위해이 수학 솔루션을 활용합니다. 나는 단순히 long값을 사용하여 각 기수 49 숫자를 기수 10 숫자로 저장하고 조회 배열을 사용하여 열 / 행 / 서브 그리드 체크 값 계산 중에 각 기수 49 자리의 "인자"를 얻습니다.

Java가 간결하게 설계되지 않았기 때문에 수학적 구성에주의를 기울이는 것이 간결한 검사기를 구성 할 수있는 유일한 방법이었습니다.

당신이 무슨 생각을하는지 제게 알려주세요.


1
실제로, 이것은 @ steve-verrill이 언급 한 것과 같은 취약점으로 인해 어려움을 겪습니다. 모두 5 또는 45에 해당하는 숫자 집합이 솔버를 속일 것입니다. 수정하겠습니다. 나는 그것을 이길 방법을 알고있다.
ProgrammerDan

최신 업데이트에서이 취약점을 해결했습니다. 이제 그 사건과 다른 모든 유형의 문제가 해결되었습니다. 기본적으로 각 10 자리 숫자의 "카운트"를 처리하지 않는 것은 심각한 감독이었습니다. 이제 직접 검사를 수행하지만 동일한 수학적 접근 방식 (base-49 숫자)을 사용합니다.
ProgrammerDan

댄, 감사합니다 나는 그것을보고 왜 통보받지 않았는지 궁금했지만, 당신이 내 이름에 대시를 넣는 것을 보았습니다. 이것은 시스템을 혼란스럽게 한 것 같습니다. 단순히 공간을 생략하십시오. 내 이름이 표시되는 방식을 변경하는 것을 고려할 것입니다.
Level River St

아하, 그 설명이 있습니다. 감사합니다 @ steveverrill-여전히 스택 교환 방식에 익숙합니다. 즉, sum-45 원칙에 대한 간결한 착취가 훌륭하게 언급되었습니다. 내 솔루션을 극복하기 위해 더 길게 만들었지 만 인생은 끝났습니다!
ProgrammerDan

3

R 145

function(x)colSums(do.call(rbind,lapply(list(R<-row(b<-matrix(1,9,9)),C<-col(b),(R-1)%/%3+1+3*(C-1)%/%3),sapply,`==`,1:9))%*%c(2^(x-1))==511)==27

디 골프 된 코드 (더 많거나 적은)는 /programming//a/21691541/1201032 에서 찾을 수 있습니다 .


r-fiddle과 같은 사이트에서 실제 예제를 제공 할 수 있습니까? r-fiddle.org/#
David Wilkins

3

하스켈 (Lambdabot), 65 바이트

k x=and$(all$([1..9]==).sort)<$>[x,transpose x,join$chunksOf 3 x]

2

펄, 193 바이트

for(@x=1..9){$i=$_-1;@y=();push@y,$a[$i][$_-1]for@x;@y=sort@y;$r+=@y~~@x;@y=();push@y,$a[3*int($i/3)+$_/3][3*($i%3)+$_%3]for 0..8;@y=sort@y;$r+=@y~~@x}for(@a){@y=sort@$_;$r+=@y~~@x}exit($r!=27)

입력은 배열 형태로 예상됩니다 :

@a=(
    [1,2,3,4,5,6,7,8,9],
    [4,5,6,7,8,9,1,2,3],
    [7,8,9,1,2,3,4,5,6],
    [2,3,1,5,6,4,8,9,7],
    [5,6,4,8,9,7,2,3,1],
    [8,9,7,2,3,1,5,6,4],
    [3,1,2,6,4,5,9,7,8],
    [6,4,5,9,7,8,3,1,2],
    [9,7,8,3,1,2,6,4,5]
);

종료 코드는 0이며 @a솔루션 인 경우 1리턴됩니다.

언 골프 버전 :

@x = (1..9);
for (@x) {
    $i = $_ - 1;
    # columns
    @y = ();
    for (@x) {
        push @y, $a[$i][$_-1];
    }
    @y = sort @y;
    $r += @y ~~ @x;
    # sub arrays
    @y = ();
    for (0..8) {
        push @y, $a[ 3 * int($i / 3) + $_ / 3 ][ 3 * ($i % 3) + $_ % 3 ];
    }
    @y = sort @y;
    $r += @y ~~ @x
}
# rows
for (@a) {
    @y = sort @$_;
    $r += @y ~~ @x
}
exit ($r != 27);

9 개의 행, 9 개의 열 및 9 개의 하위 배열 각각은 정렬 된 배열에 배치되고 배열과 일치하는지 여부를 확인합니다 (1..9). $r유효한 솔루션에 대해 총 27 개까지 합쳐야하는 각 성공적인 일치에 대해 숫자 가 증가합니다.


2

J 52 54

-.*/,(9=#)@~.@,"2(0 3 16 A.i.4)&|:(4#3)($,)".;._2]0 :0

명령 줄에 붙여 넣은 인수를 취합니다.

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
)

전달되면 1을, 그렇지 않으면 0을 리턴합니다.

내부적으로 9x9 그리드를 3x3x3x3 그리드로 변환하고 축에서 몇 가지 순열을 수행하여 마지막 2 차원에서 원하는 단위 (행, 선 및 상자)를 얻습니다.

그런 다음 각 장치에 9 개의 고유 한 값이 있는지 확인합니다.

아마도 완벽과는 거리가 멀지 만 이미 대다수를 능가합니다. ;-)


언뜻보기에, 당신은 다른 사람의 일부와 같은 요구에 의해 체포했습니다 .... 당신의 반환은 실패 0이 아닌, 0 패스 ... 반전한다
데이비드 윌킨스

패스 0은 바보입니다. Boole이 1을 true로, 0을 false로 선택한 이유가 있습니다. 하지만 네 말이 맞아 2자를 추가합니다.
jpjacobs

부울 값이 아닌 종료 상태로 생각하십시오.
David Wilkins

작동하기 때문에 귀하의 답변을 선택하고 있습니다. 당신은 규칙을 따르고 프로그램은 매우 짧습니다. 감사!
David Wilkins

그럼 난 사실 내가 당신보다 짧은 Golfscript의 답을 선택하지 정당화 할 수에서 ... fibbed ...하지만 2 위 대한 칭찬
데이비드 윌킨스

2

매스 매 티카, 84 79 문자

f=Tr[Norm[Sort@#-Range@9]&/@Join[#,Thread@#,Flatten/@Join@@#~Partition~{3,3}]]&

예 :

f[{{1,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

0

f[{{2,1,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]

2

f[{{0,2,3,4,5,6,7,8,9},
   {4,5,6,7,8,9,1,2,3},
   {7,8,9,1,2,3,4,5,6},
   {2,3,1,5,6,4,8,9,7},
   {5,6,4,8,9,7,2,3,1},
   {8,9,7,2,3,1,5,6,4},
   {3,1,2,6,4,5,9,7,8},
   {6,4,5,9,7,8,3,1,2},
   {9,7,8,3,1,2,6,4,5}}]


세 번째 출력 예 : 3항상 유효하지 않은 입력을 나타내거나 때로는 실패한 솔루션에 대한 응답입니까?
David Wilkins

2

자바 스크립트 ES6, 150 자

델리 미터없이 81 자 문자열로 입력을받습니다.

s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))

함수 반환 null 음수 응답과 첫 번째 요소의 원래 문자열이 양수인 배열을 . !!시작하는 기능 에 추가하여 부울로 변경할 수 있습니다 .

테스트 ( 더 자세한 설명 은 관련 챌린지 참조 ) :

f=s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(f)
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !f(s))

그건 우스운 정규 표현식입니다 ... 놀라운 작품입니다.
ETHproductions

2

R, 63 50 바이트

입력 m값이 9x9 행렬로 가정합니다 .

all(apply(m,1,match,x=1:9),apply(m,2,match,x=1:9))

나는 추가 골프가 가능하다는 것이 옳았다.

설명:

    apply(m,1,match,x=1:9),

를 취하고 m각 행에 대해 match함수를 적용하십시오 . x=1:9전달할 추가 인수 를 지정합니다 match. x는 첫 번째 기본 위치 인수이므로 각 행은 두 번째 인수 위치에 배치됩니다 table. 이 함수 matchxin의 인스턴스를 찾습니다 table. 이 경우 1:9각 행에서 1에서 9까지의 숫자를 찾습니다 . 각각의 경우 1:9, 그것은 반환 TRUE(또는 FALSE그 숫자가 발견 (여부) 경우).

따라서 일련의 81 개의 부울 값이 생성됩니다.

                           apply(m,2,match,x=1:9)

입력의 각 열에 대해 위의 과정을 반복하십시오.

all(                                             )

마지막으로 all부울 목록의 모든 요소가 TRUE입니다. 솔루션이 올바른 경우에만 해당됩니다 (즉, 각 숫자 1:9는 각 열과 각 행에 한 번만 나타남).

오래된 접근법 :

for(i in 1:2)F=F+apply(m,i,function(x)sort(x)==1:9);sum(F)==162

각 행을 가져 와서 정렬 한 다음와 비교합니다 [1, 2, ... 9]. 올바른 행이 정확히 일치해야합니다. 그런 다음 각 열에 대해 동일한 작업을 수행합니다. 전체적으로 162 개의 정확한 일치 항목이 있어야합니다. 이는 최종 부분이 확인하는 것입니다. 여기에 추가 골프를 할 수있는 범위가있을 것입니다 ...


열과 행은 확인하지만 상자는 확인하지 않는 것 같습니다.
JayCe

1

하스켈-175

import Data.List
c=concat
m=map
q=[1..9]
w=length.c.m (\x->(x\\q)++(q\\x))
b x=c.m(take 3.drop(3*mod x 3)).take 3.drop(3*div x 3)
v i=sum$m(w)[i,transpose i,[b x i|x<-[0..8]]]

함수 v는 호출하는 것입니다. 목록에 대한 각 행, 열 및 블록의 차이를 가져 와서 해당 차이 목록 [1..9]의 길이를 합산하여 작동합니다.

스도쿠 예제를 사용한 데모 :

*Main> :l so-22443.hs 
[1 of 1] Compiling Main             ( so-22443.hs, interpreted )
Ok, modules loaded: Main.
*Main> v [[1,2,3,4,5,6,7,8,9],[4,5,6,7,8,9,1,2,3],[7,8,9,1,2,3,4,5,6],[2,3,1,5,6,4,8,9,7],[5,6,4,8,9,7,2,3,1],[8,9,7,2,3,1,5,6,4],[3,1,2,6,4,5,9,7,8],[6,4,5,9,7,8,3,1,2],[9,7,8,3,1,2,6,4,5]]
0

1

자바 스크립트-149 자

r=[];c=[];g=[];for(i=9;i;)r[o=--i]=c[i]=g[i]=36;for(x in a)for(y in z=a[x]){r[v=z[y]-1]-=y;c[v]-=x;g[v]-=3*(x/3|0)+y/3|0}for(i in r)o|=r[i]|c[i]|g[i]

배열 a이 존재할 것으로 예상하고 성공에 o대한 출력 변수 를 작성하고 0그렇지 않으면 0이 아닌 변수 를 작성합니다 .

각 행, 열 및 3 * 3 그리드에 대해 각 값이 발생하는 위치의 합이 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8)인지 확인하여 작동합니다.

테스팅

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,4,5]
  ];

'o = 0'제공

a=[
    [1,2,3, 4,5,6, 7,8,9],
    [4,5,6, 7,8,9, 1,2,3],
    [7,8,9, 1,2,3, 4,5,6],

    [2,3,1, 5,6,4, 8,9,7],
    [5,6,4, 8,9,7, 2,3,1],
    [8,9,7, 2,3,1, 5,6,4],

    [3,1,2, 6,4,5, 9,7,8],
    [6,4,5, 9,7,8, 3,1,2],
    [9,7,8, 3,1,2, 6,5,4]
  ];

(마지막 2 자리 교체)

준다 o=-1

a=[
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5]
  ];

준다 o=-284


1

하스켈, 121 (130) 127 바이트 (87 Lambdabot)

import Data.List
import Data.List.Split
c=concat
t=transpose
k=chunksOf
p x=all(==[1..9])$(sort<$>)=<<[x,t x,k 9.c.c.t$k 3<$>x]

사용합니다 :

-- k 9.c.c.t$k 3<$> x = chunksOf 9 $ concat $ concat $ transpose $ map chunksOf 3 x

let ts = k 9$[10*a+b|a<-[1..9],b<-[1..9]] --yep, this is ugly
in k 9.c.c.t$k 3<$>ts
-- prints:
--[[11,12,13,21,22,23,31,32,33],[41,42,43,51,52,53,61,62,63],[71,72,73,81,82,83,91,92,93],[14,15,16,24,25,26,34,35,36],[44,45,46,54,55,56,64,65,66],[74,75,76,84,85,86,94,95,96],[17,18,19,27,28,29,37,38,39],[47,48,49,57,58,59,67,68,69],[77,78,79,87,88,89,97,98,99]]

Lambdabot은 기본적으로 Data.List 및 Data.List.Split을로드합니다 (BlackCap의 솔루션이 확인란을 선택하지 않는다고 생각합니다).

개선을위한 아이디어

// 편집 : 엉망 :)
// 편집 : BlackCap에 의해 3 바이트 저장


당신은 맞습니다, 나는 행과 열을 점검하는 것만으로는 충분하지 않다는 것을 알아 차리지 못했습니다 ..
BlackCap

글쎄, 나도 엉망 :)
michi7x7

1
당신은 대체 할 수 (map sort)(sort<$>)
BlackCap

1
그리고 .c$(sort<$>)<$>$(sort<$>)=<<
BlackCap

오 마이, 그 2 기억
michi7x7


0

클로저, 151 바이트

꽤 길지만 다른 사람들도 마찬가지입니다. 또한 집합의 합집합에는가 필요하므로 성가신 require벡터를 대신 사용했습니다.

각 행과 열을 반복하고 값이 1과 9 사이 인 경우 행, 열 및 3x3 셀에 대해 하나씩 세 개의 벡터를 방출합니다. 성공하면 0을 반환하고 nil그렇지 않으면 두 개의 추가 문자를 사용하면 실패하면 1을 반환 할 수 있습니다. 반환하여 1-9 이외의 숫자를 처리 nil하지만 정수가 아닌 값과 같은 다른 예외에서는 충돌합니다. 몫은 0-2이므로 값을 사용 8하고 9셀 값을 행과 열과 구분 하는 것이 안전합니다 .

(fn[s](if(= 243(count(set(apply concat(for[i(range 9)j(range 9)](let[v(nth(nth s i)j)q #(quot % 3)](if(<= 1 v 9)[[8 v i][9 v j][(q i)(q j)v]])))))))0))

입력은 벡터의 중첩 벡터입니다 (그래서 nth작동합니다).

(def sudoku [[1 2 3 4 5 6 7 8 9]
             [4 5 6 7 8 9 1 2 3] 
             [7 8 9 1 2 3 4 5 6] 
             [2 3 1 5 6 4 8 9 7] 
             [5 6 4 8 9 7 2 3 1] 
             [8 9 7 2 3 1 5 6 4] 
             [3 1 2 6 4 5 9 7 8] 
             [6 4 5 9 7 8 3 1 2] 
             [9 7 8 3 1 2 6 4 5]])

언 골프 드 :

(defn f [s]
  (->> (for [i (range 9) j (range 9)]
         (let [v (-> s (nth i) (nth j)) q #(quot % 3)]
           (if (<= 1 v 9)
             [[:row v i] [:col v j] [:cell [(q i) (q j)] v]])))
    (apply concat)
    set
    count
    (#(if (= 243 %) :pass :fail))))

0

PHP, 196 190 바이트

while($i<9){for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];for(;$k<3;)$c.=substr($a[++$k+$i-$i%3],$i%3*3,3);if(($u=count_chars)($a[++$i],3)<($d=123456789)|$u($b,3)<$d|$u($c,3)<$d)die(1);}

프로그램은 9 개의 개별 명령 행 인수 (그리드의 각 행에 대해 하나의 자릿수 문자열)를 사용합니다.
와 종료1유효하지 않은 경우 (오류)로0 (ok)로 .

로 실행하십시오 php -nr '<code>' <row1> <row2> ....

고장

while($i<9)
{
    for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];  // column to string
    for(;$k++<3;)$c.=substr($a[$i-$i%3+$k],$i%3*3,3);   // sub-grid to string
    if(($u=count_chars)($a[++$i],3)<($d=123456789)      // check row
        |$u($b,3)<$d                                    // check column
        |$u($c,3)<$d                                    // check sub-grid
    )die(1);                                            // test failed: exit with 1
}

설명

count_chars문자열의 문자 수를 계산하고 일반적으로 ASCII 코드를 키로, 문자 수를 값으로 배열을 만듭니다. 하지만 함께3 mode 매개 변수로 문자에서 정렬 된 문자열을 작성합니다. 원하는 숫자의 숫자와 쉽게 비교할 수 있습니다.

비교는 중복 검사뿐만 아니라 유효하지 않은 문자 검사도 포함합니다. 숫자 비교이기 때문에 <, not 만 필요합니다 !=. PHP는 문자열을 가능한 한 숫자로 해석합니다. 123e56789, 0x3456789문자를 정렬되기 때문에 또는 유사한 나타나지 않을 수있다; 숫자가 누락 된 순수한 정수는 123456789... 보다 작습니다 ..23456789 는 물론 .

$a=$argv1 바이트를 $d=123456789저장하고 9를 $u=count_chars저장하고 13을 저장합니다.


-1

C 번호 - 306 298 288 자

다음 콘솔 프로그램을 사용하여 점검 기능을 호출했습니다.

static void Main(string[] args)
    {
        int[,] i={{1,2,3,4,5,6,7,8,9},
             {4,5,6,7,8,9,1,2,3},
             {7,8,9,1,2,3,4,5,6},
             {2,3,1,5,6,4,8,9,7},
             {5,6,4,8,9,7,2,3,1},
             {8,9,7,2,3,1,5,6,4},
             {3,1,2,6,4,5,9,7,8},
             {6,4,5,9,7,8,3,1,2},
             {9,7,8,3,1,2,6,4,5}
            };

            Console.Write(P(i).ToString());
    }

이 모든 것은 배열을 초기화하고 검사 기능 P에 전달하는 것입니다.

점검 기능은 다음과 같습니다 (골프 형태).

private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];for(int p=0;p<9;p++){r[p]=45;c[p]=45;g[p]=45;}for(int y=0;y<9;y++){for(int x=0;x<9;x++){r[y]-=i[x,y];c[x]-=i[x,y];int k=(x/3)+((y/3)*3);g[k]-=i[x,y];}}for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}

또는 완전히 배치 된 형태로;

    private static int P(int[,] i)
    {
        int[] r = new int[9],c = new int[9],g = new int[9];
        for (int p = 0; p < 9; p++)
        {
            r[p] = 45;
            c[p] = 45;
            g[p] = 45;
        }

        for (int y = 0; y < 9; y++)
        {
            for (int x = 0; x < 9; x++)
            {
                r[y] -= i[x, y];

                c[x] -= i[x, y];

                int k = (x / 3) + ((y / 3) * 3);
                g[k] -= i[x, y];
            }
        }

        for (int p = 0; p < 9; p++)
            if (r[p] > 0 | c[p] > 0 | g[p] > 0) return 1;

        return 0;
    }

이것은 모든 열, 행 및 하위 그리드가 45를 더해야한다는 아이디어를 사용합니다. 입력 배열을 통해 작동하며 행, 열 및 하위 그리드에서 각 위치의 값을 뺍니다. 완료되면 행, 열 또는 하위 표에 여전히 값이 없는지 확인합니다.

요청에 따라 배열이 유효한 Sudoku 솔루션 인 경우 0을 반환하고 그렇지 않은 경우 0이 아닌 값을 반환합니다.


private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];대신 사용하여 일부 문자를 저장할 수 있다고 생각합니다 . (닫힌 대괄호 뒤에 공백을 제거하십시오 ].) 또한 확실하지 않지만을 제거 할 수 있다고 생각합니다 private static.
user12205

또한 마지막 부분에서는 C에서 중괄호를 제거 할 수 있습니다. 즉 for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}C #에서 작동하는지 확실하지 않습니다. (실제로 C #을 모른다)
user12205

@ace-귀하의 제안에 따라 몇 가지 기능을 향상 시켰습니다. 이제 298 자로 줄었습니다.
Will

@ace의 의견을 기반으로 10 문자를 추가했습니다.
Will

1
숫자 5로 가득 찬 배열은 어떻게됩니까? 모든 행, 열 및 사각형은 최대 45 개입니다.
Level River St
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.