Desafío
Dada una matriz estocástica izquierda o derecha donde el límite a medida que x se aproxima al infinito de la matriz a la potencia de x se aproxima a una matriz con todos los valores finitos, devuelve la matriz a la que converge la matriz. Básicamente, desea seguir multiplicando la matriz por sí misma hasta que el resultado ya no cambie.
Casos de prueba
[[7/10, 4/10], [3/10, 6/10]] -> [[4/7, 4/7], [3/7, 3/7]]
[[2/5, 4/5], [3/5, 1/5]] -> [[4/7, 4/7], [3/7, 3/7]]
[[1/2, 1/2], [1/2, 1/2]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/3, 2/3], [2/3, 1/3]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/10, 2/10, 3/10], [4/10, 5/10, 6/10], [5/10, 3/10, 1/10]] -> [[27/130, 27/130, 27/130], [66/130, 66/130, 66/130], [37/130, 37/130, 37/130]]
[[1/7, 2/7, 4/7], [2/7, 4/7, 1/7], [4/7, 1/7, 2/7]] -> [[1/3, 1/3, 1/3], [1/3, 1/3, 1/3], [1/3, 1/3, 1/3]]
Reglas
- Se aplican lagunas estándar
- Puede elegir si desea una matriz estocástica derecha o izquierda
- Puede usar cualquier tipo de número razonable, como flotantes, racionales, decimales de precisión infinita, etc.
- Este es el código de golf , por lo que el envío más corto en bytes para cada idioma se declara ganador de su idioma. No se aceptarán respuestas.
Respuestas:
R ,
4443 bytesPruébalo en línea!
Simplemente sigue multiplicándose hasta que encuentra una matriz fija. Aparentemente
X!=(X=X%*%m)
hace la comparación, luego reasignaX
, así que eso está bien.Gracias a @Vlo por eliminar un byte; a pesar de que tachado 44 sigue siendo regular 44.
fuente
function(m){ while(any(m!=(m=m%*%m)))0 m}
no funciona. ¿Imprecisiones numéricas que impiden que se active la condición de terminación?Octava ,
454235 bytesPruébalo en línea!
¡Ahorré 3 bytes gracias a Giuseppe y 7 más gracias a Luis Mendo!
Esto utiliza que el vector propio correspondiente al valor propio 1 (también el valor propio máximo) es el vector de columna que se repite para cada valor de la matriz limitante. Tenemos que normalizar el vector para que tenga la suma 1 para que sea estocástico, luego simplemente lo repetimos para completar la matriz. No estoy muy versado en el golf Octave, pero no he podido encontrar una manera funcional de hacer multiplicaciones repetidas, y un programa completo parece que siempre será más largo que esto.
Podemos usarlo
any(A)
ya que, a partir de las restricciones, sabemos que la matriz debe describir una cadena de Markov irreducible, por lo que cada estado debe ser accesible desde los otros estados. Por lo tanto, al menos un valor en cada columna debe ser distinto de cero.fuente
eigs
siempre devuelve el vector propio correspondiente1
? Mi recuerdo de las cadenas de Markov es un poco borroso.eigs
regresa a partir del valor propio más grande. Además, gracias por el golf!Wolfram Language (Mathematica) , 14 bytes
Flotadores de salida:
Pruébalo en línea!
Wolfram Language (Mathematica) , 30 bytes
Fracciones de salida:
Pruébalo en línea!
fuente
Jalea , 6 bytes
Este es un programa completo.
Pruébalo en línea!
fuente
APL (Dyalog) ,
186 bytes12 bytes guardados gracias a @ H.PWiz
Pruébalo en línea!
fuente
+.×⍨⍣≡
por 6 bytes. Es decir, cuadrado hasta que nada cambiek / q, 10 bytes
k / q porque el programa es idéntico en ambos idiomas. El código es realmente idiomático k / q.
Explicación
{..}
está fuera de la sintaxis lambda, conx
como parámetro implícito$[x]
tiene $ como operador de multiplicación de matriz binaria, proporcionar solo un parámetro crea un operador unario que deja multiplicados por la matriz de Markov/[x]
aplica la multiplicación izquierda hasta la convergencia, comenzando con la propia x.fuente
C (gcc) ,
207192190181176 bytes + 2 bytes de bandera-lm
quincediecisieteveintidós bytes gracias a ceilingcat .return A;
.Pruébalo en línea!
fuente
Python 3 ,
7561 bytesPruébalo en línea!
En los casos de prueba hay imprecisiones de flotación, por lo que los valores pueden diferir un poco de las fracciones exactas.
PD.
numpy.allclose()
se usa porquenumpy.array_equal()
es más largo y propenso a imprecisiones de flotación.-14 bytes Gracias HyperNeutrino;) Oh sí, olvidé el operador @; P
fuente
dot
lugar dematmul
: Dx=n@n
: P tio.run/…f=
al frente porque se llama recursivamente;)Java 8,
356339bytes-17 bytes gracias a @ceilingcat .
Definitivamente no es el lenguaje correcto ... Maldita precisión de coma flotante ...
Explicación:
Pruébalo en línea.
fuente
float
/double
no tiene la precisión de coma flotante adecuada,java.math.BigDecimal
debería usarse en su lugar. Y en lugar de simplemente+-*/
, BigDecimals utilizan.add(...)
,.subtract(...)
,.multiply(...)
,.divide(...)
. Entonces algo tan simple como se7/10
vuelvenew BigDecimal(7).divide(new BigDecimal(10))
. Además, el,scale,RoundingMode
en eldivide
se requieren para valores con 'infinito' decimal valores (como1/3
ser0.333...
). Por supuesto, el método principal se puede jugar al golf, pero no me molesté cuando hice una búsqueda y reemplazo para convertir los flotadores a BigDecimals.