Quandle Quandary I серія: Ідентифікація кінцевих Quandles


20

Напишіть програму, яка визначить, чи дана матриця являє собою квадрати. Quandle являє собою набір оснащений однією (некомутативними, неассоціатівное) операціями ◃ , яка задовольняє наступні аксіоми:

  • Операція закрита, тобто a◃b = cзавжди є елементом множини, якщо aі bє елементами безлічі.
  • Операція правої самостійно дистрибутивний: (a◃b)◃c = (a◃c)◃(b◃c).
  • Операція розділена справа: для будь-якої обраної пари aта b, є один унікальний cтакийc◃a = b
  • Операція ідентична: a◃a = a

Кінцевий квадратик може бути представлений у вигляді квадратної матриці. Нижче наводиться приклад набору замовлення-5 ( джерело ).

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. Наприклад, в цьому quandle, 4◃1 = 3. Деякі властивості quandle легко помітити з цієї матриці:

  • Він закритий, оскільки у цій матриці 5x5 відображаються лише значення 0-4.
  • Це ідентично, оскільки діагональ матриці дорівнює 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.

Вам також дозволено приймати транспортування матриці як вхідний (обмін рядками зі стовпцями). Просто не забудьте вказати це у своїй відповіді.

Вихідні дані

Єдине значення truthy / falsey, що вказує на статус матриці як квадрату.

Приклади квандлів

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

не ідентичний

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

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), наприклад, повторює їх, зберігаючи індекс у a і сам рядок у A , тому Aстає ярликом для t[a].

Між колишнім for(b,B)in e(t)і for C in t, ми повторюємо всі можливі впорядковані кортежі (a, b, c) в декартовій силі t 3 .

Для кожного з цих кортезів ми оцінюємо вираз

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

Значення в круглих дужках булевих помилок є хибним, якщо і лише в тому випадку, якщо одне або декілька з наведених нижче порівнянь здійснюють те саме.

  • a==A[a]не вдасться (для деякого значення a ) iff не є ідентичним .

  • A[a]in Bзазнає невдачі , якщо B не містить всі показники А .

    Оскільки A має n індексів і B має n елементів, невідмова означає, що елементи B відповідають індексам A , тому закритий і ділиться справа.

  • B>C[B[a]] є тавтологією, оскільки Python 2 вважав числа "меншими", ніж ітерабелі.

  • C[B[a]]==t[C[b]][C[a]]буде невдалим для деякого значення, якщо неправильно-саморозподілити.

Якщо будь-яке зі порівнянь поверне помилкове , вираз (0%...)буде кидати ZeroDivisionError . Крім того, якщо не закрито A[a]або C[b]також може викинути IndexError . В обох випадках програма виходить із кодом статусу 1 (збій).

Якщо всі тести пройшли, програма нормально вийде з кодом статусу 0 (успіх).


6

Haskell, 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 байт, але пропущена перевірка ідентичності, фіксована версія - 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

Математика, 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_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}<>"")
Мартін Ендер

Цікаво, чи потрібно вам переходити l=Lengthна Range@lхоч, тому що це слід оцінити спочатку, тож якщо ви використовуєте цю функцію неодноразово, я думаю, Rangeвсе одно отримує попередню l, ні?
Мартін Ендер

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
roofcat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.