Écrivez un programme qui déterminera si une matrice donnée représente un dilemme. Un quandle est un ensemble équipé d'une seule opération (non commutative, non associative) ◃ qui obéit aux axiomes suivants:
- L'opération est fermée, ce qui signifie que
a◃b = c
c'est toujours un élément de l'ensemble sia
etb
sont des éléments de l'ensemble. - L'opération est droit auto-distributive:
(a◃b)◃c = (a◃c)◃(b◃c)
. - L'opération est divisible à droite: pour toute paire choisie de
a
etb
, il existe un unique uniquec
tel quec◃a = b
- L'opération est idempotente:
a◃a = a
Un quandle fini peut être représenté comme une matrice carrée. Ci-dessous, un exemple de quandle d'ordre 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
La valeur située à la nième ligne et à la mième colonne (indexée 0) est la valeur de n◃m. Par exemple, dans ce quandle, 4◃1 = 3
. Certaines des propriétés quandle sont faciles à voir dans cette matrice:
- Il est fermé car seules les valeurs 0-4 apparaissent dans cette matrice 5x5.
- Elle est idempotente car la diagonale de la matrice est 0 1 2 3 4
- Il est divisible à droite car aucune colonne ne contient de valeurs en double. (Les rangées le peuvent et le seront généralement.)
La propriété de l'auto-distributivité droite est plus difficile à tester. Il peut y avoir un raccourci, mais la méthode la plus simple consiste à parcourir chaque combinaison possible de trois index pour le vérifier m[m[a][b]][c] = m[m[a][c]][m[b][c]]
.
Contribution
L'entrée sera la liste des lignes d'une matrice carrée, en utilisant soit l'indexation 0 soit l'index 1 (votre choix). Chaque entrée sera un numéro à un chiffre de 0
à 8
(ou à 1
travers 9
). Je serai flexible sur le format d'entrée. Certains formats acceptables comprennent:
- Formatage le plus naturel de votre langue pour les matrices ou les listes, comme
[[0 0 0][2 1 1][1 2 2]]
ou(0,0,0,2,1,1,1,2,2)
. - La liste des valeurs délimitées par des espaces, des sauts de ligne, des virgules, etc.
- Une chaîne unique composée de toutes les valeurs concaténées, telles que
000211122
.
Vous êtes également autorisé à prendre la transposition de la matrice en entrée (échange de lignes avec des colonnes). Assurez-vous simplement de l'indiquer dans votre réponse.
Production
Une seule valeur vérité / falsey indiquant l'état de la matrice comme un dilemme.
Exemples de dilemmes
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
Exemples de non-quandles
pas fermé
1
0 0 0
2 1 1
1 9 2
pas d'auto-distribution à droite
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
non divisible à droite
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
pas 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
Réponses:
Python 2 ,
104103102 102 octetsL'entrée est transposée. La sortie se fait via le code de sortie, donc 0 (succès) est vrai et 1 (échec) est faux.
Essayez-le en ligne!
Comment ça fonctionne
e(t)
renvoie les lignes énumérées de la matrice d'entrée t - qui représente un opérateur ◃ - sous forme de paires (index, ligne).for(a,A)in e(t)
, par exemple, itère sur ceux-ci, stockant l'index dans a et la ligne elle-même dans A ,A
devient ainsi un raccourci pourt[a]
.Entre les premiers ,,
for(b,B)in e(t)
etfor C in t
, nous itérons sur tous les tuples ordonnés possibles (a, b, c) dans la puissance cartésienne t 3 .Pour chacun de ces tuples, nous évaluons l'expression
La valeur du booléen entre parenthèses est False si et seulement si une ou plusieurs des comparaisons individuelles suivantes font de même.
a==A[a]
échouera (pour une valeur de a ) si ◃ n'est pas idempotent.A[a]in B
échouera si B ne contient pas tous les indices de A .Puisque A a n indices et B a n éléments, la non-défaillance signifie que les éléments de B correspondent aux indices de A , donc ◃ est fermé et divisible à droite.
B>C[B[a]]
est une tautologie, car Python 2 considérait les nombres "plus petits" que les itérables.C[B[a]]==t[C[b]][C[a]]
échouera pour une certaine valeur si ◃ n'est pas auto-distributif à droite.Si l'une des comparaisons renvoie False , l'expression lèvera
(0%...)
une ZeroDivisionError . De plus, si ◃ n'est pas ferméA[a]
ouC[b]
peut également déclencher une IndexError . Dans les deux cas, le programme se ferme avec le code d'état 1 (échec).Si tous les tests ont réussi, le programme se terminera normalement avec le code d'état 0 (succès).
la source
Haskell, 100 octets
Cette réponse utilise entrée transposée .
On dirait que je ne peux pas utiliser un modèle de garde pour lier un opérateur d'infixe, donc j'utilise
where
dans ce cas.(La première version était de 108 octets mais le test d'idempotence a été manqué, la version fixe était de 120 octets, les versions ultérieures avaient 108, 103 et 98 octets mais j'ai dû réaliser grâce à @nimi qu'elles se trompaient toutes: bien sûr, je dois faire le bien- test de divisibilité (qui implique la fermeture) avant de faire tout dangereux
!!
opérations , mais je pouvais encore utiliser la plupart de mes idées de golf ultérieures et avec une autre, il était de 102 octets, maintenant amélioré en changeant l'ordre des opérandes de#
(ce qui est plus agréable de toute façon pour compenser la transposition) pour mieux utiliser son association à gauche)Utilisez comme ceci:
la source
Python 2 , 138 octets
m
est une liste de listes d'entiers.Essayez-le en ligne!
la source
JavaScript (ES6), 150 octets
Prend l'entrée comme un tableau de tableaux de colonnes d'entiers.
la source
Mathematica, 122 octets
Fonction pure prenant en entrée un tableau 2D d'entiers (indexés 1), avec des lignes et des colonnes inversées par rapport à la convention dans la question, et retournant
True
ouFalse
. La première ligne définit l'opération d'infixe binairen_±m_
comme étant l'opération quandle.Pour un tableau
l
xl
, fermé et divisible à droite est équivalent à chaque ligne (dans mon cas) étant une permutation de{1, ..., l}
, et idempotent est équivalent à la diagonale principale étant exactement{1, ..., l}
.#&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]
Détecte donc ces trois conditions. (L'utilisationSort/@#
ici est la raison pour laquelle j'ai choisi d'échanger des lignes et des colonnes.)Pour une distribution à droite, nous vérifions littéralement toutes les possibilités en utilisant
Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}])
. (Notez que±##2±#
se développe automatiquement en(#2±#3)±#
, car##2
représente la séquence des deuxième et troisième arguments de la fonction pure à trois variables en cours de tableau.)&&And@@Flatten@
Vérifie ensuite si chaque test a été réussi. Pour certains dilemmes non fermés, des erreurs peuvent être levées lorsqu'il essaie d'accéder à une partie d'une matrice qui n'existe pas, mais la bonne réponse est toujours renvoyée.la source
±m__:=#[[m]];
Je pense. Et il y a unDiagonal
intégré. Et±
est que vous pouvez utiliser à gauche associative#2±#±(#3±#)
, mais si je ne me trompe alors il est plus court de réattribuer#
à#3
et faire#±#2±#3==#±#3±±##2&
. Et il devrait également être possible de remplacer laFlatten@
pièce entière par(...&~Array~{l,l,l}<>"")
l=Length
dansRange@l
parce que celui-ci doit être évalué en premier, donc si vous utilisez la fonction à plusieurs reprises, je penseRange
que le précédent est toujoursl
, non?C ++ 14, 175 octets
Comme lambda sans nom, en supposant
n
être commestd::vector<std::vector<int>>
et en retournant via le paramètre de référence. 0 est faux, tout le reste est vrai.Non golfé et utilisation:
la source
int a,b,c,u,s=r=m.size()F
au lieu deint s=r=m.size(),a,b,c F
,u=0;r*=s==A.size()&&a==A[a]F
au lieu der*=s==A.size()&&A[a]==a;int u=0 F
,r*=s>A[b]F
au lieu der*=A[b]<s F
et~u+(1<<s)
au lieu deu-(1<<s)+1