Kto jest królem turnieju?

13

tło

Rozważ turniej typu round-robin, w którym każdy zawodnik gra w jedną grę z każdym innym zawodnikiem. Nie ma remisów, więc każda gra ma zwycięzcę i przegranego. Uczestnik jest król turnieju, jeśli dla każdej innej zawodnik B , albo pokonać B lub pobić kolejny zawodnik C , który z kolei rytm B . Można wykazać, że każdy turniej ma co najmniej jednego króla (choć może ich być kilka). W tym wyzwaniu Twoim zadaniem jest znaleźć królów danego turnieju.

Wejście i wyjście

Twój wkład to N × Nmacierz boolowska Ti opcjonalnie liczba N ≥ 2uczestników. Każdy wpis T[i][j]reprezentuje wynik meczu pomiędzy zawodników ii j, o wartości 1 reprezentujących wygrać ii 0 wygraną dla j. Zauważ, że T[i][j] == 1-T[j][i]jeśli i != j. Przekątna Tskłada się z zer.

Twój wynik będzie listą królów w turnieju, która Treprezentuje, przy użyciu indeksowania 0 lub 1. Kolejność królów nie ma znaczenia, ale nie powinno być duplikatów.

Zarówno dane wejściowe, jak i wyjściowe można przyjmować w dowolnym rozsądnym formacie.

Zasady i punktacja

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Przypadki testowe

Te przypadki testowe wykorzystują indeksowanie oparte na 0. W przypadku indeksowania opartego na 1, zwiększaj każdą wartość wyjściową.

 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
źródło
(Czy są jakieś limity czasu działania lub pamięci?) Nieważne. Całkowicie źle zrozumiałem specyfikację.
Dennis
@Dennis Nope. Tak długo, jak Twój program teoretycznie działałby, mając nieograniczony czas i pamięć, nic ci nie jest.
Zgarb,
Żeby wyjaśnić: T [a] [b] jest identyczne jak T [b] [a], ale oglądane z przeciwnego kąta, więc T [a] [b] ==! T [b] [a]
edc65
@ edc65 To dobra obserwacja. Zredagowałem to w wyzwaniu.
Zgarb

Odpowiedzi:

9

Matlab, 36 35 29 bajtów

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

Dowiedzmy się, czy ijest królem. Następnie dla każdej jwartości T[i][j]==1 OR there is a k such that T[i][k] * T[k][l] == 1. Ale drugi warunek można również zastąpić sum_over_k(T[i][k] * T[k][l])>0, ale jest to tylko wpis macierzy T*T(jeśli uważa się ją Tza macierz). ORMogą być następnie odtwarzane przez dodanie Tdo tego wyniku, więc po prostu trzeba sprawdzić, czy n-1wartości rzędu iod T*T+Tjest większa od zera, aby zobaczyć, czy ijest królem. To właśnie robi moja funkcja.

(To jest MATLAB, więc indeksy są oparte na 1).

Matryce MATLAB powinny być kodowane średnikami jako ogranicznikami linii:

[[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]] 
wada
źródło
Prawdopodobnie możesz zaoszczędzić kilka bajtów, biorąc liczbę uczestników jako dane wejściowe, zamiast robićsize(T,1)
Luis Mendo
7

Galaretka, 13 12 11 bajtów

a"€¹o/€oḅ1M

Wyjście jest oparte na 1. Wypróbuj online!

Alternatywnie, używając operatorów bitowych zamiast manipulacji tablicami:

×Ḅ|/€|ḄBS€M

Ponownie, wyjście jest oparte na 1. Wypróbuj online!

tło

Dla zawodnik A , możemy znaleźć wszystkie B takie, że dudnienie C rytmu B poprzez wszystkie wiersze, które odpowiadają C takie, że C pokonać . IFR w B th wpisu C th jest 1 , że mamy C pokonać B .

Jeśli obliczymy logiczne OR wszystkich odpowiednich wpisów wybranych kolumn, otrzymamy pojedynczy wektor wskazujący, czy A bicie B przez przechodniość, czy nie. Na koniec ORing otrzymanego wektora odpowiednim wierszem macierzy wejściowej daje booleanom, czy A bije B , albo przez przechodniość, albo bezpośrednio.

Powtarzając to dla każdego rzędu, liczymy liczbę 1 w każdym wektorze, dlatego obliczamy liczbę zawodników w każdym uderzeniu A. Maksymalne liczby odpowiadają królom turnieju.

Jak to działa

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.
Dennis
źródło
1
Wiesz, ludzie wciąż je publikują i mówią „bajty” x, ale czy „ḅ” naprawdę jest zakodowane w 1 bajcie w jakimkolwiek standardowym kodowaniu? Przepraszam, ale uważam, że te hiper-skondensowane języki oparte na stosie są całkowicie nieciekawe, ponieważ czuję się, jakby oszustwo przypisywało każdą możliwą funkcję znakowi Unicode.
MattPutnam
2
@MattPutnam Jelly używa własnego niestandardowego kodowania. (Również nie jest oparty na stosie)
spaghetto
2
@MattPutnam Mam podobne odczucia, ale wcale nie umniejszają tradycyjnego golfa. Nikt nie patrzy na tradycyjne języki tylko dlatego, że istnieją, i w przeciwieństwie do innych witryn SE, nie ma to dokładnie „ta odpowiedź jest zdecydowanie lepsza od tej odpowiedzi”. Ponadto, chociaż technicznie nie są niedozwolone, nie zmieniają języka w celu obsługi pytania (chociaż mogą po tym zdać sobie sprawę z przydatnego skrótu do przyszłych pytań i uczynić z tego operację).
corsiKa
Dlaczego te algorytmy generują królów?
xnor
@Dennis Widzę teraz, że jest to w zasadzie logiczne mnożenie macierzy za pomocą logiki lub arytmetyki bitów. Rzeczywiste mnożenie macierzy nie byłoby krótsze?
xnor
2

Python używa numpy, 54 bajtów

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

Pobiera macierz numpy, generuje macierz numpy wierszy wskaźników opartych na 0.

Innym sposobem myślenia o królu jest uczestnik, w którym wszyscy uczestnicy są w związku króla, ludu, który król pokonał, i ludzi, których pokonali ludzie. Innymi słowy, dla każdego uczestnika istnieje relacja długości co najwyżej 2 od króla do nich wśród relacji „beat”.

Matryca I + M + M*Mkoduje liczbę ścieżek 0, 1 lub 2 kroków od każdego źródła do każdego celu. Gracz jest królem, jeśli jego rząd tej macierzy ma tylko pozytywne wpisy. Ponieważ 0 to Falsey, allmówi nam, czy cały wiersz jest niezerowy. Stosujemy to do każdego wiersza i wyprowadzamy wskaźniki niezerowych wyników.

xnor
źródło
Wygląda dokładnie tak, jak moje podejście, ale z inną interpretacją, ciekawe =)
wada
2

JavaScript (ES6), 83 bajty

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
Neil
źródło
Możesz zapisać 1 za pomocą a => a.map ((b, i) => b. Co ((c, j) => c | i == j | b.some ((d, k) => d & a [ k] [j])) && i + 1) .filter (a => a), ale oznacza to, że musisz generować indeks 1, co jest poważnym szumem
Charlie Wynn
2

MATL , 12 10 9 bajtów

Xy+HY^!Af

Dane wejściowe to: najpierw liczba uczestników, a na osobnej linii macierz z wierszami oddzielonymi średnikami. Wyjście jest oparte na 1.

Na przykład piąty przypadek testowy ma dane wejściowe

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

a ostatni przypadek testowy ma dane wejściowe

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]

Wypróbuj online!

Wyjaśnienie

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
Luis Mendo
źródło
1
MATL <Galaretka \ m /
flawr
1

JavaScript 136 131 121 121 112 bajtów

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

Zadzwoń za pomocą:

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

uważaj, ponieważ dane wyjściowe są indeksowane 1 (zapisano kilka bajtów, nie próbując odfiltrować 0 względem fal)

Charlie Wynn
źródło