Escriba un programa que determine si una matriz dada representa un quandle. Un quandle es un conjunto equipado con una sola operación (no conmutativa, no asociativa) ◃ que obedece a los siguientes axiomas:
- La operación está cerrada, lo que significa que
a◃b = c
siempre es un elemento del conjunto sia
yb
son elementos del conjunto. - El funcionamiento es correcto-autodistributiva:
(a◃b)◃c = (a◃c)◃(b◃c)
. - La operación es divisible a la derecha: para cualquier par de
a
yb
, hay un único únicoc
tal quec◃a = b
- La operación es idempotente:
a◃a = a
Un quandle finito se puede representar como una matriz cuadrada. A continuación se muestra un ejemplo de un quandle de orden 5 ( fuente ).
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
El valor ubicado en la fila n-ésima y la columna m-ésima (indexada a 0) es el valor de n◃m. Por ejemplo, en este quandle, 4◃1 = 3
. Algunas de las propiedades de quandle son fáciles de ver desde esta matriz:
- Está cerrado porque solo los valores 0-4 aparecen en esta matriz de 5x5.
- Es idempotente porque la diagonal de la matriz es 0 1 2 3 4
- Es divisible a la derecha porque ninguna columna contiene valores duplicados. (Las filas pueden, y generalmente lo harán).
La propiedad de la auto-distributividad correcta es más difícil de probar. Puede haber un atajo, pero el método más simple es iterar sobre cada combinación posible de tres índices para verificar eso m[m[a][b]][c] = m[m[a][c]][m[b][c]]
.
Entrada
La entrada será la lista de filas de una matriz cuadrada, usando 0-indexing o 1-index (su elección). Cada entrada será un número de un solo dígito desde 0
hasta 8
(o 1
hasta 9
). Seré flexible en el formato de entrada. Algunos formatos aceptables incluyen:
- El formato más natural de su idioma para matrices o listas, como
[[0 0 0][2 1 1][1 2 2]]
o(0,0,0,2,1,1,1,2,2)
. - La lista de valores delimitados por espacios en blanco, líneas nuevas, comas, etc.
- Una sola cadena que consta de todos los valores concatenados juntos, como
000211122
.
También se le permite tomar la transposición de la matriz como entrada (intercambiando filas con columnas). Solo asegúrese de indicar esto en su respuesta.
Salida
Un solo valor de verdad / falsey que indica el estado de la matriz como quandle.
Ejemplos de 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
Ejemplos de no quandles
no se ha cerrado
1
0 0 0
2 1 1
1 9 2
no correcto-auto-distributivo
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
no divisible a la derecha
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
no idempotente
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
Respuestas:
Python 2 ,
104103102 bytesLa entrada se transpone. La salida es a través del código de salida, por lo que 0 (éxito) es verdadero y 1 (fracaso) es falso.
Pruébalo en línea!
Cómo funciona
e(t)
devuelve las filas enumeradas de la matriz de entrada t , que representa un operador ◃ , como pares (índice, fila).for(a,A)in e(t)
, Por ejemplo, itera sobre estos, almacenar el índice en una y la misma fila en A , por lo queA
se convierte en un acceso directo parat[a]
.Entre los primeros,
for(b,B)in e(t)
yfor C in t
, iteramos sobre todas las tuplas ordenadas posibles (a, b, c) en el poder cartesiano t 3 .Para cada una de estas tuplas, evaluamos la expresión
El valor del booleano entre paréntesis es Falso si y solo si una o más de las siguientes comparaciones individuales hacen lo mismo.
a==A[a]
fallará (para algún valor de a ) si ◃ no es idempotente.A[a]in B
fallará si B no contiene todos los índices de una .Como A tiene n índices y B tiene n elementos, la no falla significa que los elementos de B coinciden con los índices de A , por lo que ◃ es cerrado y divisible a la derecha.
B>C[B[a]]
es una tautología, ya que Python 2 consideraba los números "más pequeños" que los iterables.C[B[a]]==t[C[b]][C[a]]
fallará por algún valor si ◃ no es auto-distributivo correcto.Si alguna de las comparaciones devuelve False , la expresión
(0%...)
arrojará un ZeroDivisionError . Además, si ◃ no está cerradoA[a]
oC[b]
también puede arrojar un IndexError . En ambos casos, el programa sale con el código de estado 1 (falla).Si se pasan todas las pruebas, el programa saldrá normalmente con el código de estado 0 (correcto).
fuente
Haskell, 100 bytes
Esta respuesta utiliza la entrada transpuesta .
Parece que no puedo usar un protector de patrón para unir un operador infijo, así que lo estoy usando
where
en este caso.(La primera versión tenía 108 bytes pero se perdió la prueba de idempotencia, la versión fija tenía 120 bytes, las versiones posteriores tenían 108, 103 y 98 bytes, pero tuve que darme cuenta gracias a @nimi de que todos estaban equivocados: por supuesto, tengo que hacer lo correcto. prueba de divisibilidad (que implica cierre) antes de realizar
!!
operaciones peligrosas , pero aún podría usar la mayoría de mis ideas de golf posteriores y con una más, era de 102 bytes, ahora mejorada al cambiar el orden de los operandos#
(que de todos modos es mejor para compensar el transposición) para hacer un mejor uso de su asociación a la izquierda)Usar así:
fuente
Python 2 , 138 bytes
m
es una lista de listas de enteros.Pruébalo en línea!
fuente
JavaScript (ES6), 150 bytes
Toma datos como una matriz de columnas de enteros.
fuente
Mathematica, 122 bytes
Función pura que toma una matriz 2D de enteros (1 indexado) como entrada, con filas y columnas invertidas de la convención en la pregunta, y devolviendo
True
oFalse
. La primera línea define la operación infijo binarian_±m_
como la operación quandle.Para una matriz
l
xl
, cerrado y divisible a la derecha es equivalente a que cada fila (en mi caso) sea alguna permutación de{1, ..., l}
, e idempotente es equivalente a que la diagonal principal sea exactamente{1, ..., l}
. Entonces#&@@Union[Sort/@#]==Range@l==Array[#±#&,l=Length@#]
detecta estas tres condiciones. (El uso deSort/@#
aquí es la razón por la que elegí intercambiar filas y columnas).Para la distribución correcta, verificamos literalmente todas las posibilidades usando
Array[±##2±#==(#2±#)±(#3±#)&,{l,l,l}])
. (Tenga en cuenta que±##2±#
se expande automáticamente a(#2±#3)±#
, ya que##2
representa la secuencia del segundo y tercer argumento de la función pura de tres variables sobre la que se está ordenando). Luego&&And@@Flatten@
verifica si se aprobó cada prueba. Para algunos quandles no cerrados, se pueden generar errores cuando intenta acceder a una parte de una matriz que no existe, pero la respuesta correcta aún se devuelve.fuente
±m__:=#[[m]];
Yo creo que. Y hay unDiagonal
incorporado. Y±
es asociativo por la izquierda y lo puede utilizar#2±#±(#3±#)
, pero si no me equivoco, entonces es más corto para volver a asignar#
a#3
y hacer#±#2±#3==#±#3±±##2&
. Y también debería ser posible reemplazar toda laFlatten@
parte con(...&~Array~{l,l,l}<>"")
l=Length
aRange@l
pesar de que debido a que uno se debe evaluar en primer lugar, por lo que si se utiliza la función en repetidas ocasiones, creo queRange
todavía se pone el anteriorl
, no?C ++ 14, 175 bytes
Como lambda sin nombre, suponiendo
n
que sea comostd::vector<std::vector<int>>
y que regrese a través del parámetro de referencia. 0 es falso, todo lo demás es cierto.Sin golf y uso:
fuente
int a,b,c,u,s=r=m.size()F
lugar deint s=r=m.size(),a,b,c F
, enu=0;r*=s==A.size()&&a==A[a]F
lugar der*=s==A.size()&&A[a]==a;int u=0 F
, enr*=s>A[b]F
lugar der*=A[b]<s F
y en~u+(1<<s)
lugar deu-(1<<s)+1