diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2026-09-23 20:53:49 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2026-09-23 20:53:49 +0200 |
| commit | d836114025efccd2c4098e5537b7376998a74213 (patch) | |
| tree | bcedcd4162f80930745f932d2534f103f443ebc1 /src | |
| parent | 1498d1b09bbb22211e9d720669833c0afde95b92 (diff) | |
| download | bycs-sol-d836114025efccd2c4098e5537b7376998a74213.tar.gz bycs-sol-d836114025efccd2c4098e5537b7376998a74213.zip | |
mass-graduation: fix selection of mandatory graduations
The previous algorithm did compare all graduations to the one with the
most mandatory changes.
However, the amount of mandatory changes can differ during normal
operation by two. Therefore, the pool of candidates consists
of graduations with one or two fewer mandatory changes than the maximum.
This is fixed by selecting as many graduations from the group with
the next fewest mandatory changes as possible.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mass-graduation.js | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/src/mass-graduation.js b/src/mass-graduation.js index 46c4efe..69bbf07 100644 --- a/src/mass-graduation.js +++ b/src/mass-graduation.js @@ -33,27 +33,31 @@ function shuffleArray(array) { function chooseMandatory(graduations) { graduations.sort((g1, g2) => g1.mandatory - g2.mandatory); - // Get all graduations with smaller mandatory amount than the one with the highest amount - let mandatoryCandidates = graduations.filter( - (g) => g.mandatory < graduations[graduations.length - 1].mandatory, - ); - let rest; - - // All graduations have the same mandatory amount - if (mandatoryCandidates.length === 0) { - mandatoryCandidates = graduations; - rest = []; - } else { - rest = graduations.filter((g) => !mandatoryCandidates.includes(g)); + // Group the graduations according to the amount of mandatory changes + let mandatoryCandidateGroups = []; + let curGroup = []; + let mandatory = graduations[0].mandatory; + for (const g of graduations) { + if (g.mandatory === mandatory) { + curGroup.push(g); + } else { + // Start a new group + mandatoryCandidateGroups.push(curGroup); + curGroup = [g]; + mandatory = g.mandatory; + } } + // push the last group + mandatoryCandidateGroups.push(curGroup); + + // Choose from the group with the smallest amount of mandatory changes + const chosen = []; + for (const candidateGroup of mandatoryCandidateGroups) { + if (chosen.length === 5) break; - // Get a random list of possible indexes - const candidatesIdxs = shuffleArray([...Array(mandatoryCandidates.length).keys()]); - let chosen = candidatesIdxs.slice(0, 5).map((i) => mandatoryCandidates[i]); - if (chosen.length < 5) { - const missing = 5 - chosen.length; - const restIdxs = shuffleArray([...Array(rest.length).keys()]); - chosen = chosen.concat(restIdxs.slice(0, missing).map((i) => rest[i])); + // Get a random list of possible indexes + const candidatesIdxs = shuffleArray([...Array(candidateGroup.length).keys()]); + chosen.push(...candidatesIdxs.slice(0, 5 - chosen.length).map((i) => candidateGroup[i])); } return chosen; |
