Quandle Quandary Episode I: การระบุ Quandles จำกัด


20

เขียนโปรแกรมที่จะตรวจสอบว่าเมทริกซ์ที่กำหนดแสดงถึงความไม่แน่ใจ quandleเป็นชุดพร้อมเดียว (ไม่ใช่การสลับที่ไม่เชื่อมโยง) การดำเนินงาน◃ซึ่งเชื่อฟังหลักการต่อไปนี้:

  • การดำเนินการถูกปิดซึ่งหมายความว่าa◃b = cจะเป็นองค์ประกอบของชุดหากaและbเป็นองค์ประกอบของชุดเสมอ
  • (a◃b)◃c = (a◃c)◃(b◃c)การดำเนินการเป็นขวาตนเองจำหน่าย:
  • การดำเนินการแบ่งออกได้อย่างถูกต้อง: สำหรับคู่ที่เลือกaและbมีความเป็นหนึ่งเดียวcที่c◃a = b
  • การดำเนินการ idempotent: a◃a = a

quandle ที่ จำกัด สามารถแสดงเป็นเมทริกซ์จตุรัส ด้านล่างนี้เป็นตัวอย่างของการสั่งซื้อ 5-quandle ( แหล่งที่มา )

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-th และคอลัมน์ m-th (ดัชนี 0) คือค่าของ n ofm ตัวอย่างเช่นในความเข้าใจนี้, 4◃1 = 3. บางส่วนของคุณสมบัติที่เข้าใจได้ง่ายจากเมทริกซ์นี้:

  • มันถูกปิดเพราะมีเพียงค่า 0-4 เท่านั้นที่ปรากฏในเมทริกซ์ 5x5 นี้
  • มันเป็น idempotent เพราะเมทริกซ์ทแยงมุมคือ 0 1 2 3 4
  • มันหารด้วยขวาเพราะไม่มีคอลัมน์ที่มีค่าซ้ำกัน (แถวสามารถและมักจะ)

คุณสมบัติของการกระจายตัวที่ถูกต้องนั้นยากที่จะทดสอบ อาจจะมีทางลัด m[m[a][b]][c] = m[m[a][c]][m[b][c]]แต่วิธีที่ง่ายที่สุดคือการย้ำกว่าแต่ละชุดเป็นไปได้ของสามดัชนีเพื่อตรวจสอบว่า

อินพุต

อินพุตจะเป็นรายการของแถวของเมทริกซ์จตุรัสโดยใช้ดัชนี 0 หรือดัชนี 1 รายการ (ตัวเลือกของคุณ) แต่ละรายการจะเป็นตัวเลขหลักเดียวจาก0ถึง8(หรือ1ผ่าน9) ฉันจะมีความยืดหยุ่นในรูปแบบการป้อนข้อมูล บางรูปแบบที่ยอมรับ ได้แก่ :

  • ภาษาของคุณการจัดรูปแบบเป็นธรรมชาติมากที่สุดสำหรับการฝึกอบรมหรือรายการเช่นหรือ[[0 0 0][2 1 1][1 2 2]](0,0,0,2,1,1,1,2,2)
  • รายการค่าคั่นด้วยช่องว่าง, การขึ้นบรรทัดใหม่, จุลภาค ฯลฯ
  • 000211122สายเดียวประกอบด้วยค่าทั้งหมดตัดแบ่งกันเช่น

คุณยังได้รับอนุญาตให้นำทรานสดิวเซอร์ของเมทริกซ์เป็นอินพุต (สลับแถวกับคอลัมน์) เพียงให้แน่ใจว่าได้ระบุสิ่งนี้ไว้ในคำตอบของคุณ

เอาท์พุต

ค่าความจริง / ค่าเท็จหนึ่งค่าที่ระบุสถานะของเมทริกซ์ว่าเป็นค่าที่ไม่แน่นอน

ตัวอย่างของความไม่แน่ใจ

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

ไม่ใช่ idempotent

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
คำว่า "เมทริกซ์" นั้นทำให้เข้าใจผิดเพราะนี่ไม่เกี่ยวอะไรกับพีชคณิตเชิงเส้น "ตาราง" น่าจะดีกว่า (หรืออาจจะเป็น "โต๊ะ Cayley" แต่ฉันคิดว่ามันเหมาะสมสำหรับกลุ่มเท่านั้น)
Peter Taylor

คำตอบ:


7

Python 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)เช่น iterates เหล่านี้มากกว่าการจัดเก็บดัชนีในและแถวตัวเองในจึงกลายเป็นทางลัดสำหรับAt[a]

ระหว่างอดีตfor(b,B)in e(t)และfor C in tเราย้ำกว่า tuples เป็นไปได้ทั้งหมดได้รับคำสั่ง(A, B, C)ในอำนาจคาร์ทีเซียนที 3

สำหรับสิ่งอันดับแต่ละสิ่งเราประเมินการแสดงออก

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

ค่าของบูลีนที่เป็นวงเล็บนั้นเป็นเท็จถ้าหากว่าการเปรียบเทียบแต่ละข้อต่อไปนี้หนึ่งข้อหรือมากกว่านั้นทำเช่นเดียวกัน

  • a==A[a]จะล้มเหลว (สำหรับค่าa ) iff ไม่ใช่ idempotent

  • A[a]in Bจะล้มเหลวถ้าBไม่ได้มีดัชนีทั้งหมดของ

    เนื่องจากAมีnดัชนีและBมีองค์ประกอบnไม่ใช่ความล้มเหลวหมายความว่าองค์ประกอบของBตรงกับดัชนีของAดังนั้นจึงปิดและหารด้วยขวา

  • B>C[B[a]] เป็นสิ่งที่ซ้ำซากเนื่องจาก Python 2 ถือว่าตัวเลข "เล็กลง" กว่า iterables

  • C[B[a]]==t[C[b]][C[a]]จะล้มเหลวสำหรับค่าบางอย่างถ้าไม่ใช่การกระจายตัวเองอย่างถูกต้อง

หากหนึ่งในการเปรียบเทียบใด ๆ ที่จะส่งกลับเท็จ , การแสดงออก(0%...)จะโยนZeroDivisionError นอกจากนี้ถ้าไม่ได้ปิดA[a]หรือC[b]อาจโยนIndexError ในทั้งสองกรณีโปรแกรมออกจากด้วยรหัสสถานะ1 (ความล้มเหลว)

หากการทดสอบทั้งหมดผ่านไปโปรแกรมจะออกตามปกติด้วยรหัสสถานะ0 (สำเร็จ)


6

Haskell, 100 ไบต์

คำตอบนี้ใช้อินพุตtransposed

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 ไบต์ แต่พลาดการทดสอบ idempotency รุ่นคงที่คือ 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

JavaScript (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

Mathematica, 122 ไบต์

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

ฟังก์ชั่นการถ่ายเพียวอาร์เรย์ 2 มิติของจำนวนเต็ม (1 จัดทำดัชนี) เป็น input ด้วยแถวและคอลัมน์ย้อนกลับจากการประชุมในคำถามและกลับมาหรือTrue Falseบรรทัดแรกกำหนดการดำเนินการ infix แบบไบนารีเป็นการดำเนินn_±m_การแบบ quandle

สำหรับlx lอาร์เรย์ปิดและขวาหารเทียบเท่ากับทุกแถว (ในกรณีของฉัน) มีการเปลี่ยนแปลงบางอย่าง{1, ..., l}และ idempotent {1, ..., l}เทียบเท่ากับเป็นเส้นทแยงมุมหลักว่า ดังนั้น#&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]ตรวจจับเงื่อนไขทั้งสามนี้ (การใช้Sort/@#ที่นี่คือเหตุผลที่ฉันเลือกสลับแถวและคอลัมน์)

Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}])สำหรับขวาจำหน่ายเราอย่างแท้จริงเพื่อดูการใช้ (โปรดสังเกตว่า±##2±#ขยายโดยอัตโนมัติ(#2±#3)±#เนื่องจาก##2แสดงลำดับของอาร์กิวเมนต์ที่สองและสามไปยังฟังก์ชันบริสุทธิ์สามตัวแปรที่มีการจัดเรียงไว้) จากนั้น&&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);}}

Ungolfed และการใช้งาน:

#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.