Team Scores in Football Tournament
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.
matches = [[10,20,3,0],[30,10,2,2],[20,30,2,2]][[10,4],[20,1],[30,2]] → ranked: [10,4],[30,2],[20,1]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;
}
Explanation
The job is to total each team's points from match results and then rank them. The clean approach is to tally points in a hash map keyed by team, then sort that map at the end.
We keep a points map starting both teams of a match at 0. For each match we compare goals: if the host scored more, the host gets +3; if the guest scored more, the guest gets +3; if it is a draw, each side gets +1.
After every match is processed, each team's value is its full season total. We then sort the entries with the key (-points, team_id): the minus sign makes higher points come first, and the team_id breaks ties by putting the smaller id first.
Example: matches [10,20,3,0], [30,10,2,2], [20,30,2,2]. Team 10 wins (+3) and draws (+1) = 4. Team 30 draws twice = 2. Team 20 loses then draws = 1. Ranked: [10,4], [30,2], [20,1].