Qui est le roi du tournoi?


13

Contexte

Considérez un tournoi à la ronde, dans lequel chaque concurrent joue un match contre tous les autres concurrents. Il n'y a pas de tirage, donc chaque match a un gagnant et un perdant. Un concurrent A est un roi du tournoi, si pour tous les concurrent B , soit A battu B ou A battre un autre concurrent C qui , à son tour battre B . Il peut être démontré que chaque tournoi a au moins un roi (bien qu'il puisse y en avoir plusieurs). Dans ce défi, votre tâche consiste à trouver les rois d'un tournoi donné.

Entrée et sortie

Votre entrée est une N × Nmatrice booléenne T, et éventuellement le nombre N ≥ 2de candidats. Chaque entrée T[i][j]représente le résultat du jeu entre les concurrents iet j, avec la valeur 1 représentant une victoire pour iet 0 une victoire pour j. Notez que T[i][j] == 1-T[j][i]si i != j. La diagonale de se Tcompose de 0.

Votre résultat sera la liste des rois du tournoi qui Treprésente, en utilisant une indexation basée sur 0 ou 1. L'ordre des rois n'est pas pertinent, mais il ne devrait pas y avoir de doublons.

L'entrée et la sortie peuvent être prises dans n'importe quel format raisonnable.

Règles et notation

Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.

Cas de test

Ces cas de test utilisent une indexation basée sur 0. Pour une indexation basée sur 1, incrémentez chaque valeur de sortie.

 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]

(Y a-t-il des temps d'exécution ou des limites de mémoire?) Peu importe. J'ai complètement mal compris la spécification.
Dennis

@Dennis Nope. Tant que votre programme fonctionnerait théoriquement avec un temps et une mémoire illimités, tout va bien.
Zgarb

Juste pour clarifier: T [a] [b] est la même correspondance que T [b] [a] mais vue sous un angle opposé, donc T [a] [b] ==! T [b] [a]
edc65

@ edc65 C'est une bonne observation. Je l'ai édité dans le défi.
Zgarb

Réponses:


9

Matlab, 36 35 29 octets

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

Voyons si ic'est un roi. Puis pour chacun jla valeur T[i][j]==1 OR there is a k such that T[i][k] * T[k][l] == 1. Mais la deuxième condition peut également être remplacée par sum_over_k(T[i][k] * T[k][l])>0, mais ce n'est qu'une entrée de la matrice T*T(si vous la considérez Tcomme une matrice). Le ORpeut ensuite être rejoué en ajoutant Tà ce résultat, il nous suffit donc de vérifier si les n-1valeurs de la ligne ide T*T+Tsont supérieures à zéro, pour voir si iest roi. C'est exactement ce que fait ma fonction.

(Il s'agit de MATLAB, donc les indices sont basés sur 1.)

Les matrices MATLAB doivent être codées avec des points-virgules comme délimiteurs de ligne:

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

Vous pouvez probablement économiser quelques octets en prenant le nombre de candidats en entrée, au lieu de le fairesize(T,1)
Luis Mendo

7

Gelée, 13 12 11 octets

a"€¹o/€oḅ1M

La sortie est basée sur 1. Essayez-le en ligne!

Alternativement, en utilisant des opérateurs au niveau du bit au lieu de la manipulation de tableaux:

×Ḅ|/€|ḄBS€M

Encore une fois, la sortie est basée sur 1. Essayez-le en ligne!

Contexte

Pour concurrent A , nous pouvons trouver tous les B tels que A TIRE C battement B en prenant toutes les lignes qui correspondent à un C tel que C a battu A . ICR le B e entrée du C e est 1 , nous avons que C a battu B .

Si nous calculons les OR logiques de toutes les entrées correspondantes des colonnes sélectionnées, nous obtenons un vecteur unique indiquant si A bat B par transitivité ou non. Enfin, ORing le vecteur résultant avec la ligne correspondante de la matrice d'entrée donne des booléens que ce soit A battu B , soit par transitivité ou directement.

En répétant cela pour chaque ligne, nous comptons le nombre de 1 dans chaque vecteur, calculant ainsi le nombre de candidats à chaque battement A. Le nombre maximum correspond aux rois du tournoi.

Comment ça fonctionne

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
Vous savez, les gens continuent de les poster et de dire x "octets", mais "ḅ" est-il vraiment encodé en 1 octet dans n'importe quel encodage standard? Désolé, mais je trouve ces langages basés sur la pile hyper-condensés complètement inintéressants car cela ressemble à de la triche pour assigner simplement toutes les fonctions imaginables à un caractère unicode.
MattPutnam

2
@MattPutnam Jelly utilise son propre encodage personnalisé. (De plus, il n'est pas basé sur la pile)
un spaghetto

2
@MattPutnam J'ai eu des sentiments similaires, mais ils ne nuisent pas du tout au golf traditionnel. Personne ne méprise les langues traditionnelles simplement parce qu'elles existent, et contrairement à d'autres sites SE, cela n'a pas exactement la 'cette réponse est objectivement meilleure que cette réponse'. En outre, bien que techniquement non autorisés, ils ne modifient pas la langue pour prendre en charge une question (bien qu'ils puissent, après coup, réaliser un raccourci utile pour les questions futures et en faire une opération).
corsiKa

Pourquoi ces algorithmes produisent-ils les rois?
xnor

@ Dennis Je vois maintenant, sa multiplication de matrice essentiellement booléenne se fait via la logique ou l'arithmétique des bits. La multiplication réelle de la matrice ne serait pas plus courte?
xnor

2

Python utilisant numpy, 54 octets

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

Prend une matrice numpy, produit une matrice de lignes numpy d'indices basés sur 0.

Une autre façon de penser à un roi est en tant que candidat pour lequel tous les candidats sont dans l'union du roi, du peuple que le roi a battu et du peuple que ce peuple a battu. Autrement dit, pour chaque concurrent, il y a un chemin de longueur au plus 2 du roi vers eux parmi la relation "beat".

La matrice I + M + M*Mcode les nombres de chemins de 0, 1 ou 2 pas de chaque source à chaque cible. Un joueur est un roi si sa rangée de cette matrice n'a que des entrées positives. Puisque 0 est Falsey, allnous indique si une ligne est entièrement différente de zéro. Nous appliquons cela à chaque ligne et produisons les indices des résultats non nuls.


Ressemble exactement à mon approche mais avec une interprétation différente, intéressant =)
flawr

2

JavaScript (ES6), 83 octets

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

Vous pouvez enregistrer 1 avec 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) mais cela signifie que vous devez produire 1 indexé, ce qui est une grave erreur
Charlie Wynn

2

MATL , 12 10 9 octets

Xy+HY^!Af

L'entrée est: d'abord le nombre de candidats, et sur une ligne séparée une matrice avec des lignes séparées par des points-virgules. La sortie est basée sur 1.

Par exemple, le cinquième cas de test a une entrée

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

et le dernier cas de test a une entrée

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]

Essayez-le en ligne!

Explication

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 octets

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

Appelez en utilisant:

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

Attention car la sortie est indexée sur 1 (enregistré quelques octets sans essayer de filtrer les 0 contre les fausses)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.