Défi
Étant donné une matrice stochastique gauche ou droite où la limite lorsque x s'approche de l'infini de la matrice à la puissance de x s'approche d'une matrice avec toutes les valeurs finies, retournez la matrice vers laquelle la matrice converge. Fondamentalement, vous souhaitez continuer à multiplier la matrice par elle-même jusqu'à ce que le résultat ne change plus.
Cas de test
[[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]]
Règles
- Les échappatoires standard s'appliquent
- Vous pouvez choisir si vous voulez une matrice stochastique droite ou gauche
- Vous pouvez utiliser n'importe quel type de nombre raisonnable, comme les flottants, les rationnels, les décimales de précision infinie, etc.
- Il s'agit de code-golf , donc la soumission la plus courte en octets pour chaque langue est déclarée gagnante pour sa langue. Aucune réponse ne sera acceptée
Réponses:
R ,
4443 octetsEssayez-le en ligne!
Continue de multiplier jusqu'à ce qu'il trouve une matrice fixe. Apparemment,
X!=(X=X%*%m)
fait la comparaison, puis réaffecteX
, donc c'est bien.Merci à @Vlo d'avoir rasé un octet; même si barré 44 est toujours régulier 44.
la source
function(m){ while(any(m!=(m=m%*%m)))0 m}
ça ne marche pas. Des inexactitudes numériques empêchant la condition de terminaison de se déclencher?Octave ,
454235 octetsEssayez-le en ligne!
Enregistré 3 octets grâce à Giuseppe et 7 autres grâce à Luis Mendo!
Cela utilise que le vecteur propre correspondant à la valeur propre 1 (également la valeur propre maximale) est le vecteur de colonne qui est répété pour chaque valeur de la matrice limite. Nous devons normaliser le vecteur pour avoir la somme 1 pour qu'il soit stochastique, puis nous le répétons simplement pour remplir la matrice. Je ne connais pas très bien le golf d'Octave, mais je n'ai pas réussi à trouver un moyen fonctionnel de faire des multiplications répétées, et un programme complet semble être toujours plus long que cela.
Nous pouvons utiliser
any(A)
car des restrictions nous savons que la matrice doit décrire une chaîne de Markov irréductible, et donc chaque état doit être accessible à partir des autres états. Par conséquent, au moins une valeur dans chaque colonne doit être différente de zéro.la source
eigs
renvoie toujours le vecteur propre correspondant1
? Ma mémoire des chaînes de Markov est un peu floue.eigs
retourne à partir de la plus grande valeur propre. Merci aussi pour le golf!Wolfram Language (Mathematica) , 14 octets
Flotteurs de sortie:
Essayez-le en ligne!
Wolfram Language (Mathematica) , 30 octets
Fractions de sortie:
Essayez-le en ligne!
la source
Gelée , 6 octets
Ceci est un programme complet.
Essayez-le en ligne!
la source
APL (Dyalog) ,
186 octets12 octets enregistrés grâce à @ H.PWiz
Essayez-le en ligne!
la source
+.×⍨⍣≡
pour 6 octets. Autrement dit, carré jusqu'à ce que rien ne changek / q, 10 octets
k / q car le programme est identique dans les deux langues. Le code est vraiment juste idiomatique k / q.
Explication
{..}
est hors syntaxe lambda, avecx
comme paramètre implicite$[x]
a $ comme opérateur de multiplication de matrice binaire, fournir un seul paramètre crée un opérateur unaire qui a laissé des multiplications par la matrice de Markov/[x]
applique la multiplication gauche jusqu'à la convergence, en commençant par x lui-même.la source
C (gcc) ,
207192190181176 octets + 2 octets d'indicateur-lm
quinzedix-septvingt-deux octets grâce au plafond .return A;
.Essayez-le en ligne!
la source
Python 3 ,
7561 octetsEssayez-le en ligne!
Dans les cas de test, il existe des inexactitudes flottantes, de sorte que les valeurs peuvent différer légèrement des fractions exactes.
PS.
numpy.allclose()
est utilisé parce qu'ilnumpy.array_equal()
est plus long et sujet à des inexactitudes flottantes.-14 octets Merci HyperNeutrino;) Oh oui j'ai oublié l'opérateur @; P
la source
dot
au lieu dematmul
: Dx=n@n
: P tio.run/…f=
car il est appelé récursivement;)Java 8,
356339 octets-17 octets grâce à @ceilingcat .
Certainement pas la bonne langue .. Maudite précision en virgule flottante ..
Explication:
Essayez-le en ligne.
la source
float
/double
n'a pas la bonne précision en virgule flottante,java.math.BigDecimal
doit être utilisé à la place. Et au lieu de simplement+-*/
, BigDecimals utiliser.add(...)
,.subtract(...)
,.multiply(...)
,.divide(...)
. Donc, quelque chose d'aussi simple que cela7/10
devientnew BigDecimal(7).divide(new BigDecimal(10))
. De plus, les,scale,RoundingMode
dansdivide
sont obligatoires pour les valeurs avec des valeurs décimales «infinies» (comme l'1/3
être0.333...
). La méthode principale peut bien sûr être utilisée, mais je n'ai pas pris la peine quand j'ai fait une recherche et un remplacement pour convertir les flotteurs en BigDecimals.