All SolutionsAll Solutions

🏂

Winter Olympics

Week 6, 2026

python - CSV | loops | BMC | Python Solutions

# (%%) means that I used Jupyter to run code in segments ;) # %% import csv data = [] with open("winter-olympics.csv", newline='') as file: reader = csv.reader(file) for row in reader: data.append(row) # %% country_idx = {} ans = [] # indexes country_name = 0 total_medals = 1 total_entries = 2 win_rate = 3 gold_medal = 4 silver_medal = 5 bronze_medal = 6 total_men = 7 total_women = 8 men_medal_percentage = 9 total_win_men = 10 total_win_women = 11 curridx = 0 for i in range(1, len(data)): country = data[i][4] if "-" in country: country = country[:country.index("-")] if country not in country_idx: country_idx.update({country:curridx}) ans.append([country, 0, 0, 0.00, 0, 0, 0, 0, 0, 0.00, 0, 0]) curridx += 1 cidx = country_idx[country] ans[cidx][total_entries] += 1 match data[i][2]: case 'M' : ans[cidx][total_men] +=1 case 'F' : ans[cidx][total_women] += 1 if data[i][12] != "": ans[cidx][total_medals] += 1 match data[i][12]: case "Gold" : ans[cidx][gold_medal] += 1 case "Silver" : ans[cidx][silver_medal] += 1 case "Bronze" : ans[cidx][bronze_medal] += 1 match data[i][2]: case 'M' : ans[cidx][total_win_men] +=1 case 'F' : ans[cidx][total_win_women] += 1 # %% # --- finally getting the answer --- ans.sort(key=lambda x: (-x[total_medals], x[total_entries], x[country_name])) for line in ans: fcountry_name = line[country_name ] ftotal_medals = line[total_medals ] ftotal_entries = line[total_entries ] fwin_rate = line[win_rate ] fgold_medal = line[gold_medal ] fsilver_medal = line[silver_medal ] fbronze_medal = line[bronze_medal ] ftotal_men = line[total_men ] ftotal_women = line[total_women ] fmen_medal_percentage = line[men_medal_percentage] ftotal_win_men = line[total_win_men ] ftotal_win_women = line[total_win_women ] fwin_rate = ftotal_medals/ftotal_entries*100 fwin_rate = f"{fwin_rate:.2f}" if ftotal_medals == 0: msg = f"{fcountry_name} has won {ftotal_medals} medals from {ftotal_entries} entries - a win rate of {fwin_rate}%. Their medal breakdown is {fgold_medal} golds, {fsilver_medal} silvers and {fbronze_medal} bronzes. {ftotal_win_men} men and {ftotal_win_women} women have won medals." else: fmen_medal_percentage = ftotal_win_men/ftotal_medals*100 fmen_medal_percentage = f"{fmen_medal_percentage:.2f}" msg = f"{fcountry_name} has won {ftotal_medals} medals from {ftotal_entries} entries - a win rate of {fwin_rate}%. Their medal breakdown is {fgold_medal} golds, {fsilver_medal} silvers and {fbronze_medal} bronzes. {ftotal_win_men} men and {ftotal_win_women} women have won medals - meaning {fmen_medal_percentage}% of medals have been won by men." print(msg) # %%

Collect, Sort, Format, Print | greenya | Odin Solutions

package main import "core:encoding/csv" import "core:fmt" import "core:slice" import "core:strings" input_bytes := #load("winter-olympics.csv") Country_Stat :: struct { name : string, total_entries : int, total_medals : int, total_medal : [Medal] int, total_medal_sex : [Sex] int, } Sex :: enum { male, female } Medal :: enum { bronze, silver, gold } main :: proc () { countries := countries_stats(string(input_bytes)) slice.sort_by(countries, less=proc (a, b: Country_Stat) -> bool { switch { case a.total_medals != b.total_medals: return a.total_medals > b.total_medals case a.total_entries != b.total_entries: return a.total_entries < b.total_entries case: return 0 > strings.compare(a.name, b.name) } }) for c in countries { male_medal_percentage_str := c.total_medals > 0\ ? fmt.tprintf( " - meaning %.2f%% of medals have been won by men", f32(c.total_medal_sex[.male]*100) / f32(c.total_medals), ) : "" fmt.printfln( "%s has won %i medals from %i entries - a win rate of %.2f%%. " + "Their medal breakdown is %i golds, %i silvers and %i bronzes. " + "%i men and %i women have won medals%s.", c.name, c.total_medals, c.total_entries, f32(c.total_medals*100) / f32(c.total_entries), c.total_medal[.gold], c.total_medal[.silver], c.total_medal[.bronze], c.total_medal_sex[.male], c.total_medal_sex[.female], male_medal_percentage_str, ) } } countries_stats :: proc (csv_text: string, allocator := context.allocator) -> [] Country_Stat { reader := csv.Reader { reuse_record_buffer=true, reuse_record=true } csv.reader_init_with_string(&reader, csv_text, context.temp_allocator) countries := make(map [string] Country_Stat, context.temp_allocator) for rec, idx, err in csv.iterator_next(&reader) { // fmt.println(err, idx, rec) assert(err == nil) if idx == 0 do continue // skip row with column names rec_sex := rec[2] rec_name := rec[4] rec_medal := rec[12] dash_idx := strings.last_index(rec_name, "-") if dash_idx >= 0 { rec_name = rec_name[:dash_idx] } if rec_name not_in countries { c := Country_Stat { name=strings.clone(rec_name, allocator) } countries[c.name] = c } c := &countries[rec_name] c.total_entries += 1 if rec_medal != "" { c.total_medals += 1 medal := parse_medal(rec_medal) c.total_medal[medal] += 1 sex := parse_sex(rec_sex) c.total_medal_sex[sex] += 1 } } result, _ := slice.map_values(countries, allocator=allocator) return result } parse_sex :: proc (s: string) -> Sex { switch s { case "M": return .male case "F": return .female case : fmt.panicf("Unexpected sex: %s", s) } } parse_medal :: proc (s: string) -> Medal { switch s { case "Bronze" : return .bronze case "Silver" : return .silver case "Gold" : return .gold case : fmt.panicf("Unexpected medal: %s", s) } }