Quandle Quandary Tập I: Xác định các quand hữu hạn


20

Viết chương trình sẽ xác định xem một ma trận đã cho có biểu thị một quandle không. Một quandle là một bộ được trang bị một hoạt động (không giao hoán, không liên kết) tuân theo các tiên đề sau:

  • Thao tác được đóng, nghĩa a◃b = clà luôn luôn là một phần tử của tập hợp nếu ablà các phần tử của tập hợp.
  • Các hoạt động là tự phân phối phải : (a◃b)◃c = (a◃c)◃(b◃c).
  • Hoạt động là chia đúng: Đối với bất kỳ cặp nào được chọn ab, có một duy nhất cnhư vậyc◃a = b
  • Các hoạt động là idempotent: a◃a = a

Một quandle hữu hạn có thể được biểu diễn dưới dạng ma trận vuông. Dưới đây là một ví dụ về một quandle thứ tự 5 ( nguồn ).

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

Giá trị nằm ở hàng thứ n và cột m-th (được lập chỉ mục 0) là giá trị của n◃m. Ví dụ, trong quandle này , 4◃1 = 3. Một số thuộc tính quandle rất dễ nhìn thấy từ ma trận này:

  • Nó bị đóng vì chỉ các giá trị 0-4 xuất hiện trong ma trận 5x5 này.
  • Đó là idempotent vì đường chéo ma trận là 0 1 2 3 4
  • Nó là chia đúng vì không có cột nào chứa bất kỳ giá trị trùng lặp nào. (Các hàng có thể, và thường sẽ.)

Tài sản của quyền tự phân phối khó kiểm tra hơn. Có thể có một phím tắt, nhưng phương pháp đơn giản nhất là lặp lại qua từng kết hợp có thể có của ba chỉ mục để xác minh điều đó m[m[a][b]][c] = m[m[a][c]][m[b][c]].

Đầu vào

Đầu vào sẽ là danh sách các hàng của ma trận vuông, sử dụng chỉ mục 0 hoặc chỉ mục 1 (lựa chọn của bạn). Mỗi mục sẽ là một số có một chữ số từ 0đến 8(hoặc 1thông qua 9). Tôi sẽ linh hoạt về định dạng đầu vào. Một số định dạng có thể chấp nhận bao gồm:

  • Định dạng tự nhiên nhất của ngôn ngữ của bạn cho ma trận hoặc danh sách, chẳng hạn như [[0 0 0][2 1 1][1 2 2]]hoặc (0,0,0,2,1,1,1,2,2).
  • Danh sách các giá trị được phân định bởi khoảng trắng, dòng mới, dấu phẩy, v.v.
  • Một chuỗi duy nhất bao gồm tất cả các giá trị được nối với nhau, chẳng hạn như 000211122.

Bạn cũng được phép lấy chuyển vị của ma trận làm đầu vào (hoán đổi các hàng với các cột). Chỉ cần chắc chắn để nói điều này trong câu trả lời của bạn.

Đầu ra

Một giá trị trung thực / falsey duy nhất cho biết trạng thái của ma trận là một quandle.

Ví dụ về 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

Ví dụ về không quandles

không đóng cửa

1

0 0 0
2 1 1
1 9 2

không tự phân phối

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

không chia đúng

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

không bình thường

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
Từ "ma trận" là sai lệch, bởi vì điều này không liên quan gì đến đại số tuyến tính. "Bảng" sẽ tốt hơn (hoặc có thể là "Bảng Cayley", nhưng tôi nghĩ rằng điều đó chỉ phù hợp với một nhóm).
Peter Taylor

Câu trả lời:


7

Python 2 , 104 103 102 byte

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]

Đầu vào được hoán vị. Đầu ra là thông qua mã thoát, vì vậy 0 (thành công) là trung thực và 1 (thất bại) là sai.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

e(t)trả về các hàng được liệt kê của ma trận đầu vào t - đại diện cho các cặp toán tử - như (chỉ mục, hàng). for(a,A)in e(t), ví dụ, lặp đi lặp lại những điều này, lưu trữ chỉ mục trong một và chính hàng trong A , do đó Atrở thành một lối tắt cho t[a].

Giữa cái trước, for(b,B)in e(t)for C in t, chúng ta lặp đi lặp lại tất cả các bộ dữ liệu có thể có (a, b, c) trong sức mạnh của Cartesian t 3 .

Đối với mỗi bộ dữ liệu này, chúng tôi đánh giá biểu thức

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

Giá trị của Boolean được ngoặc đơn là Sai khi và chỉ khi một hoặc nhiều phép so sánh riêng lẻ sau đây làm tương tự.

  • a==A[a]sẽ thất bại (đối với một số giá trị của a ) iff không phải là idempotent.

  • A[a]in Bsẽ thất bại nếu B không chứa tất cả các chỉ số của A .

    An chỉ số và Bn yếu tố, phương tiện không thất bại mà các phần tử của B phù hợp với các chỉ số của A , vì vậy được đóng lại và phải chia hết cho.

  • B>C[B[a]] là một tautology, vì Python 2 coi các số "nhỏ hơn" các lần lặp.

  • C[B[a]]==t[C[b]][C[a]]sẽ thất bại đối với một số giá trị nếu không phải là phải tự phân phối.

Nếu bất kỳ một trong các phép so sánh trả về Sai , biểu thức (0%...)sẽ đưa ra một ZeroDivisionError . Ngoài ra, nếu không bị đóng A[a]hoặc C[b]cũng có thể ném một IndexError . Trong cả hai trường hợp, chương trình thoát với mã trạng thái 1 (thất bại).

Nếu tất cả các thử nghiệm được thông qua, chương trình sẽ thoát bình thường với mã trạng thái 0 (thành công).


6

Haskell, 100 byte

Câu trả lời này sử dụng chuyển đầu vào .

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

Có vẻ như tôi không thể sử dụng một trình bảo vệ mẫu để liên kết một toán tử infix, vì vậy tôi đang sử dụng where trong trường hợp này.

. kiểm tra khả năng phân chia (ngụ ý đóng cửa) trước khi thực hiện bất kỳ nguy hiểm !! thao tác , nhưng tôi vẫn có thể sử dụng hầu hết các ý tưởng chơi gôn sau này của mình và với một ý tưởng nữa, đó là 102 byte, giờ đã được cải thiện bằng cách thay đổi thứ tự toán hạng #(dù sao cũng đẹp hơn để bù lại hoán vị) để sử dụng tốt hơn liên kết của nó ở bên trái)

Sử dụng như thế này:

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

4

Python 2 , 138 byte

def f(m):R=range(len(m));return all(m[i][i]==i<set(zip(*m)[i])==set(R)>m[m[j][k]][i]==m[m[j][i]][m[k][i]]for i in R for j in R for k in R)

m là danh sách các số nguyên.

Hãy thử trực tuyến!


4

JavaScript (ES6), 150 byte

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]]))))

Lấy đầu vào là một mảng các mảng số nguyên.


3

Toán học, 122 byte

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

Hàm thuần túy lấy một mảng số nguyên 2D (được lập chỉ mục 1) làm đầu vào, với các hàng và cột được đảo ngược so với quy ước trong câu hỏi và trả về Truehoặc False. Dòng đầu tiên định nghĩa hoạt động nhị phân nhị phân n_±m_là hoạt động quandle.

Đối với một mảng lx l, đóng và chia phải tương đương với mỗi hàng (trong trường hợp của tôi) là một số hoán vị {1, ..., l}và idempotent tương đương với đường chéo chính là chính xác {1, ..., l}. Vì vậy, #&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]phát hiện cho ba điều kiện. (Việc sử dụng Sort/@#ở đây là lý do tại sao tôi chọn trao đổi hàng và cột.)

Đối với phân phối đúng, chúng tôi thực sự kiểm tra tất cả các khả năng sử dụng Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}]). (Lưu ý rằng ±##2±#tự động mở rộng thành (#2±#3)±#, vì ##2đại diện cho chuỗi các đối số thứ hai và thứ ba cho hàm thuần ba biến được sắp xếp theo mảng.) Sau đó &&And@@Flatten@kiểm tra xem mọi thử nghiệm đơn lẻ đã được thông qua chưa. Đối với một số quandles không đóng, lỗi có thể được đưa ra khi nó cố truy cập vào một phần của ma trận không tồn tại, nhưng câu trả lời đúng vẫn được trả về.


±m__:=#[[m]];Tôi nghĩ. Và có tích Diagonalhợp sẵn. Và ±được trái kết hợp, do đó bạn có thể sử dụng #2±#±(#3±#), nhưng nếu tôi không làm cho một sai lầm sau đó nó ngắn hơn để phân công lại #đến #3và làm #±#2±#3==#±#3±±##2&. Và nó cũng có thể thay thế toàn bộ Flatten@phần bằng(...&~Array~{l,l,l}<>"")
Martin Ender

Tôi tự hỏi nếu bạn phải chuyển l=Lengthvào Range@lmặc dù bởi vì cái đó nên được đánh giá đầu tiên, vì vậy nếu bạn sử dụng chức năng nhiều lần, tôi nghĩ Rangevẫn nhận được trước đó l, phải không?
Martin Ender

0

C ++ 14, 175 byte

Như lambda chưa được đặt tên, giả sử nlà giống std::vector<std::vector<int>>và trở lại thông qua tham số tham chiếu. 0 là sai, mọi thứ khác đều đúng.

#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);}}

Ungolfed và cách sử dụng:

#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";
}

Đề xuất int a,b,c,u,s=r=m.size()Fthay vì int s=r=m.size(),a,b,c F, u=0;r*=s==A.size()&&a==A[a]Fthay vì r*=s==A.size()&&A[a]==a;int u=0 F, r*=s>A[b]Fthay vì r*=A[b]<s F~u+(1<<s)thay vìu-(1<<s)+1
trần
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.