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

Dar*_*ren 5 php arrays multidimensional-array

我目前正在经历一个伟大的老脑屁并且动态地选择下一轮的获胜者将进入的下一个"圆形比赛":

生成的梯子


上面的梯子是动态生成的,我想要做的就是找出下一个匹配ID.我目前已将此作为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 /> ";
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更简单的方法来实现上面没有硬编码变量($cases例如)的内容.

基本上,"匹配/对"的数量减少了一半,因为梯子将是:4- > 2- > 1.

以上产生了正确的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...
Run Code Online (Sandbox Code Playgroud)

如果需要,演示/上述代码的示例.


笔记

  • "球员/球队"比赛没有限制,这可能是指数级的4, 6, 8, 10, 12, 14, 16, 18....32, 34...64...etc.
  • 这将永远不会发生/适用于上一轮(总决赛 - 1比赛),因为没有进一步的进展.(很容易受到限制if($i == count($rounds)) {.... do not continue...).
  • 目前正在同时运行多个比赛的可能性,因此,"下一轮ID"可能不会lastId + 1.

shu*_*van 1

只是数学

请记住,每一轮都包含pow(2, Rounds - Round + 1)球队和pow(2, Rounds - Round)比赛。只需将其总结为几何级数即可。

每轮比赛前的比赛场数以, ,$round几何级数 。其总和为.2^(rounds-1) + 2^(rounds-2) + ... 2^(rounds - round + 1)a=2^(rounds-1)r=1/2n=round-12^(rounds) - 2^(rounds+1-round)

所以 match id 和 next match id 只是三个参数的函数:pairnum, round, rounds。我将其计算转移到函数getMatchId和中getNextId

例子

<?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";
    }
}
Run Code Online (Sandbox Code Playgroud)

其结果

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
Run Code Online (Sandbox Code Playgroud)