Кто король турнира?

13

Фон

Рассмотрим круговой турнир, в котором каждый участник играет одну игру против каждого другого участника. Нет ничьих, поэтому в каждой игре есть победитель и проигравший. Спортсмен является королем турнира, если для любой другой конкурирующей B , либо бить B , или избил другой участник C , который , в своей очереди бить B . Можно показать, что в каждом турнире есть как минимум один король (хотя их может быть несколько). В этом задании ваша задача - найти королей данного турнира.

Вход и выход

Ваш ввод представляет собой N × Nлогическую матрицу Tи, необязательно, количество N ≥ 2участников. Каждая запись T[i][j]представляет результат игры между участниками iи jсо значением 1 представляет выигрыш за, iа 0 - выигрыш за j. Обратите внимание, что T[i][j] == 1-T[j][i]если i != j. Диагональ Tсостоит из 0 с.

Ваш вывод должен представлять собой список королей в турнире, который Tиспользует индексацию на основе 0 или 1. Порядок королей не имеет значения, но не должно быть дубликатов.

Как ввод, так и вывод могут быть приняты в любом разумном формате.

Правила и оценки

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

Контрольные примеры

В этих тестах используется индексирование на основе 0. Для индексации на основе 1 увеличивайте каждое выходное значение.

 2 [[0,0],[1,0]] -> [1]
 3 [[0,1,0],[0,0,0],[1,1,0]] -> [2]
 3 [[0,1,0],[0,0,1],[1,0,0]] -> [0,1,2]
 4 [[0,1,1,1],[0,0,1,0],[0,0,0,0],[0,1,1,0]] -> [0]
 4 [[0,1,1,0],[0,0,1,0],[0,0,0,1],[1,1,0,0]] -> [0,2,3]
 5 [[0,1,0,0,1],[0,0,0,0,1],[1,1,0,0,0],[1,1,1,0,1],[0,0,1,0,0]] -> [3]
 5 [[0,1,0,1,0],[0,0,1,1,1],[1,0,0,0,0],[0,0,1,0,1],[1,0,1,0,0]] -> [0,1,4]
 5 [[0,0,0,0,0],[1,0,1,1,0],[1,0,0,0,1],[1,0,1,0,1],[1,1,0,0,0]] -> [1,3,4]
 6 [[0,0,0,0,0,0],[1,0,1,1,0,0],[1,0,0,1,1,0],[1,0,0,0,1,1],[1,1,0,0,0,1],[1,1,1,0,0,0]] -> [1,2,3,4,5]
 6 [[0,0,1,1,1,0],[1,0,0,1,1,1],[0,1,0,0,1,0],[0,0,1,0,0,1],[0,0,0,1,0,1],[1,0,1,0,0,0]] -> [0,1,2,3,5]
 6 [[0,1,1,0,0,1],[0,0,0,1,0,1],[0,1,0,1,1,0],[1,0,0,0,1,1],[1,1,0,0,0,0],[0,0,1,0,1,0]] -> [0,1,2,3,4,5]
 8 [[0,0,1,1,0,1,1,1],[1,0,1,0,1,1,0,0],[0,0,0,1,1,0,0,0],[0,1,0,0,0,1,0,0],[1,0,0,1,0,1,0,0],[0,0,1,0,0,0,1,0],[0,1,1,1,1,0,0,1],[0,1,1,1,1,1,0,0]] -> [0,1,4,6,7]
20 [[0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1],[1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1],[0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1],[0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1],[1,0,1,0,0,0,0,1,1,0,1,1,1,0,1,1,1,1,0,1],[0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1],[0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,0],[1,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,1,0],[1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1],[1,0,1,0,1,0,1,1,0,0,1,0,0,0,0,1,0,1,1,1],[1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0],[0,1,1,0,0,1,1,0,0,1,0,0,1,1,1,1,1,0,1,1],[0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1],[1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1],[0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1],[0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,1],[0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1],[0,0,1,0,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1],[1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,0]] -> [0,1,3,4,5,7,8,11,15,17,18]
Zgarb
источник
(Есть ли время выполнения или ограничения памяти?) Я совершенно не понял спецификацию.
Денис
@ Денис Нету. Пока ваша программа теоретически будет работать без ограничений по времени и памяти, все в порядке.
Згарб
Просто для пояснения: T [a] [b] совпадает с T [b] [a], но если смотреть под противоположным углом, поэтому T [a] [b] ==! T [b] [a]
edc65
@ edc65 Это хорошее наблюдение. Я отредактировал это в вызов.
Згарб

Ответы:

9

Matlab, 36 35 29 байт

@(T,N)find(sum(T*T>-T,2)>N-2)

Давайте выясним, iявляется ли король. Тогда для каждого jзначения T[i][j]==1 OR there is a k such that T[i][k] * T[k][l] == 1. Но второе условие также может быть заменено sum_over_k(T[i][k] * T[k][l])>0, но это всего лишь элемент матрицы T*T(если вы рассматриваете Tкак матрицу). ORЗатем может быть переигран, добавив Tк этому результату, поэтому мы просто должны проверить , если n-1значения строки iиз T*T+Tбольше нуля, чтобы увидеть ли iкороль. Это именно то, что делает моя функция.

(Это MATLAB, поэтому индексы основаны на 1).

Матрицы MATLAB должны быть закодированы точкой с запятой в качестве разделителей строк:

[[0,0,0,0,0];[1,0,1,1,0];[1,0,0,0,1];[1,0,1,0,1];[1,1,0,0,0]] 
flawr
источник
Вероятно, вы можете сэкономить несколько байтов, взяв количество участников вместо вводаsize(T,1)
Луис Мендо,
7

Желе, 13 12 11 байт

a"€¹o/€oḅ1M

Выход основан на 1. Попробуйте онлайн!

Альтернативно, используя побитовые операторы вместо манипулирования массивом:

×Ḅ|/€|ḄBS€M

Опять же, вывод на основе 1. Попробуйте онлайн!

Фон

Для конкурирующей А , мы можем найти все B такой , что бить C биений B , принимая все строки , которые соответствуют C такой , что C бить . Если г на B - й вход в C - й является 1 , мы получаем , что C бить B .

Если мы вычислим логические ИЛИ для всех соответствующих записей выбранных столбцов, мы получим один вектор, указывающий, превосходит ли А транзитивность В или нет. Наконец, ИЛИ получившийся вектор с соответствующей строкой входной матрицы дает булевы значения: A, бить ли B , транзитивностью или напрямую.

Повторяя это для каждой строки, мы подсчитать количество 1 -х в каждом векторе, поэтому вычисления количества участников каждый биений. Максимальное количество соответствует королям турнира.

Как это устроено

a"€¹o/€oḅ1M  Main link. Argument: M (matrix)

   ¹         Yield M.
  €          For each row of M:
a"           Take the logical AND of each entry of that row and the corr. row of M.
    o/€      Reduce each resulting matrix by logical OR.
       o     Take the logical OR of the entries of the resulting maxtrix and the
             corr. entries of M.
        ḅ1   Convert each row from base 1 to integer, i.e. sum its elements.
          M  Get all indices of maximal sums.
×Ḅ|/€|ḄBS€M  Main link. Argument: M (matrix)

 Ḅ           Convert each row of M from base 2 to integer. Result: R
×            Multiply the entries of each column of M by the corr. integer.
  |/€        Reduce each row fo the resulting matrix by bitwise OR.
     |Ḅ      Bitwise OR the results with R.
       BS€   Convert to binary and reduce by sum.
             This counts the number of set bits for each integer.
          M  Get all indices of maximal popcounts.
Деннис
источник
1
Вы знаете, люди продолжают публиковать их и произносить x "байтов", но действительно ли код "ḅ" кодируется в 1 байт в любой стандартной кодировке? Извините, но я нахожу эти языки с гиперконденсированными стеками совершенно неинтересными, потому что кажется обманом просто назначать все мыслимые функции символам юникода.
MattPutnam
2
@MattPutnam Jelly использует свою собственную кодировку. (Также это не основано на стеке)
спагетто
2
@MattPutnam У меня были подобные чувства, но они ничуть не отвлекают от традиционного гольфа. Никто не смотрит свысока на традиционные языки только потому, что они существуют, и в отличие от других сайтов SE, у этого точно нет «этот ответ объективно лучше, чем этот ответ». Кроме того, хотя технически это не запрещено, они не изменяют язык для поддержки вопроса (хотя после этого они могут реализовать полезный ярлык для будущих вопросов и сделать это операцией).
CorsiKa
Почему эти алгоритмы выводят королей?
xnor
@ Денис Теперь я вижу, что это умножение на булеву матрицу с помощью логики или битовой арифметики. Фактическое умножение матриц не будет короче?
xnor
2

Python, использующий numpy, 54 байта

import numpy
lambda M:(M**0+M+M*M).all(1).nonzero()[0]

Принимает числовую матрицу, выводит числовую матрицу строк с индексами на основе 0.

Другой способ думать о короле - это соперник, ради которого все участники находятся в союзе короля, люди, которых избил король, и люди, которых избили эти люди. Другими словами, для каждого участника есть путь длиной не более 2 от короля к ним среди отношения «бит».

Матрица I + M + M*Mкодирует количество путей из 0, 1 или 2 шагов от каждого источника к каждой цели. Игрок является королем, если в его строке этой матрицы есть только положительные записи. Так как 0 - Falsey, allговорит нам, является ли строка ненулевой. Мы применяем это к каждой строке и выводим индексы ненулевых результатов.

XNOR
источник
Выглядит так же, как мой подход, но с другой интерпретацией, интересно =)
flawr
2

JavaScript (ES6), 83 байта

a=>a.map((b,i)=>b.every((c,j)=>c|i==j|b.some((d,k)=>d&a[k][j]))&&r.push(i),r=[])&&r
Нил
источник
Вы можете сохранить 1 с помощью a => a.map ((b, i) => b.every ((c, j) => c | i == j | b.some ((d, k) => d & a [ k] [j])) && i + 1) .filter (a => a), но это означает, что вы должны вывести 1-индексированный, что является серьезным обломом
Чарли Уинн
2

MATL , 12 10 9 байт

Xy+HY^!Af

Входные данные: сначала число участников, а в отдельной строке - матрица со строками, разделенными точками с запятой. Выход основан на 1.

Например, пятый контрольный пример имеет вход

4
[0,1,1,0; 0,0,1,0; 0,0,0,1; 1,1,0,0]

и последний контрольный пример имеет вход

20
[0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1; 1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1; 0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1; 0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1; 1,0,1,0,0,0,0,1,1,0,1,1,1,0,1,1,1,1,0,1; 0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1; 0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,0; 1,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,1,0; 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1; 1,0,1,0,1,0,1,1,0,0,1,0,0,0,0,1,0,1,1,1; 1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0; 0,1,1,0,0,1,1,0,0,1,0,0,1,1,1,1,1,0,1,1; 0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1; 1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1; 0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1; 0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,1; 0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1; 0,0,1,0,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1; 1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0; 0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,0]

Попробуйте онлайн!

объяснение

Xy    % Implicitly take input: number. Push identity matrix with that size
+     % Implicitly take input: matrix. Add to identity matrix
HY^   % Matrix square
!     % Transpose
A     % Row vector with true entries for columns that contain all nonzero values
f     % Indices of nonzero values
Луис Мендо
источник
1
MATL <Jelly \ m /
flawr
1

Javascript 136 131 121 112 байтов

(n,m)=>m.map((a,k)=>eval(a.map((o,i)=>o||eval(a.map((p,j)=>p&&m[j][i]).join`|`)).join`+`)>n-2&&k+1).filter(a=>a)

Звоните используя:

f=(n,m)=>m.map((a,k)=>eval(a.map((o,i)=>o||eval(a.map((p,j)=>p&&m[j][i]).join`|`)).join`+`)>n-2&&k+1).filter(a=>a)

f(20,[[0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1],
     [1,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1],
     [0,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1],         
     [0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1],
     [1,0,1,0,0,0,0,1,1,0,1,1,1,0,1,1,1,1,0,1],         
     [0,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1],
     [0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,0],         
     [1,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,1,0],
     [1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1],         
     [1,0,1,0,1,0,1,1,0,0,1,0,0,0,0,1,0,1,1,1],
     [1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0],         
     [0,1,1,0,0,1,1,0,0,1,0,0,1,1,1,1,1,0,1,1],
     [0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1],         
     [1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1],
     [0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1],         
     [0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,1],
     [0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1],         
     [0,0,1,0,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1],
     [1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0],             
     [0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,0]])

осторожность, потому что выходные данные индексируются 1 (сохранено несколько байтов, не пытающихся отфильтровывать 0s против false)

Чарли Винн
источник