É uma matriz estocástica?

24

Uma matriz estocástica é uma matriz de probabilidades usada no contexto das cadeias de Markov.

Uma matriz estocástica direita é uma matriz em que cada linha é somada 1.

Uma matriz estocástica esquerda é uma matriz em que cada coluna é somada 1.

Uma matriz duplamente estocástica é uma matriz em que cada linha e cada coluna é somada 1.

Neste desafio, representaremos as probabilidades em porcentagem usando números inteiros . Nesse caso, uma linha ou coluna deve somar 100e não 1.

Seu objetivo é escrever um programa ou função que, dada uma matriz quadrada de números inteiros como entrada, produza um dos quatro valores indicando que a matriz é estocástica direita, estocástica esquerda, duplamente estocástica ou nenhuma delas.

Entrada

Você pode usar qualquer representação adequada de uma matriz que seja natural para o seu idioma para a entrada. Por exemplo, uma lista de listas, uma sequência de valores separados por vírgula com linhas separadas por quebras de linha, etc.

A matriz de entrada sempre será quadrada e conterá apenas números inteiros não negativos. A matriz de entrada sempre será pelo menos 1×1.

Você pode passar a entrada usando STDIN, como argumento de função, ou qualquer coisa semelhante.

Saída

Você deve escolher quatro saídas distintas que correspondem a estocástico direito , estocástico esquerdo , duplamente estocástico ou nenhum deles . Essas saídas devem ser constantes, independentemente de qual entrada é passada. Seu programa não pode retornar saídas diferentes para o mesmo caso, por exemplo, dizer que qualquer número negativo corresponde a nenhum deles não é válido.

Em suma, deve haver uma correspondência 1 para 1 entre sua saída e os quatro casos possíveis. Alguns exemplos dessas quatro saídas seriam {1, 2, 3, 4}ou {[1,0], [0,1], [1,1], [0,0]}ou mesmo {right, left, doubly, none}.

Indique na sua resposta as quatro saídas que o seu programa usa.

Se uma matriz é duplamente estocástica, você deve retornar a saída correspondente a duplamente estocástica, e não à direita ou esquerda estocástica.

Você pode imprimir a saída STDOUT, retorná-la de uma função ou algo semelhante.

Casos de teste

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

Pontuação

Isso é , então a resposta mais curta em bytes vence.

Fatalizar
fonte
Posso pegar uma entrada determinando o tamanho da matriz primeiro?
HyperNeutrino
@AlexL. Não, isso seria injusto para alterar as especificações neste momento.
Fatalize

Respostas:

9

05AB1E , 13 11 10 bytes

Estocástico direito: Estocástico [0,1]
esquerdo: [1,0]
Duplamente estocástico: [1,1]
Nenhum desses: [0,0]

Dø2FOTnQPˆ

Experimente online!

Explicação

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

Haskell, 57 55 bytes

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

Entrada do tipo (Eq a, Num a) => [[a]]. Mostra lista booleana[left-stochastic, right-stochastic]

Obrigado a @proudhaskeller por salvar 2 bytes

Angs
fonte
Não foi possível salvar alguns bytes, tornando a função isenta de pontos? por exemplo, com [transpose,id]<*>(então você pode omitir as s a=funções anynomous são permitidas)
flawr 18/11/16
@flawr possivelmente, mas [transpose,id]<*>tem um tipo de [[[a]]]->[[[a]]], que precisa de outra camada mape pure/ return/ (:[])ou de uma entrada do tipo [[[Int]]], que não é natural. O melhor que eu consegui émap(all(==100).map sum).(<$>[transpose,id]).flip id
Angs
Ah, certo, obrigado pela explicação!
flawr
Que tal em all((==100).sum)vez de all(==100).map sum?
2191616163Código do produto
@proudhaskeller, é claro! allfaz um mapeamento em si.
precisa saber é
11

R, 55 bytes

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

Função sem nome, onde mse supõe ser uma matriz R.

Saída:

  • [1] TRUE FALSE: Estocástico esquerdo
  • [1] FALSE TRUE: Estocástico direito
  • [1] TRUE TRUE: Duplamente
  • [1] FALSE FALSE: Nenhum
Billywob
fonte
any(colSums(m)-100)e da mesma forma rowSums, você eliminará dois bytes ao inverter todas as saídas; portanto, se você quiser mantê-las, sempre poderá colocar um !by-net à frente -1.
21417 Giuseppe
7

Oitava, 35 34 32 31 bytes

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

Chame assim:

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

Teste aqui.

Economizou 2 bytes graças ao flawr inicialmente, mas optou por outra abordagem que foi 1 byte menor.

Isso gera o seguinte para os diferentes casos:

0    Doubly
0    

1    None
1

0    Left
1

1    Right
0

O último ,2seria desnecessário se não fossem incluídos dígitos únicos. Além disso, se isso somar em 1vez de 100(como poderia ter), ele salvará outros 4bytes.

Stewie Griffin
fonte
6

Mathematica 29 Bytes

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

substituindo o caractere  = U + F3C7 = [\ Transpose]. Este trecho de código será colado corretamente no Mathematica.

A mesma convenção de veracidade com {lefttruth, righttruth} que a saída

Kelly Lowder
fonte
{}⋃salva um byteUnion@
A Simmons
@ ASimmons, obrigado pela dica! Coloquei e corrigi um erro no total de bytes.
Kelly Lowder
Também acho que se você fizer sua saída {righttruth, lefttruth}, a substituição Total@por Tr/@salvará mais 2 bytes.
Um Simmons
Ou equivalentemente inverter as duas matrizes torna-se então a solução{}⋃Tr/@#=={100}&/@{#,#}&
Um Simmons
@ ASimmons, Sim, isso salvou mais 2. Obrigado!
21416 Kelly Lowder
6

k, 21 19 bytes

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

Saída

  • 00b Nenhum
  • 10b esquerda
  • 01b direita
  • 11b ambos

Exemplo:

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

editar: reduzir a contagem de bytes em 3 - a função não precisa ser incluída em um lambda

edit: reduza bytecount em 2 - H / T @Simon Major

skeevey
fonte
11
Na verdade, você pode salvar um byte colocando um lambda: {min'100 = + / '(x; +: x)}
Simon Major
5

MATL , 12 bytes

sG!sv!100=XA

A saída é dois valores zero / um. Primeiro indica se a matriz é estocástica esquerda, depois se é estocástica direita.

Experimente online! Ou verifique todos os casos de teste

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
fonte
Cara que 100 foi caro, boa resposta embora.
Magia Octopus Urna
5

Mathematica, 46 43 bytes

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

Como em outras respostas, os resultados são

{False, False} para não estocástico

{True, False} para estocástico esquerdo

{False, True} para estocástico direito

{True, True} para duplamente estocástico

Salva 3 bytes alternando para o formulário do operador AllTrue

A Simmons
fonte
Use U + F3C7 (uso privado) para\[Transpose]
u54112 18/11
Eu considerei isso, mas pensei que era menos esclarecedora
A Simmons
Também há um extra @no final
u54112 18/11
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;}

Uma função anônima que ecoa 0 => ambos, 1 => esquerda, 2 => direita, 3 => nenhum.
Use 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]]"

Uma versão do programa de linha de comando em 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]]"
user59178
fonte
4

Python 2, 70 64 bytes

Nada louco aqui, apenas fazendo uso de splatting zippara transpor a matriz :) As saídas são as seguintes:

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

E aqui está o código :)

k=lambda m:all(sum(x)==100for x in m)
lambda n:k(n)+2*k(zip(*n))
Kade
fonte
A estrela está em (* na equação?
hhh 18/11
11
@hhh Não, esse é o splatoperador :) Essencialmente é isso que está me deixando transpor a matriz :)
Kade
4

C #, 205 203 183 bytes

Golfe:

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 com comentários:

    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 saída: 1 - estocástico direito 2 - estocástico esquerdo 3 - estocástico duplo 4 - nenhum

Experimente: http://rextester.com/PKYS11433

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

EDIT2: Operadores ternários aninhados. Os créditos vão para @Yodle.

paldir
fonte
2
if(e==1&&w==1)return 3;if(e==1)return 1;return w==1?2:4;Como ee wsó pode ser 1 ou 0, ele pode ser alterado para return w<<1|e;e redefinir nenhum == 0.
Link Ng
11
Você pode encurtar o seu em 30 se transformar algumas dessas ifinstruções em operações ternárias e retornar um número inteiro no final. Idunno se devo postar minha solução, pois é tão semelhante.
Yodle
@LinkNg Very nice. Não quero escrever código sem entender. Não estou familiarizado com operadores binários.
paldir
@Yodle Obrigado, mudei minha solução. Sinta-se livre para publicar o seu, mesmo que seja muito semelhante.
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))]

Apenas para ser contrário, isso não apenas produz o resultado estequiático certo à esquerda, mas os booleanos também são invertidos, de modo que uma produção de [false, true]ainda significa estatisticamente correto.

Neil
fonte
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 não estocástico
{True, False}para estocástico esquerdo para estocástico
{False, True}direito
{True, True}para duplamente estocástico

demo repl.it

Ungolfed

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)
    };
Ng do link
fonte
3

Groovy, 57

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

Saída

[0,0] se nenhum.

[1,0] se certo.

[0,1] se for deixado.

[1,1] se ambos.

Urna de polvo mágico
fonte
2

Pip , 17 bytes

Em uma reviravolta inesperada, essa submissão é uma função.

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

Retorna uma lista de dois 0/ 1valores: [0 0]= não estocástico, [0 1]= estocástico esquerdo, [1 0]= estocástico direito, [1 1]= duplamente estocástico. Experimente online!

Explicação

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

Dyalog APL , 16 bytes

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

{ }definição de função direta (aka "dfn"), é o argumento

⍵(⍉⍵) a matriz ao lado de sua transposição

misture-os em uma única matriz 2 × n × n

+/ soma ao longo do último eixo, obtenha uma matriz 2 × n

100= quais elementos são 100 (os booleanos são 0 1)

∧/ "e" - ao longo do último eixo, obtenha 2 booleanos para estocástico esquerdo e direito

ngn
fonte
2

C ++ 14, 139 136 133 130 bytes

-3 bytes para s=M.size(), -3 bytes para retornar pelo parâmetro de referência, -3 bytes como um lambda sem nome

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

Assume a entrada como vector<vector<int>> . Retorna 3,2,1,0 para duplamente, esquerda, direita, nenhuma estocástica.

Ungolfed:

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
fonte