count() < 2) { return; } $assignments = []; $newParticipantIds = $participants ->filter(fn($p) => $p->is_unmatched) ->pluck('id') ->shuffle() ->all(); $desperateGiverIds = $participants ->filter(fn($p) => $p->is_desperate && !$p->hasReceiver()) ->pluck('id') ->shuffle() ->all(); $desperateReceiverIds = $participants ->filter(fn($p) => $p->is_desperate && !$p->hasGiver()) ->pluck('id') ->shuffle() ->all(); while (!empty($desperateGiverIds) && !empty($desperateReceiverIds)) { $giverId = array_shift($desperateGiverIds); $receiverId = array_shift($desperateReceiverIds); if ($giverId === $receiverId) { array_unshift($desperateReceiverIds, $receiverId); continue; } $assignments[$giverId] = $receiverId; } $newCount = count($newParticipantIds); if ($newCount >= 2) { for ($i = 0; $i < $newCount; $i++) { $currentId = $newParticipantIds[$i]; $nextId = $newParticipantIds[($i + 1) % $newCount]; $assignments[$currentId] = $nextId; } } foreach ($assignments as $giverId => $receiverId) { Participant::where('id', $giverId)->update([ 'giving_id' => $receiverId, ]); } } }