diff --git a/brute_force.py b/brute_force.py index 3d4291e..8f962b3 100644 --- a/brute_force.py +++ b/brute_force.py @@ -38,20 +38,33 @@ def load_stats(): def team_table_json(): players, preferences = load_stats() - mean, team0, team1 = apply_brute_force(players, preferences) - data = {} - for i, team in enumerate([team0, team1]): - tablename = f"Team {i+1}" - data[tablename] = [] - for p in sorted(list(team)): - prefs = preferences[p] - matches = sum([pref in team for pref in preferences[p]]) - data[tablename].append([p, matches, len(prefs)]) + best = apply_brute_force(players, preferences) + data = {k: {} for k in best} + for k, v in best.items(): + mean, team0, team1 = v[0] + overall_matches = 0 + overall_preference_statements = 0 + for i, team in enumerate([team0, team1]): + tablename = f"Team {i+1}" + data[k][tablename] = [] + for p in sorted(list(team)): + prefs = preferences[p] + matches = sum([pref in team for pref in preferences[p]]) + data[k][tablename].append([p, matches, len(prefs)]) + overall_matches += matches + overall_preference_statements += len(prefs) + # data[k]["overall_matches"] = overall_matches + # data[k]["overall_preference_statements"] = overall_preference_statements with open("prefs_page/src/table.json", "w") as f: json.dump(data, f) +def unique_names(team): + """check if first names are unique""" + return len(set(team)) == len(set([p.split()[0] for p in team])) + + def apply_brute_force(players, preferences): def evaluate_teams(team0, team1): scores = [] @@ -63,33 +76,43 @@ def apply_brute_force(players, preferences): percentages.append(scores[-1] / len(preferences[p])) return np.mean(scores), np.mean(percentages) * 100 - best_score = [(0, [], [])] - best_percentage = [(0, [], [])] + best = { + f"{i},{j}": [(0, [], [])] + for i, j in itertools.product(["total", "relative"], ["unique", "non-unique"]) + } + for team0 in itertools.combinations(players, 9): team1 = {player for player in players if player not in team0} score, percentage = evaluate_teams(team0, team1) - if score > best_score[0][0]: - best_score = [(score, team0, team1)] - if score == best_score[0][0] and set(team0) != set(best_score[0][1]): - best_score.append((score, team0, team1)) - if percentage > best_percentage[0][0]: - best_percentage = [(percentage, team0, team1)] - if percentage == best_percentage[0][0] and set(team0) != set(best_score[0][1]): - best_percentage.append((percentage, team0, team1)) + for k, v in best.items(): + if k.startswith("total"): + meassure = score + elif k.startswith("relative"): + meassure = percentage + if meassure > best[k][0][0]: + if k.endswith(",unique") and not ( + unique_names(team0) and unique_names(team1) + ): + continue + best[k] = [(meassure, team0, team1)] + elif meassure == best[k][0][0] and set(team0) != set(best[k][0][1]): + if k.endswith(",unique") and not ( + unique_names(team0) and unique_names(team1) + ): + continue + best[k].append((meassure, team0, team1)) if __name__ == "__main__": - for result in best_score: - print(result[0]) - print(result[1]) - print(result[2]) - - for result in best_percentage: - print(result[0]) - print(result[1]) - print(result[2]) + for k, v in best.items(): + print("##", k) + for result in v: + print(result[0]) + print(sorted(result[1])) + print(sorted(result[2])) + print() # team_table(score, team0, team1) - return best_percentage[0] + return best if __name__ == "__main__": diff --git a/prefs_page/src/App.css b/prefs_page/src/App.css index 3800e3c..383f90b 100644 --- a/prefs_page/src/App.css +++ b/prefs_page/src/App.css @@ -1,5 +1,5 @@ #root { - max-width: 60vw; + max-width: 70vw; margin: 0 auto; padding: 2rem; text-align: center; @@ -11,4 +11,5 @@ .read-the-docs { color: #888; + padding: 0; } diff --git a/prefs_page/src/Table.tsx b/prefs_page/src/Table.tsx index ea34689..beb32b8 100644 --- a/prefs_page/src/Table.tsx +++ b/prefs_page/src/Table.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; @@ -6,12 +7,47 @@ import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; import Paper from "@mui/material/Paper"; import data from "./table.json"; +import { + Box, + Checkbox, + FormControlLabel, + Stack, + Switch, + Typography, +} from "@mui/material"; + +interface Data { + [index: string]: Teams; +} + +interface Teams { + teamname: Row; +} type Row = [player: string, fulfilled: number, total: number]; -export default function TeamTables() { +function RenderTable(data: object) { + let nMatches: number = 0; + let nTotal: number = 0; + let nPlayers: number = 0; + let relativeScore: number = 0.0; + for (const rows of Object.values(data)) { + for (const row of rows) { + nMatches += row[1]; + nTotal += row[2]; + relativeScore += row[1] / row[2]; + nPlayers++; + } + } return ( <> + + average wishes fulfilled:{" "} + + {(nMatches / nPlayers).toPrecision(2)} ( + {((relativeScore / nPlayers) * 100).toPrecision(3)}%) + + {Object.entries(data).map(([teamname, rows]) => ( <>

{teamname}

@@ -47,3 +83,69 @@ export default function TeamTables() { ); } + +export default function TeamTables() { + const [total, setTotal] = useState("relative"); + const [unique, setUnique] = useState("non-unique"); + + const handleTotalChange = (event: React.ChangeEvent) => { + if (event.target.checked) { + setTotal("relative"); + } else { + setTotal("total"); + } + }; + + const handleUniqueChange = (event: React.ChangeEvent) => { + if (event.target.checked) { + setUnique("unique"); + } else { + setUnique("non-unique"); + } + }; + + let tabledata: Data = data as unknown as Data; + + return ( + <> + + + according to + + total + + relative + + + number of wishes fulfilled + + + + + + } + label="unique first names" + /> + + + {RenderTable(tabledata[[total, unique].join(",") as string])} + + ); +}