- // Rule #4: Global goal difference. (Well, not strictly, but good enough.)
- var gd_parts = partition(teams, function(a, b) { return b.gd - a.gd });
+ // Rule #4: Goal difference against common opponents.
+ var results = {};
+ for (let i = 0; i < games.length; ++i) {
+ if (results[games[i].name1] === undefined) {
+ results[games[i].name1] = {};
+ }
+ if (results[games[i].name2] === undefined) {
+ results[games[i].name2] = {};
+ }
+ results[games[i].name1][games[i].name2] = [ games[i].score1, games[i].score2 ];
+ results[games[i].name2][games[i].name1] = [ games[i].score2, games[i].score1 ];
+ }
+ let gd_parts = partition_by_beat(teams, function(beat, teams_to_idx) {
+ for (const team_i of Object.keys(teams_to_idx)) {
+ let i = teams_to_idx[team_i];
+ for (const team_j of Object.keys(teams_to_idx)) {
+ let j = teams_to_idx[team_j];
+ let results_i = results[team_i], results_j = results[team_j];
+ let gd_i = 0, gd_j = 0;
+
+ // See if the two teams have both played a third team k.
+ for (let k in results_i) {
+ if (!results_i.hasOwnProperty(k)) continue;
+ if (results_j !== undefined && results_j[k] !== undefined) {
+ gd_i += results_i[k][0] - results_i[k][1];
+ gd_j += results_j[k][0] - results_j[k][1];
+ }
+ }
+
+ if (gd_i > gd_j) {
+ beat[i][j] = 1;
+ } else if (gd_i < gd_j) {
+ beat[j][i] = 1;
+ }
+ }
+ }
+ });