2017-02-15 4 views
5

Je suis en cours d'exécution à travers un grand vieux fart cerveau actuellement et je suis coincé sélectionner dynamiquement le prochain « match de premier tour » que les gagnants des séries ci-dessous avanceront à:Obtenir/trier élément suivant de tableau multidimensionnel dynamique

generated ladder


l'échelle est généré dynamiquement ci-dessus, et ce que je voudrais faire est de déterminer le prochain ID de match. J'ai cela comme un POC actuellement, mais ce n'est pas durable si une échelle de la concurrence devait courir jusqu'à 64/plus:

$ar = [ 
1 => [ 
    ['id' => 1,'name' => 'round1, pair 1'], 
    ['id' => 2,'name' => 'round1, pair 2'], 
    ['id' => 3,'name' => 'round1, pair 3'], 
    ['id' => 4,'name' => 'round1, pair 4'], 
], 
2 => [ 
    ['id' => 5,'name' => 'round2, pair 1'], 
    ['id' => 6,'name' => 'round2, pair 2'], 
] 
]; 

$cases = [0, 0, 1, 1, 2, 2]; 

foreach($ar as $i => $round) { 

    foreach($round as $_i => $r) { 
     echo $r['name'] . " & NEXT_MATCH_ID::> " . $ar[($i + 1)][$cases[$_i]]['id'] . "<br /> "; 
    } 
} 

est-il un moyen plus simple de réaliser ce qui précède sans Hard- par exemple des variables codées ($cases). Essentiellement, la quantité de "correspondances/paires" est divisée par deux: 20 4 ->2 ->1.

Ce qui précède génère les ID corrects, mais il n'est pas extensible ou dynamique;

round1, pair 1 & NEXT_MATCH_ID::> 5 
round1, pair 2 & NEXT_MATCH_ID::> 5 
round1, pair 3 & NEXT_MATCH_ID::> 6 
round1, pair 4 & NEXT_MATCH_ID::> 6 
round2, pair 1 & NEXT_MATCH_ID::> ... 
round2, pair 2 & NEXT_MATCH_ID::> ... 
//......etc etc... 

Demo/ Example du code ci-dessus si nécessaire.


Remarques

  • Il n'y a pas de limite sur les matchs "joueurs/équipe" et cela peut être exponentielle, 4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc.
  • Ceci n'arrivera jamais/s'appliquera au dernier tour (Grande Finale - match 1) car il n'y a pas d'autre tour à avancer. (facilement limité par if($i == count($rounds)) {.... do not continue...).
  • Il est possible que plusieurs correspondances soient exécutées simultanément, de sorte que "l'ID du prochain rond" puisse et non être lastId + 1.
+1

id Prochain match peut être calculé à partir de la dernière id du tour et l'indice de paire en cours: '$ nextId = $ roundLastId + 1 + (int) floor ($ pairIndex/2); Btw. Nombre de paires doivent être (rempli à) la puissance de 2 (2,4,8,16 ...). – shudder

+0

@shudder Ce serait presque correct! mais il pourrait y avoir plusieurs matches en cours avec différents ID comme "ID du prochain tour", d'où le POC que j'ai traversé: P – Darren

+0

Dans ce cas, vous ne pouvez pas trouver l'ID de correspondance suivant avec l'algorithme, car il n'est pas déterministe. Vous devez d'abord le résoudre au niveau des données. Avoir le champ 'next_match' à l'intérieur de la paire, en utilisant l'ID ladder/round commun (afin de pouvoir calculer l'ID de correspondance dans le même ladder/round) ou si vous n'avez pas de base de données relationnelle. – shudder

Répondre

1

Juste mathématiques

Gardez à l'esprit que chaque tour contient pow(2, Rounds - Round + 1) des équipes et pow(2, Rounds - Round) des matches. Il suffit de le résumer comme une progression géométrique.

Nombre de matchs prises avant $round tour est un geometric progression2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1) avec a=2^(rounds-1), r=1/2, n=round-1. Sa somme est 2^(rounds) - 2^(rounds+1-round). Donc l'id de correspondance et l'identificateur de correspondance suivant sont juste des fonctions de trois arguments: pairnum, round, rounds. J'ai déplacé ses calculs dans les fonctions getMatchId et getNextId.

Exemple

<?php 
// just matchesInPreviousRounds + parnum 
function getMatchId($pairnum, $round, $rounds) { 
    // matchesInPreviousRounds - is a sum of a geometric progression 
    // 2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1) 
    // with a=2^(rounds-1), r=1/2, n = round-1 
    // its sum is 2^(rounds) - 2^(rounds+1-round) 
    $inPreviousRounds = $round > 1 ? (pow(2, $rounds) - pow(2, $rounds + 1 - $round)) : 0; 

    $id = $inPreviousRounds + $pairnum; 

    return (int)$id; 
} 

// next id is last id of a round + half a pairnum. 
function getNextId($pairnum, $round, $rounds) { 
    if($round === $rounds) { 
     return false; 
    } 

    $matchesInThisAndPreviousRounds = pow(2, $rounds) - pow(2, $rounds - $round); 

    $nextid = $matchesInThisAndPreviousRounds + ceil($pairnum/2); 

    return (int)$nextid; 
} 

$divide = 64; // for 1/64 at the start 
$power = round(log($divide)/log(2)); // get 6 for 64 
$rounds = (int) $power + 1; 


for($round = 1; $round <= $rounds; $round++) { 
    // every round contains 2^($rounds - $round + 1) of teams 
    // and has 2^($rounds - $round) of matches 
    $teamsLeft = pow(2, $rounds - $round + 1); 
    $pairsLeft = pow(2, $rounds - $round); 


    for($pairnum = 1; $pairnum <= $pairsLeft; $pairnum++) { 
     $id = getMatchId($pairnum, $round, $rounds); 
     $nextid = getNextId($pairnum, $round, $rounds); 

     echo "Round $round, pair $pairnum, id $id "; 
     echo "winner goes to " . $nextid ? $nextid : "A BAR" . "\n"; 
    } 
} 

Ses résultats

Round 1, pair 1, id 1, winner goes to 65 
Round 1, pair 2, id 2, winner goes to 65 
... 
Round 1, pair 62, id 62, winner goes to 95 
Round 1, pair 63, id 63, winner goes to 96 
Round 1, pair 64, id 64, winner goes to 96 
Round 2, pair 1, id 65, winner goes to 97 
Round 2, pair 2, id 66, winner goes to 97 
... 
Round 2, pair 29, id 93, winner goes to 111 
Round 2, pair 30, id 94, winner goes to 111 
Round 2, pair 31, id 95, winner goes to 112 
Round 2, pair 32, id 96, winner goes to 112 
Round 3, pair 1, id 97, winner goes to 113 
Round 3, pair 2, id 98, winner goes to 113 
... 
Round 3, pair 13, id 109, winner goes to 119 
Round 3, pair 14, id 110, winner goes to 119 
Round 3, pair 15, id 111, winner goes to 120 
Round 3, pair 16, id 112, winner goes to 120 
Round 4, pair 1, id 113, winner goes to 121 
Round 4, pair 2, id 114, winner goes to 121 
... 
Round 4, pair 7, id 119, winner goes to 124 
Round 4, pair 8, id 120, winner goes to 124 
Round 5, pair 1, id 121, winner goes to 125 
Round 5, pair 2, id 122, winner goes to 125 
Round 5, pair 3, id 123, winner goes to 126 
Round 5, pair 4, id 124, winner goes to 126 
Round 6, pair 1, id 125, winner goes to 127 
Round 6, pair 2, id 126, winner goes to 127 
Round 7, pair 1, id 127, winner goes to A BAR 
+0

Wow, acclamations mate! – Darren