Php сортировка и создание команды

Рейтинг: 0Ответов: 1Опубликовано: 12.06.2023

Есть 3 переменных с массивами содержащими группы игроков, эти группы нельзя разделять $player1teams массивы групп из одного игрока

$player2teams массивы групп из двух игроков

$player3teams массивы групп из трех игроков.

Эти группы нельзя разделять так как они начинали игру вместе.

Из них мы должны составить другой массив содержащий списки укомплектованных команд. 3 команды по 3 игрока

    $teams[
        0 => [],
        1 => [],
        2 => []
    ]

Так же если это не возможно то должен быть исход

Вот пример данных:

    $player3teams = [
        0 => [
            "cUser1", "cUser2", "cUser3"
        ]
    ];
    
    $player2teams = [
        0 => [
            "cUser4", "cUser5"
        ],
        1 => [
            "dUser1", "dUser2"
        ]
    ];
    
    $player1teams = [
         0 => [
              "aUser1"
        ],
         1 => [
             "bUser1"
        ]
    ];

Другой вариант данных:

$player3teams = [
     0 => [
        "cUser1", "cUser2", "cUser3"
    ]
];

$player2teams = [
    0 => [
        "cUser4", "cUser5"
    ]
];

$player1teams = [
    0 => [
        "aUser1"
    ],
    1 => [
        "bUser1"
    ],
    2 => [
        "hUser1"
    ],
    3 => [
        "kUser1"
    ],
    
];

Тоесть нельзя разделять исходя из примера

  1. dUser1, dUser2
  2. cUser4, cUser5
  3. cUser1, cUser2, cUser3

Теперь задача составить из этих групп 3 команды по 3 игрока

Ответы

▲ 0

Всё достаточно просто. Как и написали в комментариях группы из трёх это уже готовые команды. Далее остаётся добавить игроков в группы по 2 человека и смерджить в группы по 3 для итогового списка. Если групп не хватает, то пробежаться по оставшимся участникам и объединить в группы.

Алгоритм ниже работает для разного кол-во групп. Меняете переменную $maxTeams и $maxPlayers, далее будет группировка по указанному кол-ву человек и команд.

Алгоритм:

Бежим по массиву из 2-х участников и добавляем к ним участников по одному человеку. При этом удаляем уже добавленного (array_pop). В результате в массиве по одному участнику остаются только те, которые не добавлены. Сколько надо добавить регулируется переменной $maxPlayers

Полученный массив мерджим с исходным по 3 ($maxPlayers) человека.

Проверяем набрали ли команды. Если нет проверяем хватает ли участников для доп набора

Сводим участников в плоский список для удобства итерации

Рекурсивно пробегаем по участникам, группируя их с помощью разбивки (array_chunk) по необходимому кол-ву ($maxPlayers).

Проверяем те команды которые получились полными. И добавляем их в итоговый список проверяя кол-во. Далее делим заново оставшихся участников и снова проверяем. Если участников по $maxPlayers больше не возможно сделать, то выходим из функции.

$player3teams = [
    // ["cUser1", "cUser2", "cUser3"]
];

$player2teams = [
    ["cUser4", "cUser5"],
    [ "dUser1", "dUser2"]
];

$player1teams = [
     ["aUser1"],
     ["bUser1"],
     ["aUser5"],
     ["aUser7"],
     ["bUser6"],
     ["bUser9"],
     ["bUser19"],
     ["bUser11"],
];

$maxTeams = 4;
$maxPlayers = 3;

$teams = array_map(function($players) use (&$player1teams, $maxPlayers) {
    $countPlayers = count($players);
    if (count($player1teams) && $countPlayers <= $maxPlayers) {
        for ($i = 0; $i < $maxPlayers - $countPlayers; $i++) {
            $player = array_pop($player1teams);
            $players = [...$players, ...$player];
            if (count($players) === $maxPlayers) break;
        }
    }
    return $players;
}, $player2teams);

$teams = [...$player3teams, ...$teams];

if (count($teams) === $maxTeams) {
    var_dump($teams);
    exit(1);
}

if (count($player1teams) < $maxPlayers) {
    echo "Не хватает игроков";
    exit(1);
}

$lastPlayers = [];
foreach ($player1teams as $team) {
    $lastPlayers = [...$lastPlayers, ...$team];
}

$createTeamsRecursive = function ($players) use (&$teams, $maxPlayers, $maxTeams, &$createTeamsRecursive) {
    $lastTeams = array_chunk($players, $maxPlayers);
    $canChunk = false;
    foreach ($lastTeams as $key => $team) {
        if (count($team) === $maxPlayers) {
            $teams[] = [...$team];
            if (count($teams) === $maxTeams) return $teams;
            unset($lastTeams[$key]);
            $canChunk = true;
        }
    }

    if (!count($lastTeams) || !$canChunk) {
        return $teams;
    }

    return $createTeamsRecursive($lastTeams);
};
$createTeamsRecursive($lastPlayers);
var_dump($teams);