Team Scores in Football Tournament

medium hash map aggregation sorting

Problem

Given a list of football matches, each as [host, guest, host_goals, guest_goals], award points to teams: the winner of a match gets 3 points, a draw gives each side 1 point, and the loser gets 0. Total each team's points, then rank all teams by points in descending order; ties are broken by team id in ascending order.

Inputmatches = [[10,20,3,0],[30,10,2,2],[20,30,2,2]]
Output[[10,4],[20,1],[30,2]] → ranked: [10,4],[30,2],[20,1]
Team 10 wins vs 20 (+3) and draws vs 30 (+1) = 4. Team 30 draws twice = 2. Team 20 loses then draws = 1. Sorted by points desc, id asc.

def team_scores(matches):
    points = {}
    for host, guest, hg, gg in matches:
        points.setdefault(host, 0)
        points.setdefault(guest, 0)
        if hg > gg:
            points[host] += 3
        elif hg < gg:
            points[guest] += 3
        else:
            points[host] += 1
            points[guest] += 1
    return sorted(points.items(), key=lambda kv: (-kv[1], kv[0]))
function teamScores(matches) {
  const points = new Map();
  for (const [host, guest, hg, gg] of matches) {
    if (!points.has(host)) points.set(host, 0);
    if (!points.has(guest)) points.set(guest, 0);
    if (hg > gg) points.set(host, points.get(host) + 3);
    else if (hg < gg) points.set(guest, points.get(guest) + 3);
    else { points.set(host, points.get(host) + 1); points.set(guest, points.get(guest) + 1); }
  }
  return [...points.entries()].sort((a, b) => b[1] - a[1] || a[0] - b[0]);
}
int[][] teamScores(int[][] matches) {
    Map<Integer, Integer> points = new HashMap<>();
    for (int[] m : matches) {
        int host = m[0], guest = m[1], hg = m[2], gg = m[3];
        points.putIfAbsent(host, 0);
        points.putIfAbsent(guest, 0);
        if (hg > gg) points.merge(host, 3, Integer::sum);
        else if (hg < gg) points.merge(guest, 3, Integer::sum);
        else { points.merge(host, 1, Integer::sum); points.merge(guest, 1, Integer::sum); }
    }
    return points.entrySet().stream()
        .sorted((a, b) -> b.getValue() != a.getValue()
            ? b.getValue() - a.getValue() : a.getKey() - b.getKey())
        .map(e -> new int[]{ e.getKey(), e.getValue() })
        .toArray(int[][]::new);
}
vector<pair<int,int>> teamScores(vector<vector<int>>& matches) {
    unordered_map<int, int> points;
    for (auto& m : matches) {
        int host = m[0], guest = m[1], hg = m[2], gg = m[3];
        points.emplace(host, 0);
        points.emplace(guest, 0);
        if (hg > gg) points[host] += 3;
        else if (hg < gg) points[guest] += 3;
        else { points[host] += 1; points[guest] += 1; }
    }
    vector<pair<int,int>> res(points.begin(), points.end());
    sort(res.begin(), res.end(), [](auto& a, auto& b) {
        return a.second != b.second ? a.second > b.second : a.first < b.first;
    });
    return res;
}
Time: O(n + k log k) Space: O(k)