ready for regionals
All checks were successful
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 8s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 44s
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 2m46s

This commit is contained in:
yohlo
2026-03-07 01:22:21 -06:00
parent 569ea8833b
commit e67f6b073c
9 changed files with 353 additions and 95 deletions

View File

@@ -26,57 +26,63 @@ export function calculateGroupConfigurations(teamCount: number): GroupConfigOpti
const configs: GroupConfigOption[] = [];
for (let teamsPerGroup = 3; teamsPerGroup <= Math.min(6, teamCount); teamsPerGroup++) {
const numGroups = Math.floor(teamCount / teamsPerGroup);
const remainder = teamCount % teamsPerGroup;
const numGroupsFloor = Math.floor(teamCount / teamsPerGroup);
const numGroupsCeil = Math.ceil(teamCount / teamsPerGroup);
if (numGroups < 2) continue;
const groupOptions = new Set([numGroupsFloor, numGroupsCeil]);
if (remainder > numGroups) continue;
for (const numGroups of groupOptions) {
if (numGroups < 2) continue;
const groupsWithExtra = remainder;
const baseTeamsPerGroup = Math.floor(teamCount / numGroups);
const groupsWithExtra = teamCount % numGroups;
const groupsAtBaseSize = numGroups - groupsWithExtra;
const minGroupSize = groupsAtBaseSize > 0 ? teamsPerGroup : teamsPerGroup + 1;
const matchesGuaranteed = minGroupSize - 1;
const minGroupSize = baseTeamsPerGroup;
const maxGroupSize = baseTeamsPerGroup + (groupsWithExtra > 0 ? 1 : 0);
for (let advancePerGroup = 1; advancePerGroup <= Math.min(3, teamsPerGroup - 1); advancePerGroup++) {
const teamsAdvancing = numGroups * advancePerGroup;
if (minGroupSize < 3 || maxGroupSize > 6) continue;
if (teamsAdvancing < 4 || teamsAdvancing > 32) continue;
const matchesGuaranteed = minGroupSize - 1;
const knockoutSize = getNextPowerOfTwo(teamsAdvancing);
const wildcardsNeeded = knockoutSize - teamsAdvancing;
for (let advancePerGroup = 1; advancePerGroup <= Math.min(3, minGroupSize - 1); advancePerGroup++) {
const teamsAdvancing = numGroups * advancePerGroup;
if (wildcardsNeeded > teamsAdvancing / 2) continue;
if (teamsAdvancing < 4 || teamsAdvancing > 32) continue;
let totalGroupMatches = 0;
for (let i = 0; i < numGroups; i++) {
const groupSize = teamsPerGroup + (i < groupsWithExtra ? 1 : 0);
totalGroupMatches += (groupSize * (groupSize - 1)) / 2;
const knockoutSize = getNextPowerOfTwo(teamsAdvancing);
const wildcardsNeeded = knockoutSize - teamsAdvancing;
if (wildcardsNeeded > teamsAdvancing / 2) continue;
let totalGroupMatches = 0;
for (let i = 0; i < numGroups; i++) {
const groupSize = baseTeamsPerGroup + (i < groupsWithExtra ? 1 : 0);
totalGroupMatches += (groupSize * (groupSize - 1)) / 2;
}
const description = generateDescription({
num_groups: numGroups,
teams_per_group: baseTeamsPerGroup,
groups_with_extra: groupsWithExtra,
advance_per_group: advancePerGroup,
matches_guaranteed: matchesGuaranteed,
knockout_size: knockoutSize,
wildcards_needed: wildcardsNeeded,
});
configs.push({
num_groups: numGroups,
teams_per_group: baseTeamsPerGroup,
advance_per_group: advancePerGroup,
matches_guaranteed: matchesGuaranteed,
seeding_method: "random",
groups_with_extra: groupsWithExtra,
knockout_size: knockoutSize,
wildcards_needed: wildcardsNeeded,
total_group_matches: totalGroupMatches,
description,
});
}
const description = generateDescription({
num_groups: numGroups,
teams_per_group: teamsPerGroup,
groups_with_extra: groupsWithExtra,
advance_per_group: advancePerGroup,
matches_guaranteed: matchesGuaranteed,
knockout_size: knockoutSize,
wildcards_needed: wildcardsNeeded,
});
configs.push({
num_groups: numGroups,
teams_per_group: teamsPerGroup,
advance_per_group: advancePerGroup,
matches_guaranteed: matchesGuaranteed,
seeding_method: "random",
groups_with_extra: groupsWithExtra,
knockout_size: knockoutSize,
wildcards_needed: wildcardsNeeded,
total_group_matches: totalGroupMatches,
description,
});
}
}