Get / sort the next multidimensional array element dynamically

At the moment, I am faced with a huge old brain fart and dynamically choose the next โ€œround matchโ€, which the winners of the next rounds will advance to:

generated staircase


The stairs above are dynamically generated, and I would like to know the next match identifier. Currently, I have received this as a POC, but it is not sustainable if the competition ladder must work up to 64 or more:

$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 /> "; } } 

Is there a more simplified way to achieve what is stated above without hardcoded variables ( $cases ).

Essentially, the number of matches / pairs is halved up the stairs: 4 โ†’ 2 โ†’ 1 .

The above code generates the correct identifier, but it is not extensible or dynamic;

 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 of the above code, if necessary.


Notes

  • There are no restrictions on players / teams matches, and this can be exponential, 4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc
  • This will never happen and will not apply to the last round (final match - 1 ), since no further round is needed. (easily limited to if($i == count($rounds)) {.... do not continue... ).
  • It is possible to run multiple matches at the same time, so the "next round identifier" may not be lastId + 1 .
+5
source share
1 answer

Math only

Keep in mind that each round contains pow(2, Rounds - Round + 1) teams and pow(2, Rounds - Round) matches. Just sum it up as a geometric progression.

The number of matches before the round $round is 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) .

Thus, the match identifier and the following match identifier are simply functions of three arguments: pairnum , round , rounds . I translated the calculations into getMatchId and getNextId .

Example

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

His results

 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 
+1
source

Source: https://habr.com/ru/post/1264221/


All Articles