Quandle Quandary 에피소드 I : 유한 한 Quandle 식별


20

주어진 행렬이 퀀들을 나타내는 지 결정하는 프로그램을 작성하십시오. quandle는 다음 공리를 따르는 단일 (비 - 교환 적, 비 결합) 동작 ◃ 구비 집합이다 :

  • 작업이 닫힙니다. 즉, a◃b = c항상a 과 같은b 집합의 요소이다.
  • 작업은 오른쪽 자체 배포입니다. (a◃b)◃c = (a◃c)◃(b◃c) 입니다..
  • 연산은 옳게 나눌 수 있습니다. a및의 선택된 쌍에 대해 다음 과 같은 b단일 고유 항목 c이 있습니다.c◃a = b
  • 작업은 dem 등원입니다. a◃a = a

유한 양자는 정사각 행렬로 표현 될 수 있습니다. 아래는 order-5 퀀들 ( source )의 예입니다.

0 0 1 1 1
1 1 0 0 0
3 4 2 4 3
4 2 4 3 2
2 3 3 2 4

n 번째 행과 m 번째 열 (0 인덱스)에 위치한 값은 n◃m의 값입니다. 예를 들어이 퀀들에서 4◃1 = 3. 이 행렬에서 일부 퀀들 속성을 쉽게 볼 수 있습니다.

  • 이 5x5 매트릭스에는 값 0-4 만 표시되므로 닫힙니다.
  • 행렬 대각선이 0 1 2 3 4이므로 dem 등원입니다.
  • 중복 값이 ​​포함 된 열이 없으므로 오른쪽으로 나눌 수 있습니다. (행은 가능할 것입니다.)

자기 분포의 속성은 테스트하기가 더 어렵습니다. 지름길이있을 수 있지만 가장 간단한 방법은 세 개의 색인 조합을 반복하여 확인하는 것 m[m[a][b]][c] = m[m[a][c]][m[b][c]]입니다.

입력

입력은 0- 인덱싱 또는 1- 인덱스 (선택)를 사용하여 정사각 행렬의 행 목록이됩니다. 각 엔트리의 단일 자리 숫자 08(또는 1스루 9). 입력 형식이 유연합니다. 허용되는 형식은 다음과 같습니다.

  • 같은 행렬 또는 목록에 대한 귀하의 언어의 가장 자연스러운 형식 [[0 0 0][2 1 1][1 2 2]]또는(0,0,0,2,1,1,1,2,2) .
  • 공백, 줄 바꿈, 쉼표 등으로 구분 된 값 목록
  • 모든 값 이루어진 단일 스트링과 같은, 서로 연접 000211122.

또한 행렬을 입력으로 바꿉니다 (열이있는 행 바꾸기). 답에 이것을 명시하십시오.

산출

행렬의 상태를 퀀들로 나타내는 단일 진리 / 거짓 값입니다.

quandles의 예

0

0 0
1 1

0 0 0
2 1 1
1 2 2

0 0 1 1
1 1 0 0
3 3 2 2
2 2 3 3

0 3 4 1 2
2 1 0 4 3
3 4 2 0 1
4 2 1 3 0
1 0 3 2 4

비 뭉치의 예

닫히지 않은

1

0 0 0
2 1 1
1 9 2

자기 분배가 아닌

0 0 1 0
1 1 0 1
2 3 2 2
3 2 3 3

(3◃1)◃2 = 2◃2 = 2
(3◃2)◃(1◃2) = 3◃0 = 3

옳게 나눌 수없는

0 2 3 4 1
0 1 2 3 4
3 4 2 2 2
3 3 3 3 3
4 1 1 1 4

0 1 2 3
3 1 2 0
3 1 2 3
0 1 2 3

dem 등하 지 않다

1 1 1 1
3 3 3 3
2 2 2 2
0 0 0 0

2 1 0 4 3
3 4 2 0 1
4 2 1 3 0
1 0 3 2 4
0 3 4 1 2

1
"행렬"이라는 단어는 선형 대수와 관련이 없기 때문에 오도의 소지가 있습니다. "테이블"이 더 좋을 것입니다.
피터 테일러

답변:


7

파이썬 (2) , 104 (103) 102 바이트

t=input();e=enumerate
[0%(a==A[a]in B>C[B[a]]==t[C[b]][C[a]])for(a,A)in e(t)for(b,B)in e(t)for C in t]

입력이 바뀝니다. 출력은 종료 코드를 통해 이루어 지므로 0 (성공)은 정확하고 1 (실패)은 거짓입니다.

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

작동 원리

e(t)입력 행렬의 행 열거 반환 t - 오퍼레이터를 나타내는 (인덱스, 행) 쌍으로 . for(a,A)in e(t)예를 들어, 이들을 반복하여 인덱스를 a에 저장 하고 행 자체를 A 에 저장하므로에 A대한 바로 가기가됩니다 t[a].

전자 for(b,B)in e(t)for C in t , , 우리 는 데카르트 힘 t 3 에서 가능한 모든 정렬 된 튜플 (a, b, c) 을 반복합니다 .

이 튜플 각각에 대해 표현을 평가합니다

0%(a==A[a]in B>C[B[a]]==t[C[b]][C[a]])

다음 개별 비교 중 하나 이상이 동일한 경우에만 괄호로 묶인 부울 값은 False 입니다.

  • a==A[a]실패합니다 (일부 값의 경우somedem 등원 이 아닌 경우 ) 합니다.

  • A[a]in B 만약에 실패하면 BA의 모든 인덱스가 포함되어 있지 않으면 .

    이후 A를 갖는 N 인덱스와 B를 갖는 N 소자의 소자 것이 아닌 실패 수단 B가 의 인덱스와 일치 정도, 닫히고 오른쪽 나누어.

  • B>C[B[a]] 파이썬 2는 반복 가능한 것보다 "작은"숫자를 고려했기 때문에 팽창 학입니다.

  • C[B[a]]==t[C[b]][C[a]]◃ 인 경우 일부 값에 실패합니다 가 자기 자신을 배분하지 않으면 입니다.

비교 식 중 하나를 반환하면 거짓 , 표현은 (0%...)던져 것 ZeroDivisionError를 . 또한 가 닫히지 A[a]않거나 IndexErrorC[b] 가 발생할 수도 있습니다 . 두 경우 모두 상태 코드 1 (실패)로 프로그램이 종료됩니다 .

모든 테스트가 통과되면 프로그램은 상태 코드 0 (성공) 으로 정상적으로 종료됩니다 .


6

하스켈, 100 바이트

이 답변은 바뀐 입력을 사용 합니다.

q m=and$(elem<$>v<*>m)++[a#a==a&&a#b#c==a#c#(b#c)|a<-v,b<-v,c<-v]where v=[0..length m-1];i#j=m!!j!!i

패턴 가드를 사용하여 삽입 연산자를 바인딩 할 수없는 것처럼 보이 므로이 where경우에 사용 하고 있습니다.

(첫 번째 버전은 108 바이트 였지만 dem 등성 테스트를 놓 쳤고 고정 버전은 120 바이트 였고 이후 버전은 108, 103 및 98 바이트 였지만 @nimi 덕분에 모두 잘못되었다는 것을 깨달아야했습니다. 물론 올바른 작업을 수행해야합니다. 위험한 !!작업을 수행하기 전에 분열 테스트 (폐쇄를 암시 함)를 사용하지만 나중에 골프 아이디어를 대부분 사용할 수 있으며 102 바이트로 피연산자 순서를 변경하여 개선되었습니다 #(어쨌든 보상하는 것이 좋습니다) 왼쪽으로의 연관성을 더 잘 활용하기 위해)

다음과 같이 사용하십시오.

*Main> q [[0,1,2,3],[0,1,3,2],[1,0,2,3],[0,1,2,3]]
False


4

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

a=>!(a.some((b,i)=>b[i]-i)|a.some(b=>[...new Set(b)].sort()+''!=[...b.keys()])||a.some((_,i)=>a.some((_,j)=>a.some((b,k)=>b[a[j][i]]-a[b[j]][b[i]]))))

입력을 정수 열 배열의 배열로 취합니다.


3

수학, 122 바이트

(n_±m_:=#[[m,n]];#&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]&&And@@Flatten@Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}])&

행과 열은 해당 규칙에서 반전 및 재와 정수의 2D 배열 복용 순수 함수의 입력으로서 (1 인덱싱) True또는 False. 첫 번째 줄은 이진 삽입 작업 n_±m_을 퀀들 작업으로 정의합니다 .

들어 lX의 l배열 폐쇄 및 오른쪽 나누어 일부 치환되는 (제 경우) 각 행에 해당 {1, ..., l}하고, 멱등 정확하게 주 대각선 것에 상당 {1, ..., l}. 따라서이 #&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]세 가지 조건을 감지합니다. ( Sort/@#여기에서 행과 열을 바꾸도록 선택했습니다.)

올바른 분포를 위해 문자 그대로를 사용하여 모든 가능성을 확인합니다 Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}]). ( ±##2±#자동으로 확장됩니다(#2±#3)±###2 배열되는 3 변수 순수 함수에 대한 두 번째 및 세 번째 인수의 시퀀스를 나타내 므로 .) 그런 다음 &&And@@Flatten@모든 단일 테스트가 통과되었는지 확인합니다. 닫히지 않은 퀀들의 경우 존재하지 않는 행렬의 일부에 액세스하려고 할 때 오류가 발생할 수 있지만 정답은 여전히 ​​반환됩니다.


±m__:=#[[m]];내 생각에 그리고 Diagonal내장되어 있습니다. 그리고 ±당신이 사용할 수 있도록 연관-남아 #2±#±(#3±#)있지만, 그때 실수를하지 않은 경우는 재 할당 짧다 ##3하고 할 #±#2±#3==#±#3±±##2&. 그리고 전체 Flatten@부품을 다음과 같이 교체 할 수도 있습니다.(...&~Array~{l,l,l}<>"")
Martin Ender

나는 그것을 먼저 평가해야하기 때문에 l=Length안으로 들어가야 하는지 궁금합니다 Range@l. 따라서 함수를 반복적으로 사용하면 Range여전히 이전을 얻습니다 l.
Martin Ender

0

C ++ 14, 175 바이트

이름이없는 람다로, 참조 매개 변수를 통해 n같다고 가정 합니다 std::vector<std::vector<int>>. 0은 거짓이며 다른 모든 것은 사실입니다.

#define F(x);for(x=-1;++x<s;){
[](auto m,int&r){int s=r=m.size(),a,b,c F(a)auto A=m[a];r*=s==A.size()&&A[a]==a;int u=0 F(b)u|=1<<m[b][a];r*=A[b]<s F(c)r*=m[A[b]][c]==m[A[c]][m[b][c]];}}r*=!(u-(1<<s)+1);}}

언 골프 및 사용법 :

#include<vector>
#include<iostream>

auto f=
#define F(x);for(x=-1;++x<s;){
[](auto m,int&r){
 int s=r=m.size(),a,b,c
 F(a)
  auto A=m[a];               //shortcut for this row
  r*=s==A.size()&&A[a]==a;   //square and idempotet
  int u=0                    //bitset for uniqueness in col
  F(b)
   u|=1<<m[b][a];            //count this item
   r*=A[b]<s                 //closed
   F(c)
    r*=m[A[b]][c]==m[A[c]][m[b][c]];
   }
  }
  r*=!(u-(1<<s)+1);          //check right-divisibility
 }
}
;

int main(){
 int r;
 std::vector<std::vector<int>>
  A = {
   {0, 0, 1, 1},
   {1, 1, 0, 0},
   {3, 3, 2, 2},
   {2, 2, 3, 3},
  },
  B = {
   {0, 2, 3, 4, 1},
   {0, 1, 2, 3, 4},
   {3, 4, 2, 2, 2},
   {3, 3, 3, 3, 3},
   {4, 1, 1, 1, 4},
  };
 f(A,r);
 std::cout << r << "\n";
 f(B,r);
 std::cout << r << "\n";
}

제안 int a,b,c,u,s=r=m.size()F대신 int s=r=m.size(),a,b,c F, u=0;r*=s==A.size()&&a==A[a]F대신 r*=s==A.size()&&A[a]==a;int u=0 F, r*=s>A[b]F대신 r*=A[b]<s F~u+(1<<s)대신u-(1<<s)+1
ceilingcat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.