Est-ce une matrice stochastique?

24

Une matrice stochastique est une matrice de probabilités utilisée dans le contexte des chaînes de Markov.

Une matrice stochastique droite est une matrice où chaque ligne fait la somme 1.

Une matrice stochastique gauche est une matrice où chaque colonne fait la somme 1.

Une matrice doublement stochastique est une matrice où chaque ligne et chaque colonne résument 1.

Dans ce défi, nous représenterons les probabilités en pourcentage en utilisant des entiers . Une ligne ou une colonne doit dans ce cas additionner 100et non 1.

Votre objectif est d'écrire un programme ou une fonction qui, étant donné une matrice carrée d'entiers, génère une des quatre valeurs indiquant que la matrice est soit stochastique droite, stochastique gauche, doublement stochastique ou aucune de celles-ci.

Contribution

Vous pouvez utiliser toute représentation appropriée d'une matrice qui est naturelle pour votre langue pour l'entrée. Par exemple, une liste de listes, une chaîne de valeurs séparées par des virgules avec des lignes séparées par des sauts de ligne, etc.

La matrice d'entrée sera toujours carrée et ne contiendra que des entiers non négatifs. La matrice d'entrée sera toujours au moins 1×1.

Vous pouvez passer l'entrée en utilisant STDIN, comme argument de fonction, ou quelque chose de similaire.

Sortie

Vous devez choisir quatre sorties distinctes qui correspondent à stochastique droite , gauche stochastique , bistochastiques ou aucun de ceux . Ces sorties doivent être constantes quelle que soit l'entrée transmise. Votre programme peut ne pas renvoyer des sorties différentes pour le même cas, par exemple en disant que tout nombre négatif ne correspond à aucune de celles-ci n'est pas valide.

En bref, il doit y avoir une correspondance 1 à 1 entre votre sortie et les quatre cas possibles. Quelques exemples de ces quatre sorties seraient {1, 2, 3, 4}ou {[1,0], [0,1], [1,1], [0,0]}ou même {right, left, doubly, none}.

Veuillez indiquer dans votre réponse les quatre sorties utilisées par votre programme.

Si une matrice est doublement stochastique, vous devez renvoyer la sortie correspondant à doublement stochastique et non à droite ou à gauche stochastique.

Vous pouvez imprimer la sortie dans STDOUT, la renvoyer à partir d'une fonction ou quelque chose de similaire.

Cas de test

[100]               => Doubly stochastic

[42]                => None of those

[100  0  ]          => Doubly stochastic
[0    100]

[4   8   15]
[16  23  42]        => Left stochastic
[80  69  43]

[99  1 ]            => Right stochastic
[2   98]

[1   2   3   4 ]
[5   6   7   8 ]    => None of those
[9   10  11  12]
[13  14  15  16]

Notation

Il s'agit de , donc la réponse la plus courte en octets l'emporte.

Fatalize
la source
Puis-je prendre une entrée déterminant la taille de la matrice en premier?
HyperNeutrino
@AlexL. Non, ce serait injuste de modifier les spécifications à ce stade.
Fatalize

Réponses:

9

05AB1E , 13 11 10 octets

Stochastique droit [0,1]
: [1,0]
Stochastique gauche: Doublement stochastique: [1,1]
Aucun de ceux-ci: [0,0]

Dø2FOTnQPˆ

Essayez-le en ligne!

Explication

D            # duplicate input
 ø           # transpose the copy
  2F         # 2 times do (once for each matrix)
    O        # sum of the rows
     TnQ     # is equal to 100
        P    # product
         ˆ   # add to global list
             # implicitly print global list at the end of the program
Emigna
la source
14

Haskell, 57 55 octets

import Data.List
s a=all((==100).sum)<$>[transpose a,a]

Entrée de type (Eq a, Num a) => [[a]]. Liste booléenne de sorties[left-stochastic, right-stochastic]

Merci à @proudhaskeller pour avoir économisé 2 octets

Angs
la source
Ne pourriez-vous pas enregistrer quelques octets en rendant la fonction sans point? par exemple avec [transpose,id]<*>(alors vous pouvez omettre le s a=car des fonctions anonymes sont autorisées)
flawr
@flawr peut-être, mais [transpose,id]<*>a un type de [[[a]]]->[[[a]]], qui nécessite une autre couche de mapet pure/ return/ (:[])ou une entrée de type [[[Int]]], ce qui n'est pas naturel. Le meilleur que j'ai eu estmap(all(==100).map sum).(<$>[transpose,id]).flip id
Angs
Ah oui, merci pour l'explication!
flawr
Et au all((==100).sum)lieu de all(==100).map sum?
fier haskeller
@proudhaskeller bien sûr! allfait une cartographie en soi.
Angs
11

R, 55 octets

function(m)c(all(colSums(m)==100),all(rowSums(m)==100))

Fonction sans nom où mest supposée être une matrice R.

Sortie:

  • [1] TRUE FALSE: Stochastique gauche
  • [1] FALSE TRUE: Stochastique droit
  • [1] TRUE TRUE: Doublement
  • [1] FALSE FALSE: Aucun
Billywob
la source
any(colSums(m)-100)et de même pour le rowSumsvous déposera deux octets tout en inversant toutes les sorties, donc si vous souhaitez les conserver, vous pouvez toujours mettre un !avant pour l' -1octet net .
Giuseppe
7

Octave, 35 34 32 31 octets

@(n)any([sum(n);sum(n')]-100,2)

Appelez ça comme ceci:

f(100)
f(42)
f([4,8,15; 16,23,42; 80,69,43])
f([99,1;2,98])
f([1,2,3,4;5,6,7,8;9,10,11,12;13,14,15,16])

Testez-le ici.

Enregistré 2 octets grâce à flawr au départ, mais a opté pour une autre approche qui était 1 octet plus court.

Cela génère les éléments suivants pour les différents cas:

0    Doubly
0    

1    None
1

0    Left
1

1    Right
0

Le dernier ,2serait inutile si des chiffres uniques n'étaient pas inclus. De plus, si cela se résumait à 1au lieu de 100(comme cela aurait pu être le cas), cela économiserait un autre 4octet.

Stewie Griffin
la source
6

Mathematica 29 octets

{}⋃Tr/@#=={100}&/@{#,#}&

en remplaçant le caractère  = U + F3C7 = [\ Transpose]. Cet extrait de code sera collé correctement dans Mathematica.

Même convention de véracité avec {lefttruth, righttruth} en sortie

Kelly Lowder
la source
{}⋃enregistre un octet de plusUnion@
A Simmons
@ASimmons, merci pour le conseil! Mettez-le et corrigé une erreur dans mon total d'octets.
Kelly Lowder
Je pense aussi que si vous faites votre sortie {righttruth, lefttruth}, le remplacement Total@par Tr/@sauvera encore 2 octets.
Un Simmons
Ou inversement de manière équivalente les deux matrices pour que la solution devienne{}⋃Tr/@#=={100}&/@{#,#}&
A Simmons
@ASimmons, Oui, cela en a sauvé encore 2. Merci!
Kelly Lowder
6

k, 21 19 octets

{min'100=+/'(x;+x)}

Sortie

  • 00b aucun
  • 10b la gauche
  • 01b droite
  • 11b tous les deux

Exemple:

k)f:{min'100=+/'(x;+x)} //store function as f
k)f(100 0;98 2)
01b

modifier: réduire le nombre d'octets de 3 - la fonction n'a pas besoin d'être enfermée dans un lambda

modifier: réduire le nombre d'octets de 2 - H / T @Simon Major

skeevey
la source
1
Vous pouvez réellement enregistrer un octet en enfermant dans un lambda: {min'100 = + / '(x; +: x)}
Simon Major
5

MATL , 12 octets

sG!sv!100=XA

La sortie est deux valeurs zéro / un. La première indique si la matrice est stochastique gauche, la seconde si elle est stochastique droite.

Essayez-le en ligne! Ou vérifiez tous les cas de test

s      % Implicitly input N×N matrix. Sum of each column. Gives a 1×N vector
G!     % Push input transposed
s      % Sum of each column. Gives a 1×N vector
v      % Concatenate vertically. Gives a 2×N matrix
!      % Transpose. N×2
100=   % Does each entry equal 100?
XA     % True for columns that contain only "true". Gives 1×2 vector. Implicitly display
Luis Mendo
la source
L'homme que 100 était cher, bonne réponse cependant.
Urne de poulpe magique
5

Mathematica, 46 43 octets

AllTrue[#==100&]/@Apply[Plus,{#,#},{1}]&

Comme pour les autres réponses, les sorties sont

{False, False} pour non stochastique

{True, False} pour stochastique gauche

{False, True} pour stochastique à droite

{True, True} pour doublement stochastique

Enregistré 3 octets en passant à la forme d'opérateur de AllTrue

A Simmons
la source
Utilisez U + F3C7 (usage privé) pour\[Transpose]
u54112
Je l'ai considéré mais j'ai pensé que c'était moins instructif
Un Simmons
Il y a aussi un supplément @à la fin
u54112
4

PHP, 104 octets

function($a){for($s=array_sum;$a[+$i];)$o|=$s($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;}

Une fonction anonyme qui fait écho à 0 => les deux, 1 => à gauche, 2 => à droite, 3 => ni l'un ni l'autre.
Utilisez comme:

php -r "$c=function($a){for($s=array_sum;$a[+$i];)$o|=$s($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;};$c(json_decode($argv[1]));" "[[4,8,15],[16,23,42],[80,69,43]]"

Une version du programme en ligne de commande à 114 octets:

for($a=json_decode($argv[1]);$a[+$i];)$o|=($s=array_sum)($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;

Utilisé comme:

 php -r "for($a=json_decode($argv[1]);$a[+$i];)$o|=($s=array_sum)($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;" "[[4,8,15],[16,23,42],[80,69,43]]"
user59178
la source
4

Python 2, 70 64 octets

Rien de fou ici, juste utiliser des éclaboussures zippour transposer la matrice :) Les sorties sont les suivantes:

0 - not stochastic
1 - right stochastic
2 - left stochastic
3 - doubly stochastic

Et voici le code :)

k=lambda m:all(sum(x)==100for x in m)
lambda n:k(n)+2*k(zip(*n))
Kade
la source
La star est-elle dans (* une erreur?
hhh
1
@hhh Non, c'est l' splatopérateur :) C'est essentiellement ce qui me permet de transposer la matrice :)
Kade
4

C #, 205 203 183 octets

Golfé:

int F(int[,]m){int x,i,j,r,c,e,w;x=m.GetLength(0);e=w=1;for(i=0;i<x;i++){r=c=0;for(j=0;j<x;j++){r+=m[i,j];c+=m[j,i];}if(r!=100)e=0;if(c!=100)w=0;}return e==1&&w==1?3:e==1?1:w==1?2:4;}

Non golfé avec des commentaires:

    int F(int[,] m)
    {
        //x - matrix size
        //i, j - loop control variables
        //r, c - row/column sum
        //e, w - east/west, pseudo-bool values indicate right/left stochastic
        int x, i, j, r, c, e, w;
        x = m.GetLength(0);
        e = w = 1;

        for (i = 0; i < x; i++)
        {
            r = c = 0;

            for (j = 0; j < x; j++)
            {
                r += m[i, j];
                c += m[j, i];
            }

            if (r != 100)
                e = 0;

            if (c != 100)
                w = 0;
        }

        return e == 1 && w == 1 ? 3 : e == 1 ? 1 : w == 1 ? 2 : 4;
    }

Touche de sortie: 1 - stochastique droite 2 - stochastique gauche 3 - double stochastique 4 - aucune

Essayez-le: http://rextester.com/PKYS11433

EDIT1: r=0;c=0;=>r=c=0;

EDIT2: Opérateurs ternaires imbriqués. Les crédits vont à @Yodle.

paldir
la source
2
if(e==1&&w==1)return 3;if(e==1)return 1;return w==1?2:4;Étant donné que eet wne peut être que 1 ou 0, il peut être modifié return w<<1|e;et redéfini aucun == 0.
Link Ng
1
Vous pouvez raccourcir le vôtre de 30 si vous transformez certaines de ces ifinstructions en opérations ternaires et renvoyez simplement un entier à la fin. Idunno si je devais poster ma solution car elle est tellement similaire.
Yodle
@LinkNg Very nice. Je ne veux pas écrire de code sans comprendre. Je ne connais pas les opérateurs binaires.
paldir
@Yodle Merci, j'ai changé de solution. N'hésitez pas à poster votre même s'il est très similaire.
paldir
3

JavaScript (ES6), 83 octets

a=>[a.some(a=>a.reduce((l,r)=>l-r,100)),a.some((_,i)=>a.reduce((l,a)=>l-a[i],100))]

Juste pour être contraire, non seulement cela donne le résultat stoachistique droit sur la gauche, mais les booléens sont également inversés, donc une sortie de [false, true]signifie toujours stoachistique droit.

Neil
la source
3

C # 6, 130 octets

using System.Linq;bool[]F(int[][]a)=>new[]{a.Where((_,i)=>a.Select(x=>x[i]).Sum()==100).Count()==a.Length,a.All(x=>x.Sum()==100)};

{False, False}pour non stochastique
{True, False}pour gauche-stochastique
{False, True}pour droite-stochastique
{True, True}pour doublement stochastique

démo repl.it

Non golfé

bool[]F(int[][]a)=>
    // Return new array of two bools. Array type is inferred from arguments
    new[]
    {
        // Left:
        // Count the no. of columns which sums up to 100
        a.Where((_,i)=>a.Select(x=>x[i]).Sum()==100).Count()
            // Then check if no. of such columns equal to total column count
            ==a.Length,
        // Right: Do all rows sum up to 100?
        // Can't use this trick for left because no overload of All() accept Func<TSource,int,bool> like Where() does
        a.All(x=>x.Sum()==100)
    };
Link Ng
la source
3

Groovy, 57

{a={it.every{it.sum()==100}};[a(it),a(it.transpose())]}​

Sortie

[0,0] sinon.

[1,0] si c'est vrai.

[0,1] si laissé.

[1,1] si les deux.

Urne de poulpe magique
la source
2

Pip , 17 octets

Dans une tournure inattendue, cette soumission est une fonction.

{[h]=UQ$+_M[Zaa]}

Renvoie une liste de deux 0/ 1valeurs: [0 0]= non stochastique, [0 1]= stochastique gauche [1 0]= stochastique droite, [1 1]= doublement stochastique. Essayez-le en ligne!

Explication

{               }  A function:
              a    Function argument (nested list)
           [Za ]   Create a list containing a's transpose and a
          M        Map this function to each of the above:
       $+_           Sum down the columns
     UQ              Get unique elements
 [h]=                If stochastic, the result should be [100]
DLosc
la source
2

Dyalog APL , 16 octets

{∧/100=+/↑⍵(⍉⍵)}

{ }définition de fonction directe (aka "dfn"), est l'argument

⍵(⍉⍵) la matrice à côté de sa transposition

les mélanger dans un seul tableau 2 × n × n

+/ somme le long du dernier axe, obtenez une matrice 2 × n

100= quels éléments sont 100 (les booléens sont 0 1)

∧/ "et" -réduction le long du dernier axe, obtenir 2 booléens pour gauche, droite stochastique

ngn
la source
2

C ++ 14, 139 136 133 130 octets

-3 octets pour s=M.size(), -3 octets pour le retour par paramètre de référence, -3 octets comme lambda sans nom

[](auto M,int&r){int a,b,i,j,s=M.size();r=3;for(i=-1;++i<s;){for(j=-1,a=b=0;++j<s;a+=M[i][j],b+=M[j][i]);r&=(a==100)+2*(b==100);}}

Suppose que l'entrée est similaire vector<vector<int>>. Renvoie 3,2,1,0 pour doublement, gauche, droite, aucun stochastique.

Non golfé:

auto f=
[](auto M, int& r){
  int a,b,i,j,s=M.size();
  r=3;
  for(i=-1;++i<s;){
    for(j=-1,a=b=0;++j<s;
      a+=M[i][j],
      b+=M[j][i]);
    r&=(a==100)+2*(b==100);
  }
}
;
Karl Napf
la source