简体   繁体   English

动态获取/排序下一个多维数组元素

[英]Get/sort next multi-dimensional array element dynamically

I'm running through a great old brain fart currently and am stuck dynamically selecting the next "round match" that the winners of the below rounds will advance to: 我目前正在经历一个伟大的老脑屁并且动态地选择下一轮的获胜者将进入的下一个“圆形比赛”:

生成的梯子


The ladder above is dynamically generated, and what I'd like to do is figure out the next match ID. 上面的梯子是动态生成的,我想要做的就是找出下一个匹配ID。 I've got this as a POC currently, but it isn't sustainable if a competition ladder were to run up to 64/more: 我目前已将此作为POC,但如果竞争阶梯达到64 /更多,则不可持续:

$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 of achieving what the above without hard-coded variables ( $cases ) for example. 例如,有没有更简化的方法来实现上述没有硬编码变量( $cases )的内容。

Essentially the amount of "matches/pairs" are being halved as a ladder would be: 4 -> 2 -> 1 . 基本上,“匹配/对”的数量减半,因为梯子将是: 4 - > 2 - > 1

The above generates the correct ID's but it isn't expandable or dynamic; 以上产生了正确的ID,但它不是可扩展的或动态的;

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 required. 如果需要, 演示/上述代码的示例


Notes 笔记

  • There is no limit on "players/team" matches and this can be exponential, 4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc . “球员/球队”比赛没有限制,这可以是指数4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc
  • This will never happen/apply to the last round (Grand Final - 1 match) as there is no further round to advance to. 这将不会发生/适用于最后一轮(总决赛 - 1场比赛),因为没有进一步的进展。 ( easily limited by if($i == count($rounds)) {.... do not continue... ). 容易受if($i == count($rounds)) {.... do not continue... )的限制。
  • There is a possibility of multiple matches being run simultaneously, so the "next round ID" could not be lastId + 1 . 有可能同时运行多个匹配,因此“下一轮ID” 不能lastId + 1

Just math 只是数学

Keep in mind, that every round contains pow(2, Rounds - Round + 1) of teams and pow(2, Rounds - Round) of matches. 请记住,每一轮都包含战队pow(2, Rounds - Round + 1)和战队pow(2, Rounds - Round)比赛。 Just sum it as a geometric progression. 只需将其作为几何级数进行求和。

Number of matches taken before 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 . 圆形$round前的匹配数是几何级数 2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1) a=2^(rounds-1)r=1/2n=round-1 Its sum is 2^(rounds) - 2^(rounds+1-round) . 它的总和是2^(rounds) - 2^(rounds+1-round)

So match id and next match id are just functions of three arguments: pairnum , round , rounds . 所以匹配id和下一个匹配id只是三个参数的函数: pairnumroundrounds I moved its calculations into functions getMatchId and getNextId . 我将其计算移动到函数getMatchIdgetNextId

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

Its 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM