All SolutionsAll Solutions

🏆

FIFA World Cup 2026

Week 23, 2026

WON'T WORK (MUST chng goal to goals in RND16) | devilssnare | Python Solutions

# Mr. Draw6 discovered that this solution will not work unless we change goal to goals in Round 16 only. In other words, all singular instances of goal must be converted to goals, but only in Round 16. Mr. Draw6 is a wizard from itertools import combinations groups = [ ["Mexico", "South Africa", "Korea Republic", "Czechia"], ["Canada", "Bosnia and Herzegovina", "Qatar", "Switzerland"], ["Brazil", "Morocco", "Haiti", "Scotland"], ["USA", "Paraguay", "Australia", "Türkiye"], ["Germany", "Curaçao", "Côte d'Ivoire", "Ecuador"], ["Netherlands", "Japan", "Sweden", "Tunisia"], ["Belgium", "Egypt", "IR Iran", "New Zealand"], ["Spain", "Cabo Verde", "Saudi Arabia", "Uruguay"], ["France", "Senegal", "Iraq", "Norway"], ["Argentina", "Algeria", "Austria", "Jordan"], ["Portugal", "Congo DR", "Uzbekistan", "Colombia"], ["England", "Croatia", "Ghana", "Panama"] ] ratings = { "France": 1877.32, "Spain": 1876.4, "Argentina": 1874.81, "England": 1825.97, "Portugal": 1763.83, "Brazil": 1762.66, "Netherlands": 1757.87, "Morocco": 1755.87, "Belgium": 1734.71, "Germany": 1731.3, "Croatia": 1717.07, "Colombia": 1695.99, "Senegal": 1686.41, "Mexico": 1684.13, "USA": 1675.7, "Uruguay": 1673.07, "Japan": 1661.58, "Switzerland": 1650.75, "IR Iran": 1616.04, "Türkiye": 1601.99, "Austria": 1597.4, "Ecuador": 1596.48, "Korea Republic": 1589.65, "Australia": 1578.66, "Egypt": 1565.56, "Algeria": 1564.26, "Canada": 1560.62, "Norway": 1555.6, "Panama": 1539.14, "Côte d'Ivoire": 1532.98, "Sweden": 1510.11, "Paraguay": 1503.5, "Czechia": 1503.04, "Scotland": 1499.92, "Tunisia": 1479.1, "Congo DR": 1478.35, "Uzbekistan": 1461.21, "Qatar": 1452.37, "Iraq": 1447.77, "South Africa": 1428.38, "Saudi Arabia": 1419.73, "Jordan": 1390.1, "Bosnia and Herzegovina": 1385.77, "Cabo Verde": 1369.29, "Ghana": 1345.23, "Curaçao": 1293.08, "Haiti": 1291.71, "New Zealand": 1281.57 } round_32_slots = [ "1E", "?", "1I", "?", "2A", "2B", "1F", "2C", "2K", "2L", "1H", "2J", "1D", "?", "1G", "?", "1C", "2F", "2E", "2I", "1A", "?", "1L", "?", "1J", "2H", "2D", "2G", "1B", "?", "1K", "?" ] third_place_rules = { "ACDEGIJL": ["E", "G", "J", "C", "A", "D", "L", "I"] } def get_goal_margin(rating_gap): if rating_gap >= 500: return 3 if rating_gap >= 250: return 2 if rating_gap >= 100: return 1 return 0 def play_game(first_team, second_team, knock_out_game=False): rating_gap = abs(ratings[first_team] - ratings[second_team]) goal_margin = get_goal_margin(rating_gap) if goal_margin == 0: if knock_out_game: if ratings[first_team] > ratings[second_team]: return first_team, second_team, "penalties" return second_team, first_team, "penalties" return None, None, "draw" if ratings[first_team] > ratings[second_team]: return first_team, second_team, goal_margin return second_team, first_team, goal_margin def write_game_line(first_team, second_team, knock_out_game=False): winner, loser, result = play_game(first_team, second_team, knock_out_game) if result == "draw": return f"{first_team} drew with {second_team}", None if result == "penalties": return f"{winner} beat {loser} on penalties", winner if result == 1: return f"{winner} beat {loser} by 1 goal", winner return f"{winner} beat {loser} by {result} goals", winner def run_tournament(): group_letters = "ABCDEFGHIJKL" lines = [] group_standings = {} third_place_list = [] for group_letter, group_teams in zip(group_letters, groups): team_stats = {} for team in group_teams: team_stats[team] = { "points": 0, "goal_difference": 0 } lines.append(f"--- Group {group_letter} Matches ---") for first_team, second_team in combinations(group_teams, 2): match_line, _ = write_game_line(first_team, second_team) lines.append(match_line) winner, loser, result = play_game(first_team, second_team) if result == "draw": team_stats[first_team]["points"] += 1 team_stats[second_team]["points"] += 1 else: team_stats[winner]["points"] += 3 team_stats[winner]["goal_difference"] += result team_stats[loser]["goal_difference"] -= result final_table = sorted( group_teams, key=lambda team: ( -team_stats[team]["points"], -team_stats[team]["goal_difference"], -ratings[team] ) ) group_standings[group_letter] = final_table lines.append("") lines.append(f"--- Group {group_letter} Table ---") for place, team in enumerate(final_table, 1): points = team_stats[team]["points"] goal_difference = team_stats[team]["goal_difference"] lines.append(f"{place}. {team} {points} {goal_difference}") lines.append("") third_team = final_table[2] third_place_list.append({ "group": group_letter, "team": third_team, "points": team_stats[third_team]["points"], "goal_difference": team_stats[third_team]["goal_difference"], "rating": ratings[third_team] }) third_place_list.sort( key=lambda team: ( -team["points"], -team["goal_difference"], -team["rating"] ) ) best_third_placed_teams = third_place_list[:8] eliminated_third_placed_teams = third_place_list[8:] lines.append("--- Third Place Qualifiers ---") for place, team in enumerate(best_third_placed_teams, 1): lines.append( f"{place}. {team['team']} {team['points']} {team['goal_difference']}" ) lines.append("--- Third Place Eliminations ---") for place, team in enumerate(eliminated_third_placed_teams, 9): lines.append( f"{place}. {team['team']} {team['points']} {team['goal_difference']}" ) third_place_key = "".join(sorted(team["group"] for team in best_third_placed_teams)) if third_place_key not in third_place_rules: raise ValueError(f"No third-place rule found for {third_place_key}") group_winners_that_face_third = ["A", "B", "D", "E", "G", "I", "K", "L"] third_place_order = third_place_rules[third_place_key] third_team_for_winner = dict(zip(group_winners_that_face_third, third_place_order)) team_places = {} for group_letter in group_letters: table = group_standings[group_letter] team_places[f"1{group_letter}"] = table[0] team_places[f"2{group_letter}"] = table[1] team_places[f"3{group_letter}"] = table[2] current_bracket = [] for slot_number, slot in enumerate(round_32_slots): if slot != "?": current_bracket.append(team_places[slot]) else: previous_slot = round_32_slots[slot_number - 1] winner_group = previous_slot[1] third_group = third_team_for_winner[winner_group] current_bracket.append(team_places[f"3{third_group}"]) round_names = [ "Round of 32", "Round of 16", "Quarter Final", "Semi Final", "Final" ] for round_name in round_names: lines.append("") lines.append(f"--- {round_name} ---") winners = [] for game_number in range(1, len(current_bracket) // 2 + 1): first_team = current_bracket[(game_number - 1) * 2] second_team = current_bracket[(game_number - 1) * 2 + 1] match_line, winner = write_game_line( first_team, second_team, knock_out_game=True ) lines.append(f"{game_number}. {match_line}") winners.append(winner) current_bracket = winners return "\n".join(lines) if __name__ == "__main__": result = run_tournament() print(result)

Events, groups, teams, matches etc. | greenya | Odin Solutions

package main import "core:encoding/json" import "core:fmt" import "core:slice" INPUT_TYPE :: "fifa" // "fifa", "uefa" INPUT_GROUPS_JSON := #load("groups_" + INPUT_TYPE + ".json") INPUT_RANKINGS_JSON := #load("rankings_" + INPUT_TYPE + ".json") INPUT_QUALIFIERS_JSON := #load("qualifiers.json") // The third place qualifiers table INPUT_KNOCKOUT_32_JSON := #load("knockout_32.json") // The matches played in Knockout stage with 32 teams when INPUT_TYPE == "fifa" do input_ruler := Input_Match_Ruler { 100, 250, 500 } else when INPUT_TYPE == "uefa" do input_ruler := Input_Match_Ruler { 20, 40, 80 } else do #panic("input_ruler is undefined for `" + INPUT_TYPE + "`") main :: proc () { input_groups: Input_Groups json.unmarshal(INPUT_GROUPS_JSON, &input_groups) input_rankings: Input_Rankings json.unmarshal(INPUT_RANKINGS_JSON, &input_rankings) input_qualifiers: Input_Qualifiers json.unmarshal(INPUT_QUALIFIERS_JSON, &input_qualifiers) input_knockout_32: Input_Knockout_32 json.unmarshal(INPUT_KNOCKOUT_32_JSON, &input_knockout_32) fmt.ensuref(len(input_knockout_32) == 32, "Expecting 32 teams (16 pairs) in knockout_32, got %i", len(input_knockout_32)) fmt.ensuref(len(input_groups) == 12, "Expecting 12 groups, got %i", len(input_groups)) for group, i in input_groups { fmt.ensuref(len(group) == 4, "Expecting 4 teams, got %i in group #%i", len(group), i) for team in group do fmt.ensuref(team in input_rankings, "Missing ranking for team `%s`", team) } event: Event event_init(&event, input_groups, input_rankings, input_ruler) event_do_groups(&event) event_do_third_place_qualifiers_and_eliminations(&event) event_do_knockout_32(&event, input_qualifiers, input_knockout_32) event_do_knockout_bracket(&event, from=event.knockout.teams_16[:], to=event.knockout.teams_8[:]) event_do_knockout_bracket(&event, from=event.knockout.teams_8[:], to=event.knockout.teams_4[:]) event_do_knockout_bracket(&event, from=event.knockout.teams_4[:], to=event.knockout.teams_2[:]) event_do_knockout_bracket(&event, from=event.knockout.teams_2[:], to=event.knockout.teams_1[:]) } Input_Groups :: [] [] string Input_Rankings :: map [string] f32 Input_Qualifiers :: map [string] [] string Input_Knockout_32 :: [] string Input_Match_Ruler :: [3] f32 // 0..<[0] draw/penalties, [0]..<[1] 1 goal, [1]..<[2] 2 goals, [2]+ 3 goals Event :: struct { teams : [48] Event_Team, groups : [12] Event_Group, ruler : Input_Match_Ruler, knockout: struct { teams_32: [32] ^Event_Team, // Round of 32: [0..23] 12 winners and 12 runnings, [24..31] top 8 3rd places teams_16: [16] ^Event_Team, // Round of 16 teams_8 : [8] ^Event_Team, // Quarter Final teams_4 : [4] ^Event_Team, // Semi Final teams_2 : [2] ^Event_Team, // Final teams_1 : [1] ^Event_Team, // Champion }, } Event_Group :: struct { name : byte, teams : [4] ^Event_Team, } Event_Team :: struct { name : string, group : ^Event_Group, points : int, goals : int, ranking : f32, } event_init :: proc (e: ^Event, input_groups: Input_Groups, input_rankings: Input_Rankings, input_ruler: Input_Match_Ruler) { e^ = {} e.ruler = input_ruler for group, i in input_groups { e.groups[i].name = 'A' + byte(i) for team, j in group { fmt.ensuref(team in input_rankings, "Missing ranking for team `%s`", team) e.teams[i*4+j] = { name = team, group = &e.groups[i], ranking = input_rankings[team], } e.groups[i].teams[j] = &e.teams[i*4+j] } } } event_do_groups :: proc (e: ^Event) { for &group in e.groups { fmt.printfln("--- Group %c Matches ---", group.name) for i:=0; i<4; i+=1 do for j:=i+1; j<4; j+=1 { event_teams_match(group.teams[i], group.teams[j], e.ruler, draw_allowed=true) } fmt.println() event_teams_sort(group.teams[:]) fmt.printfln("--- Group %c Table ---", group.name) for t, i in group.teams { fmt.printfln("%i. %s %i %i", i+1, t.name, t.points, t.goals) } fmt.println() } } event_do_third_place_qualifiers_and_eliminations :: proc (e: ^Event) { third_place_teams: [12] ^Event_Team for group, i in e.groups { e.knockout.teams_32[i*2+0] = group.teams[0] // group winner e.knockout.teams_32[i*2+1] = group.teams[1] // group runner third_place_teams[i] = group.teams[2] // third place candidate } event_teams_sort(third_place_teams[:]) for team, i in third_place_teams { if i < 8 do e.knockout.teams_32[12*2+i] = team if i == 0 do fmt.println("--- Third Place Qualifiers ---") if i == 8 do fmt.println("--- Third Place Eliminations ---") fmt.printfln("%i. %s %i %i", i+1, team.name, team.points, team.goals) } fmt.println() } event_do_knockout_32 :: proc (e: ^Event, input_qualifiers: Input_Qualifiers, input_knockout_32: Input_Knockout_32) { fmt.println("--- Round of 32 ---") q_row := event_qualifiers_row(e, input_qualifiers) for &winner, i in e.knockout.teams_16 { pair: [2] ^Event_Team for &team, j in pair { group_name: byte team_pos: int key := input_knockout_32[i*2+j] if key == "?" { assert(1 == j) // The "?" can only be the second in a pair assert(1 == event_team_group_pos(pair[0])) // and 1st team must be a winner, e.g. 1E not 2E group_name = q_row[pair[0].group.name-'A'] team_pos = 3 } else { group_name = key[1] team_pos = int(key[0]-'0') } team = event_team_in_group(e.knockout.teams_32[:], group_name, team_pos) } fmt.printf("%i. ", i+1) winner = event_teams_match(pair[0], pair[1], e.ruler, draw_allowed=false) } fmt.println() } event_do_knockout_bracket :: proc (e: ^Event, from, to: [] ^Event_Team) { assert(len(from) == 2 * len(to)) switch len(from) { case 16 : fmt.println("--- Round of 16 ---") case 8 : fmt.println("--- Quarter Final ---") case 4 : fmt.println("--- Semi Final ---") case 2 : fmt.println("--- Final ---") case : panic("Unexpected bracket size") } for &winner, i in to { fmt.printf("%i. ", i+1) winner = event_teams_match(from[i*2+0], from[i*2+1], e.ruler, draw_allowed=false) } fmt.println() } event_qualifiers_row :: proc (e: ^Event, input_qualifiers: Input_Qualifiers) -> [12] byte { q_key: [8] byte for &b, i in q_key do b = e.knockout.teams_32[i+24].group.name slice.sort(q_key[:]) q_key_str := string(q_key[:]) fmt.ensuref(q_key_str in input_qualifiers, "Missing qualifier key `%s`", q_key_str) q: [8] byte for s, i in input_qualifiers[q_key_str] do q[i] = s[0] // 1A 1B 1C 1D 1E 1F 1G 1H 1I 1J 1K 1L return { q[0], q[1], 0, q[2], q[3], 0, q[4], 0, q[5], 0, q[6], q[7] } } event_teams_match :: proc (team1, team2: ^Event_Team, ruler: Input_Match_Ruler, draw_allowed := true) -> (winner: ^Event_Team) { ranking_diff := team1.ranking - team2.ranking ranking_diff_abs := abs(ranking_diff) if ranking_diff_abs < ruler[0] && draw_allowed { fmt.printfln("%s drew with %s", team1.name, team2.name) team1.points += 1 team2.points += 1 return } goals: int beat_order: [2] ^Event_Team = ranking_diff > 0 ? { team1, team2 } : { team2, team1 } beat_order[0].points += 3 switch { case ranking_diff_abs < ruler[0]: fmt.printfln("%s beat %s on penalties", beat_order[0].name, beat_order[1].name) // ignore goals counter for penalties case ranking_diff_abs < ruler[1]: fmt.printfln("%s beat %s by 1 goal", beat_order[0].name, beat_order[1].name) goals = 1 case ranking_diff_abs < ruler[2]: fmt.printfln("%s beat %s by 2 goals", beat_order[0].name, beat_order[1].name) goals = 2 case: fmt.printfln("%s beat %s by 3 goals", beat_order[0].name, beat_order[1].name) goals = 3 } beat_order[0].goals += goals beat_order[1].goals -= goals return beat_order[0] } event_teams_sort :: proc (teams: [] ^Event_Team) { slice.sort_by(teams[:], less = proc (t1, t2: ^Event_Team) -> bool { switch { case t1.points != t2.points : return t1.points > t2.points case t1.goals != t2.goals : return t1.goals > t2.goals case : return t1.ranking > t2.ranking } }) } event_team_in_group :: proc (teams: [] ^Event_Team, group_name: byte, team_pos: int) -> ^Event_Team { Args :: struct { group_name: byte, team_pos: int } context.user_ptr = &Args { group_name, team_pos } i, ok := slice.linear_search_proc(teams, proc (t: ^Event_Team) -> bool { args := cast (^Args) context.user_ptr return t.group.name == args.group_name && event_team_group_pos(t) == args.team_pos }) assert(ok) return teams[i] } event_team_group_pos :: proc (team: ^Event_Team) -> int { i, ok := slice.linear_search(team.group.teams[:], team) assert(ok) return 1 + i }