Це стохастична матриця?


24

Стохастична матриця є матрицею ймовірностей , використовуваних в контексті ланцюгів Маркова.

Права стохастична матриця є матрицею , де кожен рядок суми в 1.

Вліво стохастична матриця є матрицею , де кожен стовпець суми в 1.

Двічі стохастична матриця є матрицею , де кожен рядок і кожен стовпець сум до 1.

У цьому виклику ми будемо представляти ймовірності у відсотках за допомогою цілих чисел . Рядок або стовпець повинен у цьому випадку дорівнювати 100і не 1.

Ваша мета полягає в тому, щоб написати програму або функцію, яка, маючи вхідну квадратну матрицю цілих чисел, виводить одне з чотирьох значень, що вказує на те, що матриця є або право стохастичною, ліво стохастичною, подвійно стохастичною, або жодною з них.

Вхідні дані

Ви можете використовувати будь-яке правильне подання матриці, природної для вашої мови, для введення. Наприклад, список списків, рядок знаків, розділених комами, рядками, розділеними рядковими розривами тощо.

Матриця введення завжди буде квадратною і міститиме лише невід’ємні цілі числа. Вхідна матриця завжди буде як мінімум 1×1.

Ви можете передавати дані, використовуючи STDIN, як аргумент функції, або щось подібне.

Вихідні дані

Ви повинні вибрати чотири різних виходи, які відповідають правим стохастичним , лівим стохастичним , подвійним стохастичним або жодним із них . Ці виходи повинні бути постійними незалежно від того, який вхід передано. Ваша програма може не повертати різні виходи для одного і того ж випадку, наприклад, кажучи, що будь-яке негативне число відповідає жодному з них , недійсне.

Коротше кажучи, між вашим висновком та чотирма можливими випадками має бути відповідність 1 на 1. Деякі приклади цих чотирьох виходів будуть {1, 2, 3, 4}або {[1,0], [0,1], [1,1], [0,0]}навіть {right, left, doubly, none}.

Вкажіть, будь ласка, у своїй відповіді чотири виходи, якими користується ваша програма.

Якщо матриця є подвійно стохастичною, то ви повинні повернути вихід, що відповідає подвійно стохастичному, а не правильному чи лівому стохастичному.

Ви можете надрукувати вихід STDOUT, повернути його з функції чи чогось подібного.

Тестові справи

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

Оцінка балів

Це , тому найкоротша відповідь у байтах виграє.


Чи можу я спершу взяти дані, що визначають розмір матриці?
HyperNeutrino

@AlexL. Ні, це було б несправедливо змінити характеристики в цей момент.
Фаталізувати

Відповіді:


9

05AB1E , 13 11 10 байт

Право стохастичне: [0,1]
Ліво стохастичне: [1,0]
Подвійно стохастичне: [1,1]
Жодне з цих: [0,0]

Dø2FOTnQPˆ

Спробуйте в Інтернеті!

Пояснення

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

14

Haskell, 57 55 байт

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

Введення типу (Eq a, Num a) => [[a]]. Виводить булевий список[left-stochastic, right-stochastic]

Завдяки @proudhaskeller за збереження 2 байтів


Не вдалося зберегти кілька байтів, зробивши функцію точковою? наприклад, з [transpose,id]<*>(тоді ви можете опустити, s a=оскільки дозволені будь-які функції)
недолік

@flawr можливо, але [transpose,id]<*>має тип [[[a]]]->[[[a]]], який потребує іншого шару mapта pure/ return/ (:[])або вводу типу [[[Int]]], що не є природним. Найкраще, що я отримавmap(all(==100).map sum).(<$>[transpose,id]).flip id
англ

Ага, дякую за пояснення!
недолік

Як щодо all((==100).sum)цього all(==100).map sum?
гордий haskeller

@proudhaskeller звичайно! allробить картування саме по собі.
Ангс

11

R, 55 байт

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

Безіменна функція, де mпередбачається R-матриця.

Вихід:

  • [1] TRUE FALSE: Зліва стохастична
  • [1] FALSE TRUE: Право стохастичне
  • [1] TRUE TRUE: Подвійно
  • [1] FALSE FALSE: Ні

any(colSums(m)-100)і так само для rowSumsволі ви скинете два байти, перевернувши всі виходи, тож, якщо ви хочете зберегти їх, ви завжди можете поставити !перед собою чистий -1байт.
Джузеппе

7

Октава, 35 34 32 31 байт

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

Назвіть це так:

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

Перевірте це тут.

Збережено 2 байти завдяки помилці спочатку, але пішов на інший підхід, який був на 1 байт коротшим.

Це виводить наступне для різних випадків:

0    Doubly
0    

1    None
1

0    Left
1

1    Right
0

Останній ,2був би непотрібним, якби не були включені однозначні цифри. Крім того, якщо це підсумовано 1замість 100(як міг би), це збереже ще один 4байт.


6

Mathematica 29 байт

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

підміна символу  = U + F3C7 = [\ Transpose]. Цей фрагмент коду буде правильно вставлений у Mathematica.

Це ж умовність правдивості з {lefttruth, righttruth} як вихід


{}⋃економить один байтUnion@
A Simmons

@ASimmons, дякую за пораду! Помістіть його і виправте помилку в моєму загальному байті.
Келлі Лоудер

Також я думаю, якщо ви зробите свій результат {righttruth, lefttruth}, то заміна Total@на Tr/@збереже ще 2 байти.
A Simmons

Або рівнозначно перевернути дві матриці, щоб рішення стало{}⋃Tr/@#=={100}&/@{#,#}&
A Simmons

@ASimmons, Так, це врятувало ще 2. Дякую!
Келлі Лоудер

6

k, 21 19 байт

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

Вихідні дані

  • 00b жоден
  • 10b зліва
  • 01b правильно
  • 11b і те й інше

Приклад:

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

редагувати: зменшити кількість байтів на 3 - функцію не потрібно вкладати в лямбда

редагувати: зменшити кількість рахунків на 2 - H / T @Simon Major


1
Насправді ви можете зберегти байт, додавши в лямбда: {min'100 = + / '(x; +: x)}
Майор Саймона

5

MATL , 12 байт

sG!sv!100=XA

Вихід - два значення нуля / одне. Перший вказує, чи є матриця ліво-стохастичним, другий, якщо він є право-стохастичним.

Спробуйте в Інтернеті! Або перевірити всі тестові випадки

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

Людина, котра 100 була дорогою, хоч хороша відповідь.
Чарівний восьминога Урн

5

Математика, 46 43 байти

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

Як і в інших відповідях, результати є

{False, False} для нестахастичного

{True, False} для лівостохастичних

{False, True} для право-стохастичних

{True, True} для подвійно стохастичних

Збережено 3 байти, перейшовши на форму оператора AllTrue


Використовуйте U + F3C7 (приватне використання) для\[Transpose]
u54112

Я вважав це, але вважав, що це менш просвітливо
A Simmons

Також @в кінці є додатково
u54112

4

PHP, 104 байти

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

Анонімна функція, що перегукується 0 => обидва, 1 => ліворуч, 2 => право, 3 => ні.
Використовуйте як:

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

Версія програми командного рядка в 114 байт:

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

Використовується як:

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

4

Пітон 2, 70 64 байт

Нічого божевільного тут немає, просто скористуючись zip щоб перенести матрицю :) Виходи такі:

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

А ось код :)

k=lambda m:all(sum(x)==100for x in m)
lambda n:k(n)+2*k(zip(*n))

Чи зірка в (* помилка?
hhh

1
@hhh Ні, це splatоператор :) По суті, це те, що дозволяє мені перенести матрицю :)
Каде

4

C #, 205 203 183 байт

Гольф:

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

Безголовка з коментарями:

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

Вихідний ключ: 1 - право стохастичне 2 - ліве стохастичне 3 - подвійне стохастичне 4 - жодне

Спробуйте: http://rextester.com/PKYS11433

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

EDIT2: Вкладені потрійні оператори. Кредити надходять до @Yodle.


2
if(e==1&&w==1)return 3;if(e==1)return 1;return w==1?2:4;Оскільки eі wможе бути лише 1 або 0, його можна змінити return w<<1|e;і перезначити жоден == 0.
Посилання Ng

1
Ви можете скоротити своє на 30, якщо перетворити деякі з цих ifвисловлювань у потрійні операції та просто повернути ціле число наприкінці. Idunno, якщо я повинен розмістити своє рішення, оскільки він такий подібний.
Йодл

@LinkNg Дуже приємно. Я не хочу писати код, не розуміючи. Я не знайомий з бінарними операторами.
paldir

@Yodle Дякую, я змінив своє рішення. Сміливо публікуйте свої, навіть якщо вони дуже схожі.
paldir

3

JavaScript (ES6), 83 байти

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

Навпаки, це не тільки виводить правильний стеахістичний результат зліва, але булі також перевернуто, тому вихід [false, true]все ще означає правий стеахістичний.


3

C # 6, 130 байт

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}для нестахастичних
{True, False}для лівостохастичних
{False, True}для правостохастичних
{True, True} для подвійно стохастичних

repl.it демонстрація

Безумовно

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


2

Піп , 17 байт

У несподіваному повороті це подання є функцією.

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

Повертає список двох 0/ 1значень: [0 0]= не стохастичний, [0 1]= лівий стохастичний, [1 0]= правий стохастичний, [1 1]= подвійно стохастичний. Спробуйте в Інтернеті!

Пояснення

{               }  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]

2

Діалог APL , 16 байт

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

{ }Пряме визначення функції (aka "dfn"), є аргументом

⍵(⍉⍵) матриця поряд з її транспозицією

змішайте їх в єдиний масив 2 × n × n

+/ підсумовуючи останню вісь, отримаємо матрицю 2 × n

100= яких елементів 100 (булеві 0 1)

∧/ "та" -відведення вздовж останньої осі, отримайте 2 булевих для лівої, правої стохастичної


2

C ++ 14, 139 136 133 130 байт

-3 байти для s=M.size(), -3 байти для повернення за еталонним параметром, -3 байти як безіменна лямбда

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

Передбачає, що вхід буде подібний vector<vector<int>> . Повертає 3,2,1,0 для подвійного, лівого, правого, жодного стохастичного.

Безголівки:

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);
  }
}
;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.