¿Es una matriz estocástica?

24

Una matriz estocástica es una matriz de probabilidades utilizada en el contexto de las cadenas de Markov.

Una matriz estocástica derecha es una matriz donde cada fila suma 1.

Una matriz estocástica izquierda es una matriz donde cada columna suma 1.

Una matriz doblemente estocástica es una matriz donde cada fila y cada columna suman 1.

En este desafío, representaremos las probabilidades en porcentaje usando enteros . En ese caso, una fila o columna debe sumar 100y no 1.

Su objetivo es escribir un programa o función que, dada una matriz cuadrada de enteros como entrada, genere uno de los cuatro valores que indican que la matriz es estocástica derecha, estocástica izquierda, doblemente estocástica o ninguna de esas.

Entrada

Puede usar cualquier representación adecuada de una matriz que sea natural para su idioma para la entrada. Por ejemplo, una lista de listas, una cadena de valores separados por comas con filas separadas por saltos de línea, etc.

La matriz de entrada siempre será cuadrada y solo contendrá enteros no negativos. La matriz de entrada siempre será al menos 1×1.

Puede pasar la entrada utilizando STDIN, como argumento de función, o algo similar.

Salida

Debe elegir cuatro salidas distintas que correspondan a estocástico derecho , estocástico izquierdo , doblemente estocástico o ninguno de esos . Esas salidas deben ser constantes independientemente de la entrada que se pase. Es posible que su programa no devuelva resultados diferentes para el mismo caso, por ejemplo, decir que cualquier número negativo no corresponde a ninguno de ellos no es válido.

En resumen, debe haber una correspondencia 1 a 1 entre su salida y los cuatro casos posibles. Algunos ejemplos de esas cuatro salidas serían {1, 2, 3, 4}o {[1,0], [0,1], [1,1], [0,0]}ni siquiera {right, left, doubly, none}.

Indique en su respuesta las cuatro salidas que utiliza su programa.

Si una matriz es doblemente estocástica, debe devolver la salida correspondiente a doblemente estocástica, y no estocástica derecha o izquierda.

Puede imprimir el resultado STDOUT, devolverlo desde una función o algo similar.

Casos de prueba

[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]

Tanteo

Este es el , por lo que gana la respuesta más corta en bytes.

Fatalizar
fuente
¿Puedo tomar una entrada que determine primero el tamaño de la matriz?
HyperNeutrino
@AlexL. No, sería injusto cambiar las especificaciones en este momento.
Fatalize

Respuestas:

9

05AB1E , 13 11 10 bytes

Estocástico derecho: Estocástico [0,1]
izquierdo: [1,0]
Doble estocástico: [1,1]
Ninguno de esos: [0,0]

Dø2FOTnQPˆ

Pruébalo en línea!

Explicación

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
fuente
14

Haskell, 57 55 bytes

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

Entrada de tipo (Eq a, Num a) => [[a]]. Lista booleana de salidas[left-stochastic, right-stochastic]

Gracias a @proudhaskeller por guardar 2 bytes

Angs
fuente
¿No podría guardar algunos bytes haciendo que la función no tenga puntos? por ejemplo, con [transpose,id]<*>(entonces podría omitirlo s a=ya que se permiten funciones anónimas)
falla
@flawr posiblemente, pero [transpose,id]<*>tiene un tipo de [[[a]]]->[[[a]]], que necesita otra capa de mapy un pure/ return/ (:[])o una entrada de tipo [[[Int]]], que no es natural. Lo mejor que tengo esmap(all(==100).map sum).(<$>[transpose,id]).flip id
Angs
Ah cierto, gracias por la explicación!
falla
¿Qué tal en all((==100).sum)lugar de all(==100).map sum?
orgulloso Haskeller
@proudhaskeller, por supuesto! allhace un mapeo en sí mismo.
Angs
11

R, 55 bytes

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

Función sin nombre donde mse supone que es una matriz R.

Salida:

  • [1] TRUE FALSE: Estocástico izquierdo
  • [1] FALSE TRUE: Estocástico derecho
  • [1] TRUE TRUE: Doblemente
  • [1] FALSE FALSE: Ninguna
Billywob
fuente
any(colSums(m)-100)y de la misma manera, el rowSumste dejará dos bytes mientras invierte todas las salidas, por lo que si desea conservarlos, siempre puede poner un !frente para el -1byte neto .
Giuseppe
7

Octava, 35 34 32 31 bytes

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

Llámalo así:

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])

Pruébalo aquí.

Inicialmente guardé 2 bytes gracias a flawr, pero elegí otro enfoque que fue 1 byte más corto.

Esto genera lo siguiente para los diferentes casos:

0    Doubly
0    

1    None
1

0    Left
1

1    Right
0

Lo último ,2sería innecesario si no se incluyeran dígitos individuales. Además, si esto se suma a en 1lugar de 100(como podría haberlo hecho), ahorraría otros 4bytes.

Stewie Griffin
fuente
6

Mathematica 29 Bytes

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

sustituyendo el carácter  = U + F3C7 = [\ Transpose]. Este fragmento de código se pegará correctamente en Mathematica.

La misma convención de veracidad con {lefttruth, righttruth} como salida

Kelly Lowder
fuente
{}⋃ahorra un byteUnion@
Un Simmons
@ASimmons, gracias por el consejo! Póngalo y corrigió un error en mi byte total.
Kelly Lowder
También creo que si realiza su salida {righttruth, lefttruth}, reemplazar Total@con Tr/@ahorrará otros 2 bytes.
Un Simmons
O revierta de manera equivalente las dos matrices para que la solución se convierta{}⋃Tr/@#=={100}&/@{#,#}&
A Simmons
@ASimmons, sí, eso salvó otros 2. ¡Gracias!
Kelly Lowder
6

k, 21 19 bytes

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

Salida

  • 00b ninguna
  • 10b izquierda
  • 01b Derecha
  • 11b ambos

Ejemplo:

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

editar: reducir el recuento de bytes en 3: la función no necesita estar encerrada en una lambda

editar: reducir bytecount en 2 - H / T @Simon Major

skeevey
fuente
1
En realidad, puede guardar un byte encerrándolo en una lambda: {min'100 = + / '(x; +: x)}
Simon Major el
5

MATL , 12 bytes

sG!sv!100=XA

La salida es dos valores cero / uno. Primero indica si la matriz es estocástica izquierda, segundo si es estocástica derecha.

Pruébalo en línea! O verificar todos los casos de prueba

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
fuente
Hombre que 100 era caro, buena respuesta sin embargo.
Urna de pulpo mágico
5

Mathematica, 46 43 bytes

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

Como con otras respuestas, las salidas son

{False, False} para no estocástico

{True, False} para el estocástico izquierdo

{False, True} para el estocástico derecho

{True, True} para doble estocástico

Se guardaron 3 bytes al cambiar a la forma de operador de AllTrue

Un simmons
fuente
Use U + F3C7 (uso privado) para\[Transpose]
u54112
Lo consideré pero pensé que era menos esclarecedor
un Simmons el
También hay un extra @al final
u54112
4

PHP, 104 bytes

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

Una función anónima que echos 0 => ambos, 1 => izquierda, 2 => derecha, 3 => ninguno.
Usar como:

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]]"

Una versión del programa de línea de comando a 114 bytes:

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

Usado como:

 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]]"
usuario59178
fuente
4

Python 2, 70 64 bytes

No hay nada loco aquí, solo haciendo uso de las salpicaduras zippara transponer la matriz :) Los resultados son los siguientes:

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

Y aquí está el código :)

k=lambda m:all(sum(x)==100for x in m)
lambda n:k(n)+2*k(zip(*n))
Kade
fuente
¿Está la estrella en (* un error?
hhh
1
@hhh No, ese es el splatoperador :) Esencialmente, eso es lo que me permite transponer la matriz :)
Kade
4

C #, 205 203 183 bytes

Golfizado:

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;}

Ungolfed con comentarios:

    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;
    }

Tecla de salida: 1 - estocástico derecho 2 - estocástico izquierdo 3 - estocástico doble 4 - ninguno

Pruébelo: http://rextester.com/PKYS11433

EDITAR1: r=0;c=0;=>r=c=0;

EDIT2: operadores ternarios anidados. Los créditos van a @Yodle.

paldir
fuente
2
if(e==1&&w==1)return 3;if(e==1)return 1;return w==1?2:4;Dado que ey wsolo puede ser 1 o 0, se puede cambiar return w<<1|e;y redefinir none == 0.
Enlace el
1
Puede acortar la suya en 30 si convierte algunas de esas ifdeclaraciones en operaciones ternarias y simplemente devuelve un número entero al final. No sé si debería publicar mi solución, ya que es muy similar.
Yodle
@LinkNg Muy bien. No quiero escribir código sin entenderlo. No estoy familiarizado con los operadores binarios.
paldir
@Yodle Gracias, cambié mi solución. Siéntase libre de publicar su incluso si es muy similar.
paldir
3

JavaScript (ES6), 83 bytes

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

Para ser contrario, esto no solo genera el resultado estoico derecho a la izquierda, sino que los valores booleanos también se invierten, por lo que una salida de [false, true]todavía significa estoico derecho.

Neil
fuente
3

C # 6, 130 bytes

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}para no estocástico
{True, False}para izquierdo estocástico
{False, True}para derecho estocástico
{True, True}para doble estocástico

demo de repl.it

Sin 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)
    };
Enlace Ng
fuente
3

Groovy, 57

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

Salida

[0,0] si ninguno.

[1,0] si es correcto

[0,1] si queda

[1,1] si ambos.

Urna de pulpo mágico
fuente
2

Pip , 17 bytes

En un giro inesperado, esta sumisión es una función.

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

Devuelve una lista de dos 0/ 1valores: [0 0]= no estocástico, [0 1]= estocástico izquierdo, [1 0]= estocástico derecho, [1 1]= doblemente estocástico. Pruébalo en línea!

Explicación

{               }  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
fuente
2

Dyalog APL , 16 bytes

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

{ }definición de función directa (también conocida como "dfn"), es el argumento

⍵(⍉⍵) la matriz junto con su transposición

mezclarlos en una sola matriz 2 × n × n

+/ suma a lo largo del último eje, obtiene una matriz 2 × n

100= qué elementos son 100 (los booleanos son 0 1)

∧/ "y" -reducción a lo largo del último eje, obtener 2 booleanos para el estocástico izquierdo y derecho

ngn
fuente
2

C ++ 14, 139 136 133 130 bytes

-3 bytes para s=M.size(), -3 bytes para regresar por parámetro de referencia, -3 bytes como una lambda sin nombre

[](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);}}

Asume que la entrada es como vector<vector<int>>. Devuelve 3,2,1,0 para doble, izquierda, derecha, ninguno estocástico.

Sin 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
fuente