diff --git a/scripts/2023/Simulate Champs V2.ipynb b/scripts/2023/Simulate Champs V2.ipynb new file mode 100644 index 00000000..80a993cc --- /dev/null +++ b/scripts/2023/Simulate Champs V2.ipynb @@ -0,0 +1,2174 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b698f107", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "from functools import lru_cache\n", + "import random\n", + "import requests\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import statbotics\n", + "\n", + "%matplotlib notebook\n", + "\n", + "sb = statbotics.Statbotics()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4568bf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3286" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_teams = sb.get_team_years(year=2023, limit=10000)\n", + "all_teams_dict = {t[\"team\"]: t for t in all_teams}\n", + "len(all_teams)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e2046e7e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "621\n" + ] + } + ], + "source": [ + "champ_teams = sb.get_team_events(event=\"2023cmptx\", limit=10000)\n", + "champ_team_nums = [t[\"team\"] for t in champ_teams]\n", + "champ_team_nums += [333, 449, 999, 2170, 2337, 4779, 4976, 5123, 7174, 7534, 8013, 9152, 9244]\n", + "\n", + "print(len(set(champ_team_nums)))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7ab3cd85", + "metadata": {}, + "outputs": [], + "source": [ + "epa_breakdown = pd.read_json(\"https://raw.githubusercontent.com/avgupta456/statbotics/master/data/2023/epa_breakdown.json\", orient=\"index\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "b4529072", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "84.85 0.9931 0.5175 12.2601407515\n", + "80.19 0.9545 0.6071 11.6093456675\n" + ] + } + ], + "source": [ + "team_to_epa = {t: all_teams_dict[t][\"epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_1_epa = {t: all_teams_dict[t][\"rp_1_epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_2_epa = {t: all_teams_dict[t][\"rp_2_epa_end\"] for t in champ_team_nums}\n", + "team_to_cycles = {t: epa_breakdown.loc[t][\"total_cycles\"] for t in champ_team_nums}\n", + "\n", + "print(team_to_epa[2056], team_to_rp_1_epa[2056], team_to_rp_2_epa[2056], team_to_cycles[2056])\n", + "print(team_to_epa[254], team_to_rp_1_epa[254], team_to_rp_2_epa[254], team_to_cycles[254])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "38d2a765", + "metadata": {}, + "outputs": [], + "source": [ + "TOTAL_MEAN = 74.57\n", + "TOTAL_SD = 29.36" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "811dfb7e", + "metadata": {}, + "outputs": [], + "source": [ + "@lru_cache\n", + "def make_request(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " data = response.text\n", + " lines = data.split(\"\\n\")\n", + " return lines\n", + "\n", + "@lru_cache\n", + "def get_schedule(num_teams: int, num_matches: int):\n", + " # TODO: remove this once we have pre-generated schedules for 100+ teams\n", + " if num_teams > 100:\n", + " schedule1 = get_schedule(100, num_matches)\n", + " schedule2 = get_schedule(num_teams - 100, num_matches)\n", + " schedule2 = [\n", + " {\"red\": [team + 100 for team in match[\"red\"]], \"blue\": [team + 100 for team in match[\"blue\"]]}\n", + " for match in schedule2\n", + " ]\n", + " return schedule1 + schedule2\n", + "\n", + " # load csv from external URL using requests\n", + " lines = make_request(f\"https://raw.githubusercontent.com/Team254/cheesy-arena/main/schedules/{num_teams}_{num_matches}.csv\")\n", + " \n", + " schedule = []\n", + " for line in lines:\n", + " match = line.split(\",\")\n", + " if len(match) < 12:\n", + " continue\n", + " red = [int(match[0]), int(match[2]), int(match[4])]\n", + " blue = [int(match[6]), int(match[8]), int(match[10])]\n", + " schedule.append({\"red\": red, \"blue\": blue})\n", + " \n", + " return schedule" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c2233c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def get_win_prob(a, b):\n", + " return 1 / (1 + 10 ** (((-5 / 8) * (a - b)) / TOTAL_SD))\n", + "\n", + "def get_rp_pred(a):\n", + " return 1 / (1 + np.e ** (-4 * (a - 0.5)))\n", + "\n", + "def sim_single_quals(teams, schedule):\n", + " scores, grids = [], []\n", + " curr_sim_matches = {t: 0 for t in teams}\n", + " curr_sim_rps = {t: 0 for t in teams}\n", + " for m in schedule:\n", + " red_epa = sum(team_to_epa[x] for x in m[\"red\"])\n", + " blue_epa = sum(team_to_epa[x] for x in m[\"blue\"])\n", + " red_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"red\"])\n", + " blue_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"blue\"])\n", + " red_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"red\"])\n", + " blue_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"blue\"])\n", + " red_cycles = sum(team_to_cycles[x] for x in m[\"red\"])\n", + " blue_cycles = sum(team_to_cycles[x] for x in m[\"blue\"])\n", + " \n", + " scores.extend([red_epa, blue_epa])\n", + " grids.extend([red_cycles, blue_cycles])\n", + " \n", + " win_prob = get_win_prob(red_epa, blue_epa)\n", + " red_win = 1 if random.random() < win_prob else 0\n", + "\n", + " red_rp_1_prob = get_rp_pred(0.9 * red_rp_1_epa)\n", + " red_rp_1 = 1 if random.random() < red_rp_1_prob else 0\n", + " \n", + " red_rp_2_prob = get_rp_pred(red_rp_2_epa)\n", + " red_rp_2 = 1 if random.random() < red_rp_2_prob else 0\n", + " \n", + " blue_rp_1_prob = get_rp_pred(0.9 * blue_rp_1_epa)\n", + " blue_rp_1 = 1 if random.random() < blue_rp_1_prob else 0\n", + " \n", + " blue_rp_2_prob = get_rp_pred(blue_rp_2_epa)\n", + " blue_rp_2 = 1 if random.random() < blue_rp_2_prob else 0\n", + "\n", + " red_rps = red_rp_1 + red_rp_2 + (2 if red_win else 0)\n", + " blue_rps = blue_rp_1 + blue_rp_2 + (0 if red_win else 2)\n", + " \n", + " for x in m[\"red\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += red_rps\n", + " \n", + " for x in m[\"blue\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += blue_rps\n", + " \n", + " curr_sim_ranks = sorted(curr_sim_rps.items(), key=lambda x: [-x[1], random.random()])\n", + " \n", + " return [x[0] for x in curr_sim_ranks], scores, grids\n", + "\n", + "def softmax_select(options, mult=1):\n", + " exp = [np.e ** (mult * o) for o in options]\n", + " sum_exp = sum(exp)\n", + " exp = [e / sum_exp for e in exp]\n", + " rand = random.random()\n", + " curr, i = 0, 0\n", + " while curr < rand:\n", + " curr += exp[i]\n", + " i += 1\n", + " return i - 1\n", + "\n", + "def sim_alliance_selection(ranks):\n", + " alliances = [[], [], [], [], [], [], [], []]\n", + " locked_teams = []\n", + " remaining_teams = [(r, team_to_epa[r]) for r in ranks]\n", + " \n", + " r1_mult = 1 / 3\n", + " r2_mult = 1 / 2\n", + " \n", + " def handle_selection(selector, reject=True):\n", + " selected = None\n", + " while selected is None:\n", + " temp_remaining_teams = [r for r in remaining_teams if r not in locked_teams]\n", + " _selected = softmax_select([r[1] for r in temp_remaining_teams], r1_mult)\n", + " _selected_team = temp_remaining_teams[_selected]\n", + " orig_rank = ranks.index(_selected_team[0]) + 1\n", + " if not reject or orig_rank > 8:\n", + " selected = _selected\n", + " continue\n", + " \n", + " selected_rank = remaining_teams.index(_selected_team) + 1\n", + " remaining_best_epas = sorted(temp_remaining_teams[_selected + 1:], key=lambda x: -x[1])\n", + " if remaining_best_epas[selected_rank][1] > selector[1] + 5:\n", + " locked_teams.append(_selected_team)\n", + " else:\n", + " selected = _selected\n", + " \n", + " return remaining_teams.index(temp_remaining_teams[selected])\n", + " \n", + " # Captain and Round 1\n", + " alliances[0].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[1].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[2].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[3].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + "\n", + " alliances[4].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[5].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[6].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[7].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 2\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 3\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " aepas = [sum(a[1] for a in alliance[:3]) for alliance in alliances]\n", + " return [[a[0] for a in alliance] for alliance in alliances], aepas\n", + "\n", + "def sim_single_elims(alliances):\n", + " scores, grids = [], []\n", + " \n", + " aepas = [sum(team_to_epa[a] for a in alliance[:3]) for alliance in alliances]\n", + " ms = [[0, 7], [3, 4], [1, 6], [2, 5], [], [], [], [], [], [], [], [], []]\n", + " \n", + " def _get_win_prob(i):\n", + " red_cycles = sum(team_to_cycles[x] for x in alliances[ms[i][0]][:3])\n", + " blue_cycles = sum(team_to_cycles[x] for x in alliances[ms[i][1]][:3])\n", + " \n", + " scores.extend([aepas[ms[i][0]], aepas[ms[i][1]]])\n", + " grids.extend([red_cycles, blue_cycles])\n", + " return get_win_prob(aepas[ms[i][0]], aepas[ms[i][1]])\n", + "\n", + " m1_red_winner = random.random() < _get_win_prob(0)\n", + " ms[4].append(ms[0][1] if m1_red_winner else ms[0][0])\n", + " ms[6].append(ms[0][0] if m1_red_winner else ms[0][1])\n", + " \n", + " m2_red_winner = random.random() < _get_win_prob(1)\n", + " ms[4].append(ms[1][1] if m2_red_winner else ms[1][0])\n", + " ms[6].append(ms[1][0] if m2_red_winner else ms[1][1])\n", + " \n", + " m3_red_winner = random.random() < _get_win_prob(2)\n", + " ms[5].append(ms[2][1] if m3_red_winner else ms[2][0])\n", + " ms[7].append(ms[2][0] if m3_red_winner else ms[2][1])\n", + " \n", + " m4_red_winner = random.random() < _get_win_prob(3)\n", + " ms[5].append(ms[3][1] if m4_red_winner else ms[3][0])\n", + " ms[7].append(ms[3][0] if m4_red_winner else ms[3][1])\n", + " \n", + " m5_red_winner = random.random() < _get_win_prob(4)\n", + " ms[9].append(ms[4][0] if m5_red_winner else ms[4][1])\n", + " \n", + " m6_red_winner = random.random() < _get_win_prob(5)\n", + " ms[8].append(ms[5][0] if m6_red_winner else ms[5][1])\n", + " \n", + " m7_red_winner = random.random() < _get_win_prob(6)\n", + " ms[8].append(ms[6][1] if m7_red_winner else ms[6][0])\n", + " ms[10].append(ms[6][0] if m7_red_winner else ms[6][1])\n", + " \n", + " m8_red_winner = random.random() < _get_win_prob(7)\n", + " ms[9].append(ms[7][1] if m8_red_winner else ms[7][0])\n", + " ms[10].append(ms[7][0] if m8_red_winner else ms[7][1])\n", + " \n", + " m9_red_winner = random.random() < _get_win_prob(8)\n", + " ms[11].append(ms[8][0] if m9_red_winner else ms[8][1])\n", + " \n", + " m10_red_winner = random.random() < _get_win_prob(9)\n", + " ms[11].append(ms[9][0] if m10_red_winner else ms[9][1])\n", + " \n", + " m11_red_winner = random.random() < _get_win_prob(10)\n", + " ms[12].append(ms[10][1] if m11_red_winner else ms[10][0])\n", + " finalist_1 = ms[10][0] if m11_red_winner else ms[10][1]\n", + " \n", + " m12_red_winner = random.random() < _get_win_prob(11)\n", + " fourth_place = ms[11][1] if m12_red_winner else ms[11][0]\n", + " ms[12].append(ms[11][0] if m12_red_winner else ms[11][1])\n", + " \n", + " m13_red_winner = random.random() < _get_win_prob(12)\n", + " third_place = ms[12][1] if m13_red_winner else ms[12][0]\n", + " finalist_2 = ms[12][0] if m13_red_winner else ms[12][1]\n", + " \n", + " \n", + " f1_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f2_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f3_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " winner = finalist_1 if f1_red_winner + f2_red_winner + f3_red_winner >= 2 else finalist_2\n", + " second_place = finalist_2 if winner == finalist_1 else finalist_1\n", + " \n", + " return winner, second_place, third_place, fourth_place, scores, grids\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "62276690", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n" + ] + } + ], + "source": [ + "overall_winner_count = defaultdict(int)\n", + "overall_finalist_count = defaultdict(int)\n", + "overall_third_place_count = defaultdict(int)\n", + "overall_fourth_place_count = defaultdict(int)\n", + "\n", + "winner_count = defaultdict(int)\n", + "finalist_count = defaultdict(int)\n", + "third_place_count = defaultdict(int)\n", + "fourth_place_count = defaultdict(int)\n", + "\n", + "winner_alliances = defaultdict(int)\n", + "winner_best_epas = []\n", + "alliance_epas = []\n", + "best_epas = []\n", + "winner_epas = []\n", + "\n", + "einstein_winner_best_epas = []\n", + "einstein_alliance_epas = []\n", + "einstein_best_epas = []\n", + "einstein_winner_epas = []\n", + "\n", + "quals_score_distrib = []\n", + "quals_grid_distrib = []\n", + "\n", + "elims_score_distrib = []\n", + "elims_grid_distrib = []\n", + "\n", + "einstein_score_distrib = []\n", + "einstein_grid_distrib = []\n", + "\n", + "qual_rank_list = defaultdict(lambda: [0] * 78)\n", + "\n", + "num_sims = 100000\n", + "\n", + "def pre_sim(all_teams):\n", + " for sim in range(num_sims):\n", + " if sim % 100 == 0:\n", + " print(sim)\n", + " \n", + " random.shuffle(all_teams)\n", + "\n", + " division_1 = all_teams[:78]\n", + " division_2 = all_teams[78:156]\n", + " division_3 = all_teams[156:233]\n", + " division_4 = all_teams[233:310]\n", + " division_5 = all_teams[310:388]\n", + " division_6 = all_teams[388:466]\n", + " division_7 = all_teams[466:543]\n", + " division_8 = all_teams[543:620]\n", + "\n", + " divisions = [division_1, division_2, division_3, division_4, division_5, division_6, division_7, division_8]\n", + "\n", + " einstein_alliances = []\n", + " einstein_aepas = []\n", + " for division in divisions:\n", + " random.shuffle(division)\n", + " schedule = get_schedule(len(division), 10)\n", + " schedule = [\n", + " {\n", + " \"red\": [division[x - 1] for x in m[\"red\"]],\n", + " \"blue\": [division[x - 1] for x in m[\"blue\"]],\n", + " }\n", + " for m in schedule\n", + " ]\n", + " qual_ranks, qual_scores, qual_grids = sim_single_quals(division, schedule)\n", + " for i, t in enumerate(qual_ranks):\n", + " qual_rank_list[t][i] += 1\n", + " \n", + " quals_score_distrib.extend(qual_scores)\n", + " quals_grid_distrib.extend(qual_grids)\n", + " \n", + " alliances, aepas = sim_alliance_selection(qual_ranks)\n", + " winner, finalist, third_place, fourth_place, elim_scores, elim_grids = sim_single_elims(alliances)\n", + " einstein_alliances.append(alliances[winner])\n", + " einstein_aepas.append(aepas[winner])\n", + " \n", + " elims_score_distrib.extend(elim_scores)\n", + " elims_grid_distrib.extend(elim_grids)\n", + " \n", + " winner_alliances[winner] += 1\n", + " best_epa = max(aepas)\n", + " winner_epa = aepas[winner]\n", + " winner_best_epas.append(best_epa == winner_epa)\n", + " alliance_epas.extend(aepas)\n", + " best_epas.append(best_epa)\n", + " winner_epas.append(winner_epa)\n", + " \n", + " for t in alliances[winner]:\n", + " winner_count[t] += 1\n", + " \n", + " for t in alliances[finalist]:\n", + " finalist_count[t] += 1\n", + " \n", + " for t in alliances[third_place]:\n", + " third_place_count[t] += 1\n", + " \n", + " for t in alliances[fourth_place]:\n", + " fourth_place_count[t] += 1\n", + " \n", + " winner, finalist, third_place, fourth_place, einstein_scores, einstein_grids = sim_single_elims(einstein_alliances)\n", + "\n", + " einstein_score_distrib.extend(einstein_scores)\n", + " einstein_grid_distrib.extend(einstein_grids)\n", + " \n", + " einstein_best_epa = max(einstein_aepas)\n", + " einstein_winner_epa = einstein_aepas[winner]\n", + " einstein_winner_best_epas.append(einstein_best_epa == einstein_winner_epa)\n", + " einstein_alliance_epas.extend(einstein_aepas)\n", + " einstein_best_epas.append(einstein_best_epa)\n", + " einstein_winner_epas.append(einstein_winner_epa)\n", + "\n", + " for t in einstein_alliances[winner]:\n", + " overall_winner_count[t] += 1\n", + " \n", + " for t in einstein_alliances[finalist]:\n", + " overall_finalist_count[t] += 1\n", + " \n", + " for t in einstein_alliances[third_place]:\n", + " overall_third_place_count[t] += 1\n", + " \n", + " for t in einstein_alliances[fourth_place]:\n", + " overall_fourth_place_count[t] += 1\n", + " \n", + "pre_sim(champ_team_nums)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1d053d42", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Division\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 66.3% | 11.5% | 6.8% | 4.7% |\n", + "| 2 | 1323 | 57.5% | 13.7% | 8.6% | 5.9% |\n", + "| 3 | 254 | 56.7% | 13.7% | 9.0% | 6.0% |\n", + "| 4 | 1678 | 40.7% | 16.5% | 11.7% | 8.5% |\n", + "| 5 | 3005 | 37.9% | 16.9% | 12.2% | 8.9% |\n", + "| 6 | 111 | 31.5% | 17.1% | 12.9% | 10.1% |\n", + "| 7 | 971 | 31.0% | 17.1% | 12.9% | 10.2% |\n", + "| 8 | 3538 | 30.5% | 17.1% | 13.0% | 10.1% |\n", + "| 9 | 5940 | 29.8% | 17.0% | 12.9% | 10.4% |\n", + "| 10 | 6036 | 29.6% | 17.1% | 13.2% | 10.2% |\n", + "| 11 | 930 | 24.6% | 16.9% | 13.4% | 11.3% |\n", + "| 12 | 6672 | 24.5% | 16.6% | 13.5% | 11.3% |\n", + "| 13 | 7157 | 23.4% | 16.6% | 13.6% | 11.4% |\n", + "| 14 | 2337 | 22.5% | 25.5% | 24.5% | 24.3% |\n", + "| 15 | 1987 | 20.6% | 16.1% | 13.6% | 11.7% |\n", + "| 16 | 1619 | 20.4% | 16.4% | 13.7% | 11.9% |\n", + "| 17 | 195 | 20.3% | 16.1% | 13.5% | 11.9% |\n", + "| 18 | 333 | 19.8% | 20.3% | 20.6% | 20.6% |\n", + "| 19 | 2910 | 19.1% | 15.7% | 13.7% | 12.0% |\n", + "| 20 | 3683 | 18.9% | 15.8% | 13.8% | 11.9% |\n", + "| 21 | 176 | 18.5% | 15.8% | 13.5% | 12.2% |\n", + "| 22 | 4028 | 18.4% | 15.5% | 13.6% | 12.0% |\n", + "| 23 | 2338 | 18.2% | 15.6% | 13.6% | 12.2% |\n", + "| 24 | 1577 | 18.1% | 15.4% | 13.7% | 12.3% |\n", + "| 25 | 3467 | 18.0% | 15.5% | 13.5% | 12.2% |\n", + "\n", + "Division\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 66.3% | 11.5% | 6.8% | 4.7% |\n", + "| 2 | 1323 | 57.5% | 13.7% | 8.6% | 5.9% |\n", + "| 3 | 254 | 56.7% | 13.7% | 9.0% | 6.0% |\n", + "| 4 | 1678 | 40.7% | 16.5% | 11.7% | 8.5% |\n", + "| 5 | 3005 | 37.9% | 16.9% | 12.2% | 8.9% |\n", + "| 6 | 111 | 31.5% | 17.1% | 12.9% | 10.1% |\n", + "| 7 | 971 | 31.0% | 17.1% | 12.9% | 10.2% |\n", + "| 8 | 3538 | 30.5% | 17.1% | 13.0% | 10.1% |\n", + "| 9 | 5940 | 29.8% | 17.0% | 12.9% | 10.4% |\n", + "| 10 | 6036 | 29.6% | 17.1% | 13.2% | 10.2% |\n", + "| 11 | 930 | 24.6% | 16.9% | 13.4% | 11.3% |\n", + "| 12 | 6672 | 24.5% | 16.6% | 13.5% | 11.3% |\n", + "| 13 | 7157 | 23.4% | 16.6% | 13.6% | 11.4% |\n", + "| 14 | 2337 | 22.5% | 25.5% | 24.5% | 24.3% |\n", + "| 15 | 1987 | 20.6% | 16.1% | 13.6% | 11.7% |\n", + "| 16 | 1619 | 20.4% | 16.4% | 13.7% | 11.9% |\n", + "| 17 | 195 | 20.3% | 16.1% | 13.5% | 11.9% |\n", + "| 18 | 333 | 19.8% | 20.3% | 20.6% | 20.6% |\n", + "| 19 | 2910 | 19.1% | 15.7% | 13.7% | 12.0% |\n", + "| 20 | 3683 | 18.9% | 15.8% | 13.8% | 11.9% |\n", + "| 21 | 176 | 18.5% | 15.8% | 13.5% | 12.2% |\n", + "| 22 | 4028 | 18.4% | 15.5% | 13.6% | 12.0% |\n", + "| 23 | 2338 | 18.2% | 15.6% | 13.6% | 12.2% |\n", + "| 24 | 1577 | 18.1% | 15.4% | 13.7% | 12.3% |\n", + "| 25 | 3467 | 18.0% | 15.5% | 13.5% | 12.2% |\n", + "| 26 | 4414 | 17.3% | 15.4% | 13.5% | 12.2% |\n", + "| 27 | 1591 | 16.7% | 15.4% | 13.7% | 12.3% |\n", + "| 28 | 2539 | 16.4% | 14.8% | 13.5% | 12.5% |\n", + "| 29 | 4499 | 15.6% | 14.6% | 13.6% | 12.5% |\n", + "| 30 | 359 | 15.3% | 14.9% | 13.7% | 12.4% |\n", + "| 31 | 2468 | 15.3% | 14.7% | 13.5% | 12.5% |\n", + "| 32 | 2767 | 15.1% | 14.6% | 13.5% | 12.5% |\n", + "| 33 | 8013 | 15.1% | 16.0% | 16.7% | 16.9% |\n", + "| 34 | 4976 | 15.0% | 16.7% | 17.3% | 18.2% |\n", + "| 35 | 1706 | 14.8% | 14.7% | 13.4% | 12.6% |\n", + "| 36 | 987 | 14.4% | 14.4% | 13.4% | 12.7% |\n", + "| 37 | 6090 | 14.2% | 14.5% | 13.6% | 12.5% |\n", + "| 38 | 7890 | 14.1% | 14.4% | 13.5% | 12.6% |\n", + "| 39 | 5913 | 13.5% | 14.1% | 13.3% | 12.9% |\n", + "| 40 | 2687 | 13.4% | 14.2% | 13.1% | 12.9% |\n", + "| 41 | 4907 | 13.2% | 13.9% | 13.3% | 12.9% |\n", + "| 42 | 1756 | 13.0% | 14.0% | 13.3% | 12.8% |\n", + "| 43 | 1538 | 13.0% | 14.0% | 13.4% | 12.7% |\n", + "| 44 | 1727 | 12.9% | 13.9% | 13.3% | 12.7% |\n", + "| 45 | 6329 | 12.5% | 13.6% | 13.3% | 12.8% |\n", + "| 46 | 604 | 12.4% | 13.7% | 13.2% | 13.0% |\n", + "| 47 | 694 | 12.3% | 13.7% | 13.1% | 12.7% |\n", + "| 48 | 4522 | 12.3% | 13.8% | 13.0% | 12.9% |\n", + "| 49 | 4381 | 12.2% | 13.6% | 13.2% | 12.6% |\n", + "| 50 | 148 | 12.2% | 13.5% | 13.0% | 12.9% |\n", + "| 51 | 3847 | 12.2% | 12.1% | 12.3% | 12.0% |\n", + "| 52 | 179 | 12.0% | 12.0% | 12.0% | 12.0% |\n", + "| 53 | 2883 | 11.9% | 12.0% | 12.2% | 12.1% |\n", + "| 54 | 4476 | 11.9% | 12.1% | 11.9% | 12.0% |\n", + "| 55 | 5712 | 11.9% | 12.2% | 12.2% | 11.9% |\n", + "| 56 | 2363 | 11.9% | 13.3% | 12.9% | 12.9% |\n", + "| 57 | 1468 | 11.8% | 11.6% | 11.5% | 11.4% |\n", + "| 58 | 5166 | 11.8% | 11.8% | 12.0% | 11.8% |\n", + "| 59 | 4336 | 11.8% | 11.4% | 11.7% | 11.6% |\n", + "| 60 | 245 | 11.8% | 11.9% | 12.2% | 12.0% |\n", + "| 61 | 1868 | 11.7% | 12.0% | 12.1% | 12.4% |\n", + "| 62 | 2930 | 11.7% | 12.0% | 12.1% | 12.2% |\n", + "| 63 | 5460 | 11.7% | 12.2% | 12.2% | 12.2% |\n", + "| 64 | 5895 | 11.7% | 13.4% | 13.2% | 12.8% |\n", + "| 65 | 4635 | 11.7% | 11.9% | 12.1% | 12.1% |\n", + "| 66 | 70 | 11.7% | 11.9% | 12.2% | 12.0% |\n", + "| 67 | 7407 | 11.7% | 12.2% | 12.3% | 12.4% |\n", + "| 68 | 1189 | 11.6% | 11.5% | 11.9% | 11.8% |\n", + "| 69 | 9312 | 11.6% | 12.1% | 12.1% | 12.1% |\n", + "| 70 | 3647 | 11.6% | 12.2% | 12.2% | 12.0% |\n", + "| 71 | 4020 | 11.6% | 12.1% | 12.2% | 12.3% |\n", + "| 72 | 4607 | 11.6% | 11.6% | 11.7% | 11.7% |\n", + "| 73 | 5232 | 11.5% | 11.3% | 11.6% | 11.5% |\n", + "| 74 | 7211 | 11.5% | 11.9% | 11.8% | 11.8% |\n", + "| 75 | 1771 | 11.5% | 11.6% | 11.8% | 11.8% |\n", + "| 76 | 1318 | 11.5% | 12.2% | 12.2% | 12.1% |\n", + "| 77 | 3539 | 11.4% | 11.7% | 12.2% | 12.1% |\n", + "| 78 | 876 | 11.4% | 11.8% | 11.8% | 11.7% |\n", + "| 79 | 5804 | 11.4% | 12.1% | 12.3% | 12.3% |\n", + "| 80 | 1403 | 11.4% | 12.3% | 12.3% | 12.4% |\n", + "| 81 | 5406 | 11.4% | 11.9% | 12.2% | 12.5% |\n", + "| 82 | 4481 | 11.4% | 12.2% | 12.2% | 12.5% |\n", + "| 83 | 3668 | 11.4% | 12.0% | 12.1% | 12.3% |\n", + "| 84 | 1757 | 11.3% | 13.3% | 12.8% | 12.8% |\n", + "| 85 | 2659 | 11.3% | 11.3% | 11.4% | 11.6% |\n", + "| 86 | 1745 | 11.3% | 11.6% | 11.7% | 11.7% |\n", + "| 87 | 461 | 11.3% | 13.1% | 13.1% | 12.9% |\n", + "| 88 | 599 | 11.3% | 10.9% | 11.1% | 11.1% |\n", + "| 89 | 1732 | 11.3% | 12.1% | 12.3% | 12.1% |\n", + "| 90 | 862 | 11.2% | 12.3% | 12.2% | 12.5% |\n", + "| 91 | 972 | 11.2% | 11.4% | 11.8% | 11.6% |\n", + "| 92 | 3478 | 11.2% | 11.1% | 11.6% | 11.5% |\n", + "| 93 | 6919 | 11.2% | 11.7% | 11.7% | 11.6% |\n", + "| 94 | 3175 | 11.1% | 13.1% | 12.9% | 12.8% |\n", + "| 95 | 2075 | 11.1% | 13.0% | 13.1% | 12.8% |\n", + "| 96 | 5010 | 11.1% | 12.1% | 12.3% | 12.4% |\n", + "| 97 | 1325 | 11.1% | 13.1% | 13.1% | 12.9% |\n", + "| 98 | 1241 | 11.1% | 12.2% | 12.3% | 12.5% |\n", + "| 99 | 2974 | 11.0% | 12.2% | 12.5% | 12.4% |\n", + "| 100 | 4362 | 11.0% | 12.2% | 12.6% | 12.6% |\n", + "\n", + "Einstein\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 31.6% | 11.3% | 7.1% | 5.3% |\n", + "| 2 | 1323 | 21.3% | 10.7% | 7.2% | 5.6% |\n", + "| 3 | 254 | 20.9% | 10.5% | 7.1% | 5.7% |\n", + "| 4 | 1678 | 9.8% | 7.3% | 5.7% | 5.0% |\n", + "| 5 | 3005 | 8.6% | 6.7% | 5.5% | 4.6% |\n", + "| 6 | 111 | 5.9% | 5.2% | 4.5% | 4.2% |\n", + "| 7 | 971 | 5.6% | 5.2% | 4.5% | 4.0% |\n", + "| 8 | 3538 | 5.6% | 5.1% | 4.3% | 4.0% |\n", + "| 9 | 5940 | 5.2% | 5.0% | 4.2% | 3.9% |\n", + "| 10 | 6036 | 5.1% | 4.9% | 4.2% | 3.8% |\n", + "| 11 | 6672 | 3.5% | 3.8% | 3.5% | 3.3% |\n", + "| 12 | 930 | 3.5% | 3.8% | 3.5% | 3.4% |\n", + "| 13 | 7157 | 3.2% | 3.5% | 3.3% | 3.2% |\n", + "| 14 | 1619 | 2.4% | 3.0% | 2.8% | 2.8% |\n", + "| 15 | 1987 | 2.4% | 3.0% | 2.8% | 2.7% |\n", + "| 16 | 195 | 2.4% | 2.8% | 2.9% | 2.7% |\n", + "| 17 | 333 | 2.3% | 2.4% | 2.5% | 2.4% |\n", + "| 18 | 2910 | 2.1% | 2.7% | 2.7% | 2.5% |\n", + "| 19 | 3683 | 2.1% | 2.6% | 2.7% | 2.6% |\n", + "| 20 | 4028 | 2.0% | 2.5% | 2.6% | 2.5% |\n", + "| 21 | 176 | 1.9% | 2.5% | 2.5% | 2.6% |\n", + "| 22 | 2338 | 1.9% | 2.4% | 2.5% | 2.5% |\n", + "| 23 | 3467 | 1.9% | 2.4% | 2.5% | 2.5% |\n", + "| 24 | 1577 | 1.8% | 2.5% | 2.5% | 2.5% |\n", + "| 25 | 4414 | 1.7% | 2.3% | 2.4% | 2.3% |\n", + "\n", + "Einstein\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 31.6% | 11.3% | 7.1% | 5.3% |\n", + "| 2 | 1323 | 21.3% | 10.7% | 7.2% | 5.6% |\n", + "| 3 | 254 | 20.9% | 10.5% | 7.1% | 5.7% |\n", + "| 4 | 1678 | 9.8% | 7.3% | 5.7% | 5.0% |\n", + "| 5 | 3005 | 8.6% | 6.7% | 5.5% | 4.6% |\n", + "| 6 | 111 | 5.9% | 5.2% | 4.5% | 4.2% |\n", + "| 7 | 971 | 5.6% | 5.2% | 4.5% | 4.0% |\n", + "| 8 | 3538 | 5.6% | 5.1% | 4.3% | 4.0% |\n", + "| 9 | 5940 | 5.2% | 5.0% | 4.2% | 3.9% |\n", + "| 10 | 6036 | 5.1% | 4.9% | 4.2% | 3.8% |\n", + "| 11 | 6672 | 3.5% | 3.8% | 3.5% | 3.3% |\n", + "| 12 | 930 | 3.5% | 3.8% | 3.5% | 3.4% |\n", + "| 13 | 7157 | 3.2% | 3.5% | 3.3% | 3.2% |\n", + "| 14 | 1619 | 2.4% | 3.0% | 2.8% | 2.8% |\n", + "| 15 | 1987 | 2.4% | 3.0% | 2.8% | 2.7% |\n", + "| 16 | 195 | 2.4% | 2.8% | 2.9% | 2.7% |\n", + "| 17 | 333 | 2.3% | 2.4% | 2.5% | 2.4% |\n", + "| 18 | 2910 | 2.1% | 2.7% | 2.7% | 2.5% |\n", + "| 19 | 3683 | 2.1% | 2.6% | 2.7% | 2.6% |\n", + "| 20 | 4028 | 2.0% | 2.5% | 2.6% | 2.5% |\n", + "| 21 | 176 | 1.9% | 2.5% | 2.5% | 2.6% |\n", + "| 22 | 2338 | 1.9% | 2.4% | 2.5% | 2.5% |\n", + "| 23 | 3467 | 1.9% | 2.4% | 2.5% | 2.5% |\n", + "| 24 | 1577 | 1.8% | 2.5% | 2.5% | 2.5% |\n", + "| 25 | 4414 | 1.7% | 2.3% | 2.4% | 2.3% |\n", + "| 26 | 3847 | 1.6% | 1.6% | 1.5% | 1.6% |\n", + "| 27 | 2883 | 1.6% | 1.5% | 1.4% | 1.4% |\n", + "| 28 | 70 | 1.6% | 1.4% | 1.4% | 1.4% |\n", + "| 29 | 179 | 1.6% | 1.4% | 1.5% | 1.5% |\n", + "| 30 | 4336 | 1.6% | 1.4% | 1.5% | 1.4% |\n", + "| 31 | 1468 | 1.6% | 1.5% | 1.5% | 1.5% |\n", + "| 32 | 1189 | 1.6% | 1.4% | 1.4% | 1.5% |\n", + "| 33 | 1591 | 1.6% | 2.1% | 2.3% | 2.3% |\n", + "| 34 | 5460 | 1.6% | 1.4% | 1.4% | 1.5% |\n", + "| 35 | 5712 | 1.6% | 1.5% | 1.5% | 1.5% |\n", + "| 36 | 1868 | 1.6% | 1.5% | 1.4% | 1.5% |\n", + "| 37 | 8013 | 1.5% | 1.8% | 1.8% | 1.9% |\n", + "| 38 | 4976 | 1.5% | 1.7% | 1.9% | 1.9% |\n", + "| 39 | 9312 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 40 | 4635 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 41 | 245 | 1.5% | 1.5% | 1.4% | 1.5% |\n", + "| 42 | 2337 | 1.5% | 2.6% | 2.8% | 3.0% |\n", + "| 43 | 7407 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 44 | 2930 | 1.5% | 1.5% | 1.4% | 1.5% |\n", + "| 45 | 4476 | 1.5% | 1.5% | 1.4% | 1.5% |\n", + "| 46 | 5166 | 1.5% | 1.4% | 1.4% | 1.5% |\n", + "| 47 | 4607 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 48 | 4020 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 49 | 2539 | 1.5% | 2.2% | 2.2% | 2.3% |\n", + "| 50 | 3668 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 51 | 1403 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 52 | 876 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 53 | 3647 | 1.5% | 1.4% | 1.5% | 1.4% |\n", + "| 54 | 3539 | 1.5% | 1.3% | 1.4% | 1.4% |\n", + "| 55 | 1745 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 56 | 599 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 57 | 7211 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 58 | 5232 | 1.4% | 1.5% | 1.4% | 1.4% |\n", + "| 59 | 3478 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 60 | 2659 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 61 | 5406 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 62 | 5804 | 1.4% | 1.4% | 1.4% | 1.5% |\n", + "| 63 | 1318 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 64 | 1732 | 1.4% | 1.3% | 1.4% | 1.4% |\n", + "| 65 | 6919 | 1.4% | 1.3% | 1.3% | 1.4% |\n", + "| 66 | 4481 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 67 | 4903 | 1.4% | 1.4% | 1.3% | 1.3% |\n", + "| 68 | 972 | 1.4% | 1.3% | 1.4% | 1.4% |\n", + "| 69 | 862 | 1.4% | 1.3% | 1.4% | 1.3% |\n", + "| 70 | 1466 | 1.4% | 1.3% | 1.4% | 1.3% |\n", + "| 71 | 2240 | 1.4% | 1.3% | 1.3% | 1.4% |\n", + "| 72 | 4499 | 1.4% | 2.0% | 2.0% | 2.1% |\n", + "| 73 | 1771 | 1.4% | 1.4% | 1.4% | 1.5% |\n", + "| 74 | 5907 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 75 | 1768 | 1.3% | 1.3% | 1.4% | 1.3% |\n", + "| 76 | 3218 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 77 | 316 | 1.3% | 1.3% | 1.3% | 1.2% |\n", + "| 78 | 2468 | 1.3% | 1.9% | 2.1% | 2.1% |\n", + "| 79 | 1241 | 1.3% | 1.3% | 1.4% | 1.3% |\n", + "| 80 | 6045 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 81 | 4422 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 82 | 2767 | 1.3% | 1.8% | 2.1% | 2.1% |\n", + "| 83 | 5010 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 84 | 359 | 1.3% | 2.0% | 2.1% | 2.0% |\n", + "| 85 | 4362 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 86 | 2974 | 1.3% | 1.4% | 1.3% | 1.3% |\n", + "| 87 | 4373 | 1.3% | 1.4% | 1.4% | 1.3% |\n", + "| 88 | 1796 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 89 | 6722 | 1.3% | 1.4% | 1.4% | 1.4% |\n", + "| 90 | 1706 | 1.3% | 1.9% | 2.0% | 2.0% |\n", + "| 91 | 6002 | 1.2% | 1.3% | 1.3% | 1.3% |\n", + "| 92 | 115 | 1.2% | 1.2% | 1.3% | 1.3% |\n", + "| 93 | 5687 | 1.2% | 1.3% | 1.4% | 1.3% |\n", + "| 94 | 1701 | 1.2% | 1.2% | 1.2% | 1.2% |\n", + "| 95 | 1731 | 1.2% | 1.2% | 1.2% | 1.2% |\n", + "| 96 | 5987 | 1.2% | 1.2% | 1.3% | 1.3% |\n", + "| 97 | 1690 | 1.2% | 1.2% | 1.4% | 1.4% |\n", + "| 98 | 6377 | 1.2% | 1.3% | 1.3% | 1.3% |\n", + "| 99 | 2992 | 1.2% | 1.2% | 1.3% | 1.3% |\n", + "| 100 | 1807 | 1.2% | 1.2% | 1.2% | 1.2% |\n", + "\n", + "| Alliance | Win Probability |\n", + "| --- | --- |\n", + "| 1 | 34.13% |\n", + "| 2 | 16.78% |\n", + "| 3 | 11.98% |\n", + "| 4 | 9.62% |\n", + "| 5 | 8.13% |\n", + "| 6 | 7.16% |\n", + "| 7 | 6.4% |\n", + "| 8 | 5.8% |\n", + "\n", + "Probability 'Favorite' Wins: 0.4607\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Average Division Alliance EPA: 168.6\n", + "Average Division 'Favorite' EPA: 186.7\n", + "Average Division Winner EPA: 180.5\n", + "\n", + "Probability Einstein 'Favorite' Wins: 0.5091\n", + "Average Einstein Alliance EPA: 180.5\n", + "Average Einstein 'Favorite' EPA: 202.3\n", + "Average Einstein Winner EPA: 196.1\n", + "\n" + ] + } + ], + "source": [ + "def pad(s, length = 15):\n", + " return s + \" \" * (length - len(s))\n", + "\n", + "print(\"Division\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(winner_count.items(), key=lambda x: -x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Division\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(winner_count.items(), key=lambda x: -x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Einstein\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(overall_winner_count.items(), key=lambda x: -x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * overall_winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Einstein\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(overall_winner_count.items(), key=lambda x: -x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * overall_winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"| Alliance | Win Probability |\")\n", + "print(\"| --- | --- |\")\n", + "for i, count in sorted(winner_alliances.items(), key=lambda x: -x[1]):\n", + " print(\"|\", i + 1, \"|\", str(round(100 * count / 8 / num_sims, 2)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Probability 'Favorite' Wins:\", round(np.array(winner_best_epas).mean(), 4))\n", + "print(\"Average Division Alliance EPA:\", round(np.array(alliance_epas).mean(), 1))\n", + "print(\"Average Division 'Favorite' EPA:\", round(np.array(best_epas).mean(), 1))\n", + "print(\"Average Division Winner EPA:\", round(np.array(winner_epas).mean(), 1))\n", + "print()\n", + "\n", + "print(\"Probability Einstein 'Favorite' Wins:\", round(np.array(einstein_winner_best_epas).mean(), 4))\n", + "print(\"Average Einstein Alliance EPA:\", round(np.array(einstein_alliance_epas).mean(), 1))\n", + "print(\"Average Einstein 'Favorite' EPA:\", round(np.array(einstein_best_epas).mean(), 1))\n", + "print(\"Average Einstein Winner EPA:\", round(np.array(einstein_winner_epas).mean(), 1))\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "13c5b686", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| Rank | Team            | Mean Rank       | 1st             | Top 4           | Top 8           | Top 16          |\n", + "| --- | --- | --- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 5.13 | 28.8% | 62.4% | 79.6% | 92.0% |\n", + "| 2 | 1323 | 5.53 | 26.6% | 59.7% | 77.5% | 91.0% |\n", + "| 3 | 254 | 5.88 | 24.9% | 57.2% | 75.6% | 90.0% |\n", + "| 4 | 1678 | 7.44 | 18.9% | 47.8% | 67.3% | 85.6% |\n", + "| 5 | 3538 | 9.61 | 12.9% | 37.5% | 57.2% | 78.7% |\n", + "| 6 | 971 | 10.63 | 11.1% | 34.0% | 53.1% | 75.4% |\n", + "| 7 | 3005 | 10.74 | 10.7% | 33.3% | 52.9% | 75.1% |\n", + "| 8 | 930 | 10.82 | 10.6% | 32.9% | 52.3% | 74.9% |\n", + "| 9 | 6036 | 10.87 | 10.7% | 32.9% | 52.3% | 74.6% |\n", + "| 10 | 111 | 11.06 | 10.5% | 32.6% | 51.8% | 74.1% |\n", + "| 11 | 1987 | 11.12 | 10.0% | 31.7% | 50.9% | 73.9% |\n", + "| 12 | 176 | 11.21 | 9.7% | 31.3% | 50.4% | 73.5% |\n", + "| 13 | 5940 | 11.35 | 9.9% | 31.6% | 50.5% | 73.3% |\n", + "| 14 | 195 | 11.5 | 9.5% | 30.5% | 49.5% | 72.7% |\n", + "| 15 | 4414 | 12.15 | 8.5% | 28.3% | 46.7% | 70.6% |\n", + "| 16 | 3467 | 12.47 | 8.2% | 27.6% | 46.0% | 69.6% |\n", + "| 17 | 6672 | 12.64 | 8.4% | 27.5% | 45.6% | 68.9% |\n", + "| 18 | 2910 | 12.7 | 7.9% | 26.6% | 45.1% | 68.8% |\n", + "| 19 | 7157 | 12.71 | 8.2% | 27.2% | 45.2% | 68.6% |\n", + "| 20 | 1619 | 13.16 | 7.4% | 25.8% | 43.9% | 67.2% |\n", + "| 21 | 2338 | 13.23 | 7.5% | 25.4% | 43.2% | 67.1% |\n", + "| 22 | 2767 | 13.25 | 7.3% | 25.3% | 43.1% | 66.9% |\n", + "| 23 | 2539 | 13.3 | 7.2% | 25.2% | 42.9% | 66.8% |\n", + "| 24 | 1577 | 13.37 | 7.2% | 24.8% | 42.7% | 66.5% |\n", + "| 25 | 2468 | 13.4 | 7.2% | 24.8% | 42.5% | 66.4% |\n", + "\n", + "| Rank | Team            | Mean Rank       | 1st             | Top 4           | Top 8           | Top 16          |\n", + "| --- | --- | --- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 5.13 | 28.8% | 62.4% | 79.6% | 92.0% |\n", + "| 2 | 1323 | 5.53 | 26.6% | 59.7% | 77.5% | 91.0% |\n", + "| 3 | 254 | 5.88 | 24.9% | 57.2% | 75.6% | 90.0% |\n", + "| 4 | 1678 | 7.44 | 18.9% | 47.8% | 67.3% | 85.6% |\n", + "| 5 | 3538 | 9.61 | 12.9% | 37.5% | 57.2% | 78.7% |\n", + "| 6 | 971 | 10.63 | 11.1% | 34.0% | 53.1% | 75.4% |\n", + "| 7 | 3005 | 10.74 | 10.7% | 33.3% | 52.9% | 75.1% |\n", + "| 8 | 930 | 10.82 | 10.6% | 32.9% | 52.3% | 74.9% |\n", + "| 9 | 6036 | 10.87 | 10.7% | 32.9% | 52.3% | 74.6% |\n", + "| 10 | 111 | 11.06 | 10.5% | 32.6% | 51.8% | 74.1% |\n", + "| 11 | 1987 | 11.12 | 10.0% | 31.7% | 50.9% | 73.9% |\n", + "| 12 | 176 | 11.21 | 9.7% | 31.3% | 50.4% | 73.5% |\n", + "| 13 | 5940 | 11.35 | 9.9% | 31.6% | 50.5% | 73.3% |\n", + "| 14 | 195 | 11.5 | 9.5% | 30.5% | 49.5% | 72.7% |\n", + "| 15 | 4414 | 12.15 | 8.5% | 28.3% | 46.7% | 70.6% |\n", + "| 16 | 3467 | 12.47 | 8.2% | 27.6% | 46.0% | 69.6% |\n", + "| 17 | 6672 | 12.64 | 8.4% | 27.5% | 45.6% | 68.9% |\n", + "| 18 | 2910 | 12.7 | 7.9% | 26.6% | 45.1% | 68.8% |\n", + "| 19 | 7157 | 12.71 | 8.2% | 27.2% | 45.2% | 68.6% |\n", + "| 20 | 1619 | 13.16 | 7.4% | 25.8% | 43.9% | 67.2% |\n", + "| 21 | 2338 | 13.23 | 7.5% | 25.4% | 43.2% | 67.1% |\n", + "| 22 | 2767 | 13.25 | 7.3% | 25.3% | 43.1% | 66.9% |\n", + "| 23 | 2539 | 13.3 | 7.2% | 25.2% | 42.9% | 66.8% |\n", + "| 24 | 1577 | 13.37 | 7.2% | 24.8% | 42.7% | 66.5% |\n", + "| 25 | 2468 | 13.4 | 7.2% | 24.8% | 42.5% | 66.4% |\n", + "| 26 | 118 | 14.05 | 6.1% | 22.4% | 39.8% | 64.2% |\n", + "| 27 | 4522 | 14.28 | 6.2% | 22.4% | 39.5% | 63.4% |\n", + "| 28 | 3175 | 14.34 | 6.1% | 22.1% | 39.1% | 63.3% |\n", + "| 29 | 694 | 14.63 | 5.8% | 21.5% | 38.4% | 62.5% |\n", + "| 30 | 4381 | 14.72 | 5.7% | 21.5% | 38.1% | 62.0% |\n", + "| 31 | 4028 | 14.95 | 5.8% | 21.2% | 37.8% | 61.5% |\n", + "| 32 | 359 | 14.99 | 5.6% | 21.1% | 37.6% | 61.5% |\n", + "| 33 | 6090 | 15.09 | 5.5% | 20.6% | 37.1% | 60.9% |\n", + "| 34 | 2687 | 15.15 | 5.5% | 20.5% | 36.9% | 60.8% |\n", + "| 35 | 1706 | 15.36 | 5.5% | 20.2% | 36.5% | 60.1% |\n", + "| 36 | 3357 | 15.41 | 5.4% | 20.0% | 35.9% | 59.9% |\n", + "| 37 | 3683 | 15.41 | 5.5% | 20.3% | 36.5% | 60.3% |\n", + "| 38 | 6329 | 15.62 | 5.2% | 19.7% | 35.6% | 59.4% |\n", + "| 39 | 7890 | 15.76 | 5.1% | 19.3% | 35.0% | 58.9% |\n", + "| 40 | 4907 | 15.9 | 5.1% | 19.1% | 34.9% | 58.5% |\n", + "| 41 | 3015 | 15.94 | 4.9% | 18.8% | 34.5% | 58.4% |\n", + "| 42 | 1591 | 15.99 | 5.1% | 19.3% | 35.0% | 58.3% |\n", + "| 43 | 230 | 16.23 | 4.6% | 18.1% | 33.7% | 57.5% |\n", + "| 44 | 4499 | 16.52 | 4.7% | 18.1% | 33.3% | 56.8% |\n", + "| 45 | 4613 | 16.53 | 4.5% | 17.6% | 32.8% | 56.4% |\n", + "| 46 | 1727 | 16.54 | 4.6% | 17.7% | 33.0% | 56.6% |\n", + "| 47 | 2046 | 16.64 | 4.4% | 17.1% | 32.2% | 56.0% |\n", + "| 48 | 973 | 16.79 | 4.2% | 16.8% | 31.8% | 55.6% |\n", + "| 49 | 5913 | 16.82 | 4.4% | 17.4% | 32.4% | 55.7% |\n", + "| 50 | 870 | 16.84 | 4.3% | 16.8% | 31.9% | 55.5% |\n", + "| 51 | 4270 | 17.04 | 4.1% | 16.6% | 31.3% | 54.7% |\n", + "| 52 | 604 | 17.07 | 4.2% | 16.8% | 31.7% | 55.0% |\n", + "| 53 | 1757 | 17.07 | 4.3% | 16.6% | 31.4% | 54.8% |\n", + "| 54 | 1325 | 17.13 | 4.2% | 16.6% | 31.3% | 54.9% |\n", + "| 55 | 148 | 17.17 | 4.2% | 16.8% | 31.5% | 54.7% |\n", + "| 56 | 5895 | 17.49 | 4.1% | 16.1% | 30.6% | 53.7% |\n", + "| 57 | 1756 | 17.52 | 4.0% | 16.0% | 30.3% | 53.7% |\n", + "| 58 | 3310 | 17.67 | 3.9% | 15.9% | 30.1% | 53.2% |\n", + "| 59 | 2363 | 17.72 | 4.0% | 15.7% | 29.8% | 53.0% |\n", + "| 60 | 987 | 17.98 | 3.8% | 15.4% | 29.5% | 52.4% |\n", + "| 61 | 3663 | 18.06 | 3.7% | 15.0% | 28.9% | 51.9% |\n", + "| 62 | 4391 | 18.07 | 3.7% | 14.9% | 28.8% | 51.9% |\n", + "| 63 | 341 | 18.2 | 3.6% | 14.8% | 28.8% | 51.6% |\n", + "| 64 | 1114 | 18.67 | 3.3% | 14.0% | 27.3% | 50.1% |\n", + "| 65 | 7457 | 18.68 | 3.3% | 13.8% | 27.3% | 50.2% |\n", + "| 66 | 2052 | 18.68 | 3.3% | 13.9% | 27.2% | 50.1% |\n", + "| 67 | 2451 | 18.71 | 3.4% | 14.2% | 27.6% | 50.1% |\n", + "| 68 | 1339 | 18.75 | 3.1% | 13.3% | 26.7% | 49.7% |\n", + "| 69 | 2481 | 18.76 | 3.4% | 13.8% | 27.3% | 49.8% |\n", + "| 70 | 3314 | 18.78 | 3.3% | 13.8% | 27.3% | 50.1% |\n", + "| 71 | 3184 | 18.86 | 3.3% | 14.0% | 27.3% | 49.5% |\n", + "| 72 | 51 | 18.88 | 3.3% | 13.9% | 27.1% | 49.6% |\n", + "| 73 | 7021 | 18.96 | 3.2% | 13.6% | 26.6% | 49.2% |\n", + "| 74 | 1923 | 19.04 | 3.1% | 13.1% | 26.2% | 49.0% |\n", + "| 75 | 2521 | 19.14 | 3.1% | 13.2% | 26.2% | 48.8% |\n", + "| 76 | 2075 | 19.16 | 3.2% | 13.5% | 26.4% | 48.8% |\n", + "| 77 | 1690 | 19.21 | 3.1% | 13.1% | 26.1% | 48.5% |\n", + "| 78 | 3937 | 19.66 | 3.0% | 12.6% | 25.1% | 47.4% |\n", + "| 79 | 4362 | 19.67 | 2.7% | 12.3% | 25.1% | 47.2% |\n", + "| 80 | 1718 | 19.69 | 3.0% | 12.9% | 25.3% | 47.4% |\n", + "| 81 | 494 | 19.7 | 2.8% | 12.3% | 24.7% | 47.0% |\n", + "| 82 | 695 | 19.84 | 2.8% | 12.4% | 24.9% | 46.8% |\n", + "| 83 | 8033 | 19.91 | 2.9% | 12.2% | 24.5% | 46.6% |\n", + "| 84 | 3476 | 20.01 | 2.8% | 12.1% | 24.5% | 46.4% |\n", + "| 85 | 67 | 20.18 | 2.8% | 12.0% | 24.1% | 45.8% |\n", + "| 86 | 1391 | 20.19 | 2.7% | 11.9% | 24.2% | 46.0% |\n", + "| 87 | 461 | 20.25 | 2.7% | 12.0% | 24.1% | 45.8% |\n", + "| 88 | 7769 | 20.31 | 2.7% | 11.9% | 24.1% | 45.6% |\n", + "| 89 | 6424 | 20.38 | 2.6% | 11.7% | 23.7% | 45.4% |\n", + "| 90 | 1796 | 20.38 | 2.5% | 11.2% | 23.4% | 45.2% |\n", + "| 91 | 2974 | 20.45 | 2.5% | 11.4% | 23.3% | 45.1% |\n", + "| 92 | 4946 | 20.65 | 2.6% | 11.4% | 23.2% | 44.6% |\n", + "| 93 | 6002 | 20.7 | 2.5% | 11.1% | 22.9% | 44.2% |\n", + "| 94 | 6328 | 20.72 | 2.5% | 11.3% | 23.1% | 44.5% |\n", + "| 95 | 125 | 20.77 | 2.4% | 11.1% | 22.7% | 44.1% |\n", + "| 96 | 4481 | 20.8 | 2.5% | 11.0% | 22.6% | 43.9% |\n", + "| 97 | 1732 | 20.93 | 2.3% | 10.7% | 22.2% | 43.6% |\n", + "| 98 | 5010 | 20.97 | 2.3% | 10.7% | 22.1% | 43.6% |\n", + "| 99 | 4003 | 21.1 | 2.3% | 10.2% | 21.6% | 43.0% |\n", + "| 100 | 180 | 21.11 | 2.2% | 10.4% | 21.6% | 43.2% |\n", + "\n" + ] + } + ], + "source": [ + "avg_ranks = {t: sum(((i + 1) * qual_rank_list[t][i]) for i in range(78)) / num_sims for t in qual_rank_list}\n", + "top_1 = {t: sum(qual_rank_list[t][i] for i in range(1)) / num_sims for t in qual_rank_list}\n", + "top_4 = {t: sum(qual_rank_list[t][i] for i in range(4)) / num_sims for t in qual_rank_list}\n", + "top_8 = {t: sum(qual_rank_list[t][i] for i in range(8)) / num_sims for t in qual_rank_list}\n", + "top_16 = {t: sum(qual_rank_list[t][i] for i in range(16)) / num_sims for t in qual_rank_list}\n", + "\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Mean Rank\"), \" | \", pad(\"1st\"), \" | \", pad(\"Top 4\"), \" | \", pad(\"Top 8\"), \" | \", pad(\"Top 16\"), \" |\")\n", + "print(\"| --- | --- | --- | --- | --- | --- | --- |\")\n", + "for i, (key, avg_rank) in enumerate(sorted(avg_ranks.items(), key=lambda x: x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", round(avg_rank, 2), \"|\", str(round(100 * top_1[key], 1)) + \"%\", \"|\", str(round(100 * top_4[key], 1)) + \"%\", \"|\", str(round(100 * top_8[key], 1)) + \"%\", \"|\", str(round(100 * top_16[key], 1)) + \"%\", \"|\")\n", + "print()\n", + " \n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Mean Rank\"), \" | \", pad(\"1st\"), \" | \", pad(\"Top 4\"), \" | \", pad(\"Top 8\"), \" | \", pad(\"Top 16\"), \" |\")\n", + "print(\"| --- | --- | --- | --- | --- | --- | --- |\")\n", + "for i, (key, avg_rank) in enumerate(sorted(avg_ranks.items(), key=lambda x: x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", round(avg_rank, 2), \"|\", str(round(100 * top_1[key], 1)) + \"%\", \"|\", str(round(100 * top_4[key], 1)) + \"%\", \"|\", str(round(100 * top_8[key], 1)) + \"%\", \"|\", str(round(100 * top_16[key], 1)) + \"%\", \"|\")\n", + "print()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a53f540c", + "metadata": {}, + "outputs": [], + "source": [ + "quals_score_distrib = np.array(quals_score_distrib)\n", + "elims_score_distrib = np.array(elims_score_distrib)\n", + "einstein_score_distrib = np.array(einstein_score_distrib)\n", + "\n", + "quals_grid_distrib = np.array(quals_grid_distrib)\n", + "elims_grid_distrib = np.array(elims_grid_distrib)\n", + "einstein_grid_distrib = np.array(einstein_grid_distrib)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a50b7934", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "124.79600341790419\n", + "169.39111698605774\n", + "181.63297854230765\n", + "\n", + "17.597071658301015\n", + "23.83914602651653\n", + "25.621365152475576\n" + ] + } + ], + "source": [ + "print(quals_score_distrib.mean())\n", + "print(elims_score_distrib.mean())\n", + "print(einstein_score_distrib.mean())\n", + "print()\n", + "\n", + "print(quals_grid_distrib.mean())\n", + "print(elims_grid_distrib.mean())\n", + "print(einstein_grid_distrib.mean())" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "31664503", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ranks 49.33 0.0% 0.2% 0.6% 2.7%\n", + "Division 0.0% 0.0% 0.1% 0.1%\n", + "Einstein 0.0% 0.0% 0.0% 0.0%\n" + ] + } + ], + "source": [ + "def get_stats(team):\n", + " print(\"Ranks\", round(avg_ranks[team], 2), str(round(100 * top_1[team], 1)) + \"%\", str(round(100 * top_4[team], 1)) + \"%\", str(round(100 * top_8[team], 1)) + \"%\", str(round(100 * top_16[team], 1)) + \"%\")\n", + " print(\"Division\", str(round(100 * winner_count[team] / num_sims, 1)) + \"%\", str(round(100 * finalist_count[team] / num_sims, 1)) + \"%\", str(round(100 * third_place_count[team] / num_sims, 1)) + \"%\", str(round(100 * fourth_place_count[team] / num_sims, 1)) + \"%\")\n", + " print(\"Einstein\", str(round(100 * overall_winner_count[team] / num_sims, 1)) + \"%\", str(round(100 * overall_finalist_count[team] / num_sims, 1)) + \"%\", str(round(100 * overall_third_place_count[team] / num_sims, 1)) + \"%\", str(round(100 * overall_fourth_place_count[team] / num_sims, 1)) + \"%\") \n", + " \n", + "get_stats(3003)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21e95ec8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/scripts/2023/Simulate Champs V3.ipynb b/scripts/2023/Simulate Champs V3.ipynb new file mode 100644 index 00000000..252eecb5 --- /dev/null +++ b/scripts/2023/Simulate Champs V3.ipynb @@ -0,0 +1,3157 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b698f107", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "from functools import lru_cache\n", + "import random\n", + "import requests\n", + "from requests import Session\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import statbotics\n", + "\n", + "%matplotlib notebook\n", + "\n", + "sb = statbotics.Statbotics()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4568bf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3286" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_teams = sb.get_team_years(year=2023, limit=10000)\n", + "all_teams_dict = {t[\"team\"]: t for t in all_teams}\n", + "len(all_teams)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4a08ee65", + "metadata": {}, + "outputs": [], + "source": [ + "AUTH_KEY = \"XeUIxlvO4CPc44NlLE3ncevDg7bAhp6CRy6zC9M2aQb2zGfys0M30eKwavFJSEJr\"\n", + "\n", + "read_prefix = \"https://www.thebluealliance.com/api/v3/\"\n", + "\n", + "session = Session()\n", + "session.headers.update({\"X-TBA-Auth-Key\": AUTH_KEY, \"X-TBA-Auth-Id\": \"\"})\n", + "\n", + "def get_tba(url):\n", + " response = session.get(read_prefix + url)\n", + " return response.json()\n", + "\n", + "@lru_cache()\n", + "def get_event_teams(key):\n", + " data = get_tba(f\"event/{key}/teams\")\n", + " return [int(x[\"key\"][3:]) for x in data]" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "f8fa559f", + "metadata": {}, + "outputs": [], + "source": [ + "divisions = [\n", + " get_event_teams(\"2023arc\"),\n", + " get_event_teams(\"2023cur\"),\n", + " get_event_teams(\"2023dal\"),\n", + " get_event_teams(\"2023gal\"),\n", + " get_event_teams(\"2023hop\"),\n", + " get_event_teams(\"2023joh\"),\n", + " get_event_teams(\"2023mil\"),\n", + " get_event_teams(\"2023new\"),\n", + "]\n", + "\n", + "champ_team_nums = []\n", + "for division in divisions:\n", + " champ_team_nums.extend(division)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7ab3cd85", + "metadata": {}, + "outputs": [], + "source": [ + "epa_breakdown = pd.read_json(\"https://raw.githubusercontent.com/avgupta456/statbotics/master/data/2023/epa_breakdown.json\", orient=\"index\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "b4529072", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "84.85 0.9931 0.5175 12.2601407515\n", + "80.19 0.9545 0.6071 11.6093456675\n" + ] + } + ], + "source": [ + "team_to_epa = {t: all_teams_dict[t][\"epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_1_epa = {t: all_teams_dict[t][\"rp_1_epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_2_epa = {t: all_teams_dict[t][\"rp_2_epa_end\"] for t in champ_team_nums}\n", + "team_to_cycles = {t: epa_breakdown.loc[t][\"total_cycles\"] for t in champ_team_nums}\n", + "\n", + "print(team_to_epa[2056], team_to_rp_1_epa[2056], team_to_rp_2_epa[2056], team_to_cycles[2056])\n", + "print(team_to_epa[254], team_to_rp_1_epa[254], team_to_rp_2_epa[254], team_to_cycles[254])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "38d2a765", + "metadata": {}, + "outputs": [], + "source": [ + "TOTAL_MEAN = 74.57\n", + "TOTAL_SD = 29.36" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "811dfb7e", + "metadata": {}, + "outputs": [], + "source": [ + "@lru_cache\n", + "def make_request(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " data = response.text\n", + " lines = data.split(\"\\n\")\n", + " return lines\n", + "\n", + "@lru_cache\n", + "def get_schedule(num_teams: int, num_matches: int):\n", + " # TODO: remove this once we have pre-generated schedules for 100+ teams\n", + " if num_teams > 100:\n", + " schedule1 = get_schedule(100, num_matches)\n", + " schedule2 = get_schedule(num_teams - 100, num_matches)\n", + " schedule2 = [\n", + " {\"red\": [team + 100 for team in match[\"red\"]], \"blue\": [team + 100 for team in match[\"blue\"]]}\n", + " for match in schedule2\n", + " ]\n", + " return schedule1 + schedule2\n", + "\n", + " # load csv from external URL using requests\n", + " lines = make_request(f\"https://raw.githubusercontent.com/Team254/cheesy-arena/main/schedules/{num_teams}_{num_matches}.csv\")\n", + " \n", + " schedule = []\n", + " for line in lines:\n", + " match = line.split(\",\")\n", + " if len(match) < 12:\n", + " continue\n", + " red = [int(match[0]), int(match[2]), int(match[4])]\n", + " blue = [int(match[6]), int(match[8]), int(match[10])]\n", + " schedule.append({\"red\": red, \"blue\": blue})\n", + " \n", + " return schedule" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "c2233c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def get_win_prob(a, b):\n", + " return 1 / (1 + 10 ** (((-5 / 8) * (a - b)) / TOTAL_SD))\n", + "\n", + "def get_rp_pred(a):\n", + " return 1 / (1 + np.e ** (-4 * (a - 0.5)))\n", + "\n", + "def sim_single_quals(teams, schedule, team_to_epa, team_to_rp_1_epa, team_to_rp_2_epa):\n", + " curr_sim_matches = {t: 0 for t in teams}\n", + " curr_sim_rps = {t: 0 for t in teams}\n", + " for m in schedule:\n", + " red_epa = sum(team_to_epa[x] for x in m[\"red\"])\n", + " blue_epa = sum(team_to_epa[x] for x in m[\"blue\"])\n", + " red_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"red\"])\n", + " blue_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"blue\"])\n", + " red_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"red\"])\n", + " blue_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"blue\"])\n", + " \n", + " win_prob = get_win_prob(red_epa, blue_epa)\n", + " red_win = 1 if random.random() < win_prob else 0\n", + "\n", + " red_rp_1_prob = get_rp_pred(0.9 * red_rp_1_epa)\n", + " red_rp_1 = 1 if random.random() < red_rp_1_prob else 0\n", + " \n", + " red_rp_2_prob = get_rp_pred(red_rp_2_epa)\n", + " red_rp_2 = 1 if random.random() < red_rp_2_prob else 0\n", + " \n", + " blue_rp_1_prob = get_rp_pred(0.9 * blue_rp_1_epa)\n", + " blue_rp_1 = 1 if random.random() < blue_rp_1_prob else 0\n", + " \n", + " blue_rp_2_prob = get_rp_pred(blue_rp_2_epa)\n", + " blue_rp_2 = 1 if random.random() < blue_rp_2_prob else 0\n", + "\n", + " red_rps = red_rp_1 + red_rp_2 + (2 if red_win else 0)\n", + " blue_rps = blue_rp_1 + blue_rp_2 + (0 if red_win else 2)\n", + " \n", + " for x in m[\"red\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += red_rps\n", + " \n", + " for x in m[\"blue\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += blue_rps\n", + " \n", + " curr_sim_ranks = sorted(curr_sim_rps.items(), key=lambda x: [-x[1], random.random()])\n", + " \n", + " return [x[0] for x in curr_sim_ranks]\n", + "\n", + "def softmax_select(options, mult=1):\n", + " exp = [np.e ** (mult * o) for o in options]\n", + " sum_exp = sum(exp)\n", + " exp = [e / sum_exp for e in exp]\n", + " rand = random.random()\n", + " curr, i = 0, 0\n", + " while curr < rand:\n", + " curr += exp[i]\n", + " i += 1\n", + " return i - 1\n", + "\n", + "def sim_alliance_selection(ranks, team_to_epa):\n", + " alliances = [[], [], [], [], [], [], [], []]\n", + " locked_teams = []\n", + " remaining_teams = [(r, team_to_epa[r]) for r in ranks]\n", + " \n", + " r1_mult = 1 / 3\n", + " r2_mult = 1 / 2\n", + " \n", + " def handle_selection(selector, reject=True):\n", + " selected = None\n", + " while selected is None:\n", + " temp_remaining_teams = [r for r in remaining_teams if r not in locked_teams]\n", + " _selected = softmax_select([r[1] for r in temp_remaining_teams], r1_mult)\n", + " _selected_team = temp_remaining_teams[_selected]\n", + " orig_rank = ranks.index(_selected_team[0]) + 1\n", + " if not reject or orig_rank > 8:\n", + " selected = _selected\n", + " continue\n", + " \n", + " selected_rank = remaining_teams.index(_selected_team) + 1\n", + " remaining_best_epas = sorted(temp_remaining_teams[_selected + 1:], key=lambda x: -x[1])\n", + " if remaining_best_epas[selected_rank][1] > selector[1] + 5:\n", + " locked_teams.append(_selected_team)\n", + " else:\n", + " selected = _selected\n", + " \n", + " return remaining_teams.index(temp_remaining_teams[selected])\n", + " \n", + " # Captain and Round 1\n", + " alliances[0].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[1].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[2].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[3].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + "\n", + " alliances[4].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[5].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[6].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[7].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 2\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 3\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " aepas = [sum(a[1] for a in alliance[:3]) for alliance in alliances]\n", + " return [[a[0] for a in alliance] for alliance in alliances], aepas\n", + "\n", + "def sim_single_elims(alliances, team_to_epa):\n", + " scores, grids = [], []\n", + " \n", + " aepas = [sum(team_to_epa[a] for a in alliance[:3]) for alliance in alliances]\n", + " ms = [[0, 7], [3, 4], [1, 6], [2, 5], [], [], [], [], [], [], [], [], []]\n", + " \n", + " def _get_win_prob(i):\n", + " return get_win_prob(aepas[ms[i][0]], aepas[ms[i][1]])\n", + "\n", + " m1_red_winner = random.random() < _get_win_prob(0)\n", + " ms[4].append(ms[0][1] if m1_red_winner else ms[0][0])\n", + " ms[6].append(ms[0][0] if m1_red_winner else ms[0][1])\n", + " \n", + " m2_red_winner = random.random() < _get_win_prob(1)\n", + " ms[4].append(ms[1][1] if m2_red_winner else ms[1][0])\n", + " ms[6].append(ms[1][0] if m2_red_winner else ms[1][1])\n", + " \n", + " m3_red_winner = random.random() < _get_win_prob(2)\n", + " ms[5].append(ms[2][1] if m3_red_winner else ms[2][0])\n", + " ms[7].append(ms[2][0] if m3_red_winner else ms[2][1])\n", + " \n", + " m4_red_winner = random.random() < _get_win_prob(3)\n", + " ms[5].append(ms[3][1] if m4_red_winner else ms[3][0])\n", + " ms[7].append(ms[3][0] if m4_red_winner else ms[3][1])\n", + " \n", + " m5_red_winner = random.random() < _get_win_prob(4)\n", + " ms[9].append(ms[4][0] if m5_red_winner else ms[4][1])\n", + " \n", + " m6_red_winner = random.random() < _get_win_prob(5)\n", + " ms[8].append(ms[5][0] if m6_red_winner else ms[5][1])\n", + " \n", + " m7_red_winner = random.random() < _get_win_prob(6)\n", + " ms[8].append(ms[6][1] if m7_red_winner else ms[6][0])\n", + " ms[10].append(ms[6][0] if m7_red_winner else ms[6][1])\n", + " \n", + " m8_red_winner = random.random() < _get_win_prob(7)\n", + " ms[9].append(ms[7][1] if m8_red_winner else ms[7][0])\n", + " ms[10].append(ms[7][0] if m8_red_winner else ms[7][1])\n", + " \n", + " m9_red_winner = random.random() < _get_win_prob(8)\n", + " ms[11].append(ms[8][0] if m9_red_winner else ms[8][1])\n", + " \n", + " m10_red_winner = random.random() < _get_win_prob(9)\n", + " ms[11].append(ms[9][0] if m10_red_winner else ms[9][1])\n", + " \n", + " m11_red_winner = random.random() < _get_win_prob(10)\n", + " ms[12].append(ms[10][1] if m11_red_winner else ms[10][0])\n", + " finalist_1 = ms[10][0] if m11_red_winner else ms[10][1]\n", + " \n", + " m12_red_winner = random.random() < _get_win_prob(11)\n", + " fourth_place = ms[11][1] if m12_red_winner else ms[11][0]\n", + " ms[12].append(ms[11][0] if m12_red_winner else ms[11][1])\n", + " \n", + " m13_red_winner = random.random() < _get_win_prob(12)\n", + " third_place = ms[12][1] if m13_red_winner else ms[12][0]\n", + " finalist_2 = ms[12][0] if m13_red_winner else ms[12][1]\n", + " \n", + " \n", + " f1_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f2_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f3_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " winner = finalist_1 if f1_red_winner + f2_red_winner + f3_red_winner >= 2 else finalist_2\n", + " second_place = finalist_2 if winner == finalist_1 else finalist_1\n", + " \n", + " return winner, second_place, third_place, fourth_place\n" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "62276690", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Options: Pre Divisions, Pre Schedules, Final\n", + "def run_simulation(status=\"Pre Divisions\", num_sims=1000):\n", + " overall_winner_count = defaultdict(int)\n", + " overall_finalist_count = defaultdict(int)\n", + " overall_third_place_count = defaultdict(int)\n", + " overall_fourth_place_count = defaultdict(int)\n", + "\n", + " winner_count = defaultdict(int)\n", + " finalist_count = defaultdict(int)\n", + " third_place_count = defaultdict(int)\n", + " fourth_place_count = defaultdict(int)\n", + "\n", + " winner_alliances = defaultdict(int)\n", + " winner_best_epas = []\n", + " alliance_epas = []\n", + " best_epas = []\n", + " winner_epas = []\n", + "\n", + " einstein_winner_best_epas = []\n", + " einstein_alliance_epas = []\n", + " einstein_best_epas = []\n", + " einstein_winner_epas = []\n", + "\n", + " einstein_winner = defaultdict(int)\n", + " einstein_finalist = defaultdict(int)\n", + " einstein_third = defaultdict(int)\n", + " einstein_fourth = defaultdict(int)\n", + "\n", + " einstein_pairs = defaultdict(int)\n", + " winning_pairs = defaultdict(int)\n", + " pairs = defaultdict(int)\n", + "\n", + " qual_rank_list = defaultdict(lambda: [0] * 78)\n", + "\n", + " for sim in range(num_sims):\n", + " if sim % 100 == 0:\n", + " print(sim)\n", + "\n", + " noise = 4.5\n", + " curr_team_to_epa = {k : v + np.random.normal(0, noise) for k, v in team_to_epa.items()}\n", + "\n", + " rp_noise = 0.1\n", + " curr_team_to_rp_1_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_1_epa.items()}\n", + " curr_team_to_rp_2_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_2_epa.items()}\n", + "\n", + " einstein_alliances = []\n", + " einstein_aepas = []\n", + " \n", + " if status == \"Pre Divisions\":\n", + " random.shuffle(champ_team_nums)\n", + " division_1 = champ_team_nums[:78]\n", + " division_2 = champ_team_nums[78:156]\n", + " division_3 = champ_team_nums[156:233]\n", + " division_4 = champ_team_nums[233:310]\n", + " division_5 = champ_team_nums[310:388]\n", + " division_6 = champ_team_nums[388:466]\n", + " division_7 = champ_team_nums[466:543]\n", + " division_8 = champ_team_nums[543:620]\n", + " curr_divisions = [division_1, division_2, division_3, division_4, division_5, division_6, division_7, division_8]\n", + " else:\n", + " curr_divisions = divisions\n", + " \n", + " for division in curr_divisions:\n", + " random.shuffle(division)\n", + " schedule = get_schedule(len(division), 10)\n", + " schedule = [\n", + " {\n", + " \"red\": [division[x - 1] for x in m[\"red\"]],\n", + " \"blue\": [division[x - 1] for x in m[\"blue\"]],\n", + " }\n", + " for m in schedule\n", + " ]\n", + " qual_ranks = sim_single_quals(division, schedule, curr_team_to_epa, curr_team_to_rp_1_epa, curr_team_to_rp_2_epa)\n", + " for i, t in enumerate(qual_ranks):\n", + " qual_rank_list[t][i] += 1\n", + "\n", + " alliances, aepas = sim_alliance_selection(qual_ranks, curr_team_to_epa)\n", + " for alliance in alliances:\n", + " pairs[frozenset((alliance[0], alliance[1]))] += 1\n", + " \n", + " winner, finalist, third_place, fourth_place = sim_single_elims(alliances, curr_team_to_epa)\n", + " einstein_alliances.append(alliances[winner])\n", + " einstein_aepas.append(aepas[winner])\n", + "\n", + " einstein_pairs[frozenset((alliances[winner][0], alliances[winner][1]))] += 1\n", + "\n", + " winner_alliances[winner] += 1\n", + " best_epa = max(aepas)\n", + " winner_epa = aepas[winner]\n", + " winner_best_epas.append(best_epa == winner_epa)\n", + " alliance_epas.extend(aepas)\n", + " best_epas.append(best_epa)\n", + " winner_epas.append(winner_epa)\n", + "\n", + " for t in alliances[winner]:\n", + " winner_count[t] += 1\n", + "\n", + " for t in alliances[finalist]:\n", + " finalist_count[t] += 1\n", + "\n", + " for t in alliances[third_place]:\n", + " third_place_count[t] += 1\n", + "\n", + " for t in alliances[fourth_place]:\n", + " fourth_place_count[t] += 1\n", + "\n", + " winner, finalist, third_place, fourth_place = sim_single_elims(einstein_alliances, curr_team_to_epa)\n", + " einstein_winner[winner] += 1\n", + " einstein_finalist[finalist] += 1\n", + " einstein_third[third_place] += 1\n", + " einstein_fourth[fourth_place] += 1\n", + "\n", + " winning_pairs[frozenset((einstein_alliances[winner][0], einstein_alliances[winner][1]))] += 1\n", + "\n", + " einstein_best_epa = max(einstein_aepas)\n", + " einstein_winner_epa = einstein_aepas[winner]\n", + " einstein_winner_best_epas.append(einstein_best_epa == einstein_winner_epa)\n", + " einstein_alliance_epas.extend(einstein_aepas)\n", + " einstein_best_epas.append(einstein_best_epa)\n", + " einstein_winner_epas.append(einstein_winner_epa)\n", + "\n", + " for t in einstein_alliances[winner]:\n", + " overall_winner_count[t] += 1\n", + "\n", + " for t in einstein_alliances[finalist]:\n", + " overall_finalist_count[t] += 1\n", + "\n", + " for t in einstein_alliances[third_place]:\n", + " overall_third_place_count[t] += 1\n", + "\n", + " for t in einstein_alliances[fourth_place]:\n", + " overall_fourth_place_count[t] += 1\n", + " \n", + " avg_ranks = {t: sum(((i + 1) * qual_rank_list[t][i]) for i in range(78)) / num_sims for t in qual_rank_list}\n", + " top_1 = {t: sum(qual_rank_list[t][i] for i in range(1)) / num_sims for t in qual_rank_list}\n", + " top_4 = {t: sum(qual_rank_list[t][i] for i in range(4)) / num_sims for t in qual_rank_list}\n", + " top_8 = {t: sum(qual_rank_list[t][i] for i in range(8)) / num_sims for t in qual_rank_list}\n", + " top_16 = {t: sum(qual_rank_list[t][i] for i in range(16)) / num_sims for t in qual_rank_list}\n", + " \n", + " return {\n", + " \"overall_winner_count\": overall_winner_count,\n", + " \"overall_finalist_count\": overall_finalist_count,\n", + " \"overall_third_place_count\": overall_third_place_count,\n", + " \"overall_fourth_place_count\": overall_fourth_place_count,\n", + " \"winner_count\": winner_count,\n", + " \"finalist_count\": finalist_count,\n", + " \"third_place_count\": third_place_count,\n", + " \"fourth_place_count\": fourth_place_count,\n", + " \"winner_alliances\": winner_alliances,\n", + " \"winner_best_epas\": winner_best_epas,\n", + " \"alliance_epas\": alliance_epas,\n", + " \"best_epas\": best_epas,\n", + " \"winner_epas\": winner_epas,\n", + " \"einstein_winner_best_epas\": einstein_winner_best_epas,\n", + " \"einstein_alliance_epas\": einstein_alliance_epas,\n", + " \"einstein_best_epas\": einstein_best_epas,\n", + " \"einstein_winner_epas\": einstein_winner_epas,\n", + " \"einstein_winner\": einstein_winner,\n", + " \"einstein_finalist\": einstein_finalist,\n", + " \"einstein_third\": einstein_third,\n", + " \"einstein_fourth\": einstein_fourth,\n", + " \"pairs\": pairs,\n", + " \"einstein_pairs\": einstein_pairs,\n", + " \"winning_pairs\": winning_pairs,\n", + " \"qual_rank_list\": qual_rank_list,\n", + " \"avg_ranks\": avg_ranks,\n", + " \"top_1\": top_1,\n", + " \"top_4\": top_4,\n", + " \"top_8\": top_8,\n", + " \"top_16\": top_16,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "01332858", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n" + ] + } + ], + "source": [ + "before = run_simulation(\"Pre Divisions\", 100000)\n", + "after = run_simulation(\"Pre Schedule\", 100000)" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "991e8ce8", + "metadata": {}, + "outputs": [], + "source": [ + "num_sims = 100000" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "1d053d42", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "

Chance of winning Einstein

\n", + "\n", + "| Division | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| --- | :-: | :-: |\n", + "| Archimedes|13.04%|50.11%|\n", + "| Curie|12.69%|4.06%|\n", + "| Daly|12.64%|2.65%|\n", + "| Galileo|12.66%|12.79%|\n", + "| Hopper|12.96%|12.46%|\n", + "| Johnson|13.05%|5.85%|\n", + "| Milstein|12.68%|8.31%|\n", + "| Newton|10.29%|3.78%|\n", + "\n", + "\n", + "

Chance of Ranking High

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Mean Rank | Pre-Schedule Mean Rank |\n", + "| --- | --- | --- | :-: | :-: |\n", + "| 1|1323|Hopper|5.98|5.34 |\n", + "| 2|2056|Archimedes|5.64|6.76 |\n", + "| 3|254|Archimedes|6.38|7.78 |\n", + "| 4|3538|Newton|10.17|8.03 |\n", + "| 5|1678|Galileo|8.0|8.08 |\n", + "| 6|195|Newton|12.22|9.62 |\n", + "| 7|971|Johnson|11.39|10.17 |\n", + "| 8|1987|Hopper|11.84|10.36 |\n", + "| 9|5940|Curie|12.08|10.77 |\n", + "| 10|4414|Hopper|12.84|11.26 |\n", + "| 11|3005|Galileo|11.62|11.97 |\n", + "| 12|7157|Johnson|13.52|12.33 |\n", + "| 13|4522|Newton|15.14|12.48 |\n", + "| 14|930|Milstein|11.51|12.54 |\n", + "| 15|2338|Hopper|13.96|12.61 |\n", + "| 16|176|Milstein|11.88|13.05 |\n", + "| 17|2767|Daly|13.83|13.27 |\n", + "| 18|3467|Galileo|13.16|13.54 |\n", + "| 19|6036|Archimedes|11.64|13.74 |\n", + "| 20|111|Archimedes|11.77|13.76 |\n", + "| 21|2910|Galileo|13.41|14.12 |\n", + "| 22|3175|Johnson|15.0|14.12 |\n", + "| 23|3357|Hopper|16.21|14.21 |\n", + "| 24|6672|Milstein|13.51|14.46 |\n", + "| 25|359|Johnson|15.71|14.62 |\n", + "\n", + "\n", + "See Statbotics event pages for individual event simulations\n", + "\n", + "

Chance of winning division

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2056|Archimedes|64.53%|58.53%|\n", + "| 2|1323|Hopper|55.55%|56.33%|\n", + "| 3|254|Archimedes|54.53%|47.23%|\n", + "| 4|1678|Galileo|38.73%|38.52%|\n", + "| 5|3005|Galileo|35.2%|35.92%|\n", + "| 6|3538|Newton|28.78%|35.49%|\n", + "| 7|971|Johnson|29.26%|34.46%|\n", + "| 8|5940|Curie|27.79%|34.41%|\n", + "| 9|7157|Johnson|22.08%|26.83%|\n", + "| 10|195|Newton|19.69%|25.34%|\n", + "| 11|930|Milstein|23.17%|22.22%|\n", + "| 12|6672|Milstein|22.6%|21.75%|\n", + "| 13|1987|Hopper|20.1%|20.99%|\n", + "| 14|2767|Daly|15.32%|19.54%|\n", + "| 15|7890|Curie|14.72%|18.29%|\n", + "| 16|4499|Johnson|15.53%|17.9%|\n", + "| 17|359|Johnson|15.28%|17.89%|\n", + "| 18|4907|Daly|13.91%|17.84%|\n", + "| 19|2338|Hopper|17.78%|17.62%|\n", + "| 20|3683|Milstein|17.98%|17.58%|\n", + "| 21|176|Milstein|18.41%|17.28%|\n", + "| 22|1756|Curie|14.01%|17.27%|\n", + "| 23|111|Archimedes|29.31%|17.13%|\n", + "| 24|4414|Hopper|17.02%|16.93%|\n", + "| 25|2910|Galileo|18.47%|16.76%|\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2056|Archimedes|64.53%|58.53%|\n", + "| 2|254|Archimedes|54.53%|47.23%|\n", + "| 3|111|Archimedes|29.31%|17.13%|\n", + "| 4|6036|Archimedes|27.67%|15.49%|\n", + "| 5|1619|Archimedes|19.86%|9.95%|\n", + "| 6|27|Archimedes|10.47%|9.15%|\n", + "| 7|6002|Archimedes|10.32%|9.11%|\n", + "| 8|70|Archimedes|9.37%|9.08%|\n", + "| 9|862|Archimedes|9.84%|9.01%|\n", + "| 10|33|Archimedes|10.72%|9.0%|\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|5940|Curie|27.79%|34.41%|\n", + "| 2|7890|Curie|14.72%|18.29%|\n", + "| 3|1756|Curie|14.01%|17.27%|\n", + "| 4|6329|Curie|13.26%|16.48%|\n", + "| 5|148|Curie|13.01%|16.08%|\n", + "| 6|3310|Curie|11.74%|13.9%|\n", + "| 7|2451|Curie|11.42%|12.98%|\n", + "| 8|4270|Curie|11.19%|12.89%|\n", + "| 9|7021|Curie|10.84%|12.39%|\n", + "| 10|4253|Curie|10.78%|12.07%|\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2767|Daly|15.32%|19.54%|\n", + "| 2|4907|Daly|13.91%|17.84%|\n", + "| 3|2363|Daly|12.89%|16.57%|\n", + "| 4|1325|Daly|12.29%|15.31%|\n", + "| 5|230|Daly|11.92%|14.79%|\n", + "| 6|870|Daly|11.79%|14.45%|\n", + "| 7|4613|Daly|11.78%|14.36%|\n", + "| 8|3314|Daly|11.37%|13.8%|\n", + "| 9|7769|Daly|11.2%|13.68%|\n", + "| 10|695|Daly|11.03%|13.12%|\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|1678|Galileo|38.73%|38.52%|\n", + "| 2|3005|Galileo|35.2%|35.92%|\n", + "| 3|2910|Galileo|18.47%|16.76%|\n", + "| 4|3467|Galileo|17.83%|15.83%|\n", + "| 5|1591|Galileo|16.39%|14.65%|\n", + "| 6|4381|Galileo|13.11%|11.72%|\n", + "| 7|2337|Galileo|13.03%|11.55%|\n", + "| 8|461|Galileo|12.45%|11.21%|\n", + "| 9|3476|Galileo|11.37%|10.61%|\n", + "| 10|4415|Galileo|10.66%|10.29%|\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|1323|Hopper|55.55%|56.33%|\n", + "| 2|1987|Hopper|20.1%|20.99%|\n", + "| 3|2338|Hopper|17.78%|17.62%|\n", + "| 4|4414|Hopper|17.02%|16.93%|\n", + "| 5|1706|Hopper|15.07%|14.04%|\n", + "| 6|1727|Hopper|13.54%|11.88%|\n", + "| 7|4336|Hopper|8.98%|10.47%|\n", + "| 8|1807|Hopper|8.21%|10.45%|\n", + "| 9|876|Hopper|9.21%|10.24%|\n", + "| 10|3357|Hopper|11.93%|10.14%|\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|971|Johnson|29.26%|34.46%|\n", + "| 2|7157|Johnson|22.08%|26.83%|\n", + "| 3|4499|Johnson|15.53%|17.9%|\n", + "| 4|359|Johnson|15.28%|17.89%|\n", + "| 5|2075|Johnson|12.36%|13.55%|\n", + "| 6|3175|Johnson|12.26%|13.49%|\n", + "| 7|1718|Johnson|12.1%|12.89%|\n", + "| 8|51|Johnson|11.82%|12.49%|\n", + "| 9|1391|Johnson|10.93%|11.45%|\n", + "| 10|973|Johnson|10.87%|11.37%|\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|930|Milstein|23.17%|22.22%|\n", + "| 2|6672|Milstein|22.6%|21.75%|\n", + "| 3|3683|Milstein|17.98%|17.58%|\n", + "| 4|176|Milstein|18.41%|17.28%|\n", + "| 5|2539|Milstein|16.02%|15.77%|\n", + "| 6|987|Milstein|14.52%|14.54%|\n", + "| 7|6090|Milstein|14.61%|14.34%|\n", + "| 8|5913|Milstein|14.0%|14.0%|\n", + "| 9|604|Milstein|13.38%|13.18%|\n", + "| 10|694|Milstein|13.12%|13.13%|\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|3538|Newton|28.78%|35.49%|\n", + "| 2|195|Newton|19.69%|25.34%|\n", + "| 3|1538|Newton|13.6%|16.63%|\n", + "| 4|4522|Newton|13.22%|16.07%|\n", + "| 5|1757|Newton|12.69%|14.74%|\n", + "| 6|3184|Newton|11.98%|13.89%|\n", + "| 7|857|Newton|11.4%|12.89%|\n", + "| 8|494|Newton|10.7%|11.91%|\n", + "| 9|4143|Newton|10.6%|11.73%|\n", + "| 10|7285|Newton|10.51%|11.51%|\n", + "\n", + "[/details]\n", + "\n", + "

Chance of winning Einstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2056|Archimedes|28.6%|37.46% |\n", + "| 2|254|Archimedes|19.01%|29.77% |\n", + "| 3|1323|Hopper|19.52%|10.99% |\n", + "| 4|111|Archimedes|5.45%|7.92% |\n", + "| 5|1678|Galileo|8.97%|7.75% |\n", + "| 6|3005|Galileo|7.73%|7.18% |\n", + "| 7|6036|Archimedes|4.65%|6.82% |\n", + "| 8|70|Archimedes|1.03%|4.5% |\n", + "| 9|7211|Archimedes|1.01%|4.33% |\n", + "| 10|5232|Archimedes|0.98%|4.33% |\n", + "| 11|6002|Archimedes|1.08%|4.31% |\n", + "| 12|4476|Archimedes|0.99%|4.27% |\n", + "| 13|862|Archimedes|1.06%|4.26% |\n", + "| 14|624|Archimedes|1.06%|4.2% |\n", + "| 15|1189|Archimedes|0.99%|4.18% |\n", + "| 16|33|Archimedes|1.09%|4.18% |\n", + "| 17|4362|Archimedes|0.95%|4.13% |\n", + "| 18|27|Archimedes|1.04%|4.12% |\n", + "| 19|972|Archimedes|0.91%|3.96% |\n", + "| 20|4373|Archimedes|0.91%|3.94% |\n", + "| 21|4903|Archimedes|0.97%|3.94% |\n", + "| 22|1768|Archimedes|0.93%|3.91% |\n", + "| 23|1619|Archimedes|2.39%|3.79% |\n", + "| 24|1574|Archimedes|0.92%|3.64% |\n", + "| 25|3663|Archimedes|1.07%|3.63% |\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2056|Archimedes|28.6%|37.46% |\n", + "| 2|254|Archimedes|19.01%|29.77% |\n", + "| 3|111|Archimedes|5.45%|7.92% |\n", + "| 4|6036|Archimedes|4.65%|6.82% |\n", + "| 5|70|Archimedes|1.03%|4.5% |\n", + "| 6|7211|Archimedes|1.01%|4.33% |\n", + "| 7|5232|Archimedes|0.98%|4.33% |\n", + "| 8|6002|Archimedes|1.08%|4.31% |\n", + "| 9|4476|Archimedes|0.99%|4.27% |\n", + "| 10|862|Archimedes|1.06%|4.26% |\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|5940|Curie|4.9%|2.63% |\n", + "| 2|7890|Curie|1.44%|0.91% |\n", + "| 3|1756|Curie|1.32%|0.8% |\n", + "| 4|6329|Curie|1.17%|0.78% |\n", + "| 5|148|Curie|1.19%|0.69% |\n", + "| 6|3310|Curie|1.04%|0.49% |\n", + "| 7|2451|Curie|1.03%|0.48% |\n", + "| 8|4270|Curie|1.07%|0.47% |\n", + "| 9|4253|Curie|1.06%|0.43% |\n", + "| 10|7021|Curie|1.02%|0.42% |\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|2767|Daly|1.5%|0.74% |\n", + "| 2|4907|Daly|1.27%|0.64% |\n", + "| 3|2363|Daly|1.18%|0.54% |\n", + "| 4|1325|Daly|1.12%|0.47% |\n", + "| 5|870|Daly|1.1%|0.44% |\n", + "| 6|4613|Daly|1.11%|0.41% |\n", + "| 7|230|Daly|1.08%|0.41% |\n", + "| 8|6424|Daly|1.06%|0.37% |\n", + "| 9|7769|Daly|1.03%|0.36% |\n", + "| 10|695|Daly|1.04%|0.36% |\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|1678|Galileo|8.97%|7.75% |\n", + "| 2|3005|Galileo|7.73%|7.18% |\n", + "| 3|2910|Galileo|2.21%|2.03% |\n", + "| 4|3467|Galileo|2.02%|1.9% |\n", + "| 5|1591|Galileo|1.77%|1.7% |\n", + "| 6|4381|Galileo|1.19%|1.19% |\n", + "| 7|5987|Galileo|1.09%|1.13% |\n", + "| 8|5199|Galileo|1.1%|1.12% |\n", + "| 9|3476|Galileo|1.04%|1.12% |\n", + "| 10|461|Galileo|1.17%|1.11% |\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|1323|Hopper|19.52%|10.99% |\n", + "| 2|1987|Hopper|2.51%|3.04% |\n", + "| 3|2338|Hopper|2.05%|2.33% |\n", + "| 4|4414|Hopper|1.87%|2.1% |\n", + "| 5|1706|Hopper|1.46%|1.51% |\n", + "| 6|1807|Hopper|0.9%|1.29% |\n", + "| 7|4336|Hopper|1.01%|1.27% |\n", + "| 8|4265|Hopper|0.75%|1.24% |\n", + "| 9|876|Hopper|0.99%|1.2% |\n", + "| 10|1727|Hopper|1.27%|1.19% |\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|971|Johnson|5.29%|3.44% |\n", + "| 2|7157|Johnson|3.13%|2.41% |\n", + "| 3|359|Johnson|1.6%|1.18% |\n", + "| 4|4499|Johnson|1.59%|1.17% |\n", + "| 5|2075|Johnson|1.08%|0.65% |\n", + "| 6|3175|Johnson|1.18%|0.65% |\n", + "| 7|1718|Johnson|1.06%|0.63% |\n", + "| 8|51|Johnson|1.09%|0.6% |\n", + "| 9|1391|Johnson|1.01%|0.54% |\n", + "| 10|422|Johnson|1.08%|0.53% |\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|930|Milstein|3.35%|2.54% |\n", + "| 2|6672|Milstein|3.32%|2.52% |\n", + "| 3|3683|Milstein|2.09%|1.7% |\n", + "| 4|176|Milstein|2.08%|1.65% |\n", + "| 5|2539|Milstein|1.64%|1.37% |\n", + "| 6|987|Milstein|1.47%|1.27% |\n", + "| 7|6090|Milstein|1.39%|1.15% |\n", + "| 8|5913|Milstein|1.29%|1.13% |\n", + "| 9|5895|Milstein|1.15%|1.04% |\n", + "| 10|694|Milstein|1.16%|1.04% |\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: |\n", + "| 1|3538|Newton|4.96%|2.43% |\n", + "| 2|195|Newton|2.43%|1.5% |\n", + "| 3|1538|Newton|1.26%|0.66% |\n", + "| 4|4522|Newton|1.25%|0.56% |\n", + "| 5|1757|Newton|1.15%|0.53% |\n", + "| 6|3184|Newton|1.1%|0.46% |\n", + "| 7|857|Newton|1.06%|0.43% |\n", + "| 8|1468|Newton|1.02%|0.38% |\n", + "| 9|2992|Newton|1.0%|0.38% |\n", + "| 10|494|Newton|1.0%|0.36% |\n", + "\n", + "[/details]\n", + "\n", + "

Most likely paiarings

\n", + "\n", + "| Rank | Division        | Team 1          | Team 2          | On Alliance     | Win Division    | Win Einstein    |\n", + "| --- | --- | --- | --- | :-: | :-: | :-: |\n", + "| 1|Archimedes|2056|254|33.49%|27.79%|21.16%\n", + "| 2|Archimedes|2056|111|9.95%|6.47%|4.06%\n", + "| 3|Galileo|1678|3005|20.11%|13.36%|3.99%\n", + "| 4|Archimedes|2056|6036|9.25%|5.72%|3.49%\n", + "| 5|Hopper|1323|1987|16.46%|10.82%|2.5%\n", + "| 6|Archimedes|254|111|7.82%|3.76%|2.12%\n", + "| 7|Hopper|1323|2338|12.71%|8.14%|1.9%\n", + "| 8|Archimedes|254|6036|7.27%|3.37%|1.78%\n", + "| 9|Archimedes|2056|1619|5.86%|3.09%|1.69%\n", + "| 10|Hopper|1323|4414|12.64%|7.87%|1.68%\n", + "| 11|Archimedes|2056|1577|5.04%|2.51%|1.29%\n", + "| 12|Archimedes|2056|4028|4.67%|2.38%|1.29%\n", + "| 13|Johnson|971|7157|13.86%|7.91%|1.21%\n", + "| 14|Hopper|1323|1706|9.09%|5.57%|1.11%\n", + "| 15|Archimedes|2056|2468|4.13%|1.92%|0.91%\n", + "| 16|Newton|3538|195|16.37%|8.62%|0.91%\n", + "| 17|Archimedes|254|1619|5.08%|1.86%|0.91%\n", + "| 18|Hopper|1323|1727|7.03%|4.1%|0.81%\n", + "| 19|Galileo|1678|2910|8.74%|4.01%|0.75%\n", + "| 20|Archimedes|2056|2687|3.34%|1.51%|0.74%\n", + "| 21|Archimedes|254|1577|4.63%|1.6%|0.69%\n", + "| 22|Archimedes|254|4028|4.35%|1.53%|0.68%\n", + "| 23|Galileo|1678|3467|8.25%|3.6%|0.64%\n", + "| 24|Galileo|3005|2910|7.44%|3.26%|0.61%\n", + "| 25|Galileo|1678|1591|6.98%|3.07%|0.6%\n" + ] + } + ], + "source": [ + "def pad(s, length = 15):\n", + " return s + \" \" * (length - len(s))\n", + "\n", + "def percent(x):\n", + " return str(round(100 * x, 2)) + \"%\"\n", + "\n", + "division_names = [\"Archimedes\", \"Curie\", \"Daly\", \"Galileo\", \"Hopper\", \"Johnson\", \"Milstein\", \"Newton\"]\n", + "division_to_team = {}\n", + "for i, division in enumerate(divisions):\n", + " for t in division:\n", + " division_to_team[t] = division_names[i]\n", + "\n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print(\"| Division | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" |\")\n", + "print(\"| --- | :-: | :-: |\")\n", + "for i in range(8):\n", + " print(\"|\", \"|\".join([division_names[i], percent(before[\"einstein_winner\"][i] / num_sims), percent(after[\"einstein_winner\"][i] / num_sims)]) + \"|\")\n", + "print()\n", + "print()\n", + "\n", + "def print_ranks(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Mean Rank\"), \" | \", pad(\"Pre-Schedule Mean Rank\"), \" |\")\n", + " print(\"| --- | --- | --- | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(after[\"avg_ranks\"].items(), key=lambda x: (filter(x[0]), x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], str(round(before[\"avg_ranks\"][key], 2)), str(round(after[\"avg_ranks\"][key], 2))]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of Ranking High

\")\n", + "print()\n", + " \n", + "print_ranks()\n", + "\n", + "print()\n", + "print(\"See Statbotics event pages for individual event simulations\")\n", + "print()\n", + "\n", + "\n", + "def print_divisions(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(after[\"winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"winner_count\"][key] / num_sims), percent(after[\"winner_count\"][key] / num_sims)]) + \"|\")\n", + " print()\n", + "\n", + "print(\"

Chance of winning division

\")\n", + "print()\n", + " \n", + "print_divisions()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_divisions(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "def print_einstein(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(after[\"overall_winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"overall_winner_count\"][key] / num_sims), percent(after[\"overall_winner_count\"][key] / num_sims)]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print_einstein()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_einstein(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "print(\"

Most likely pairings

\")\n", + "print()\n", + "\n", + "print(\"| Rank | \", pad(\"Division\"), \"|\", pad(\"Team 1\"), \"|\", pad(\"Team 2\"), \"|\", pad(\"On Alliance\"), \"|\", pad(\"Win Division\"), \"|\", pad(\"Win Einstein\"), \"|\")\n", + "print(\"| --- | --- | --- | --- | :-: | :-: | :-: |\")\n", + "for i, (key, _) in enumerate(sorted(after[\"winning_pairs\"].items(), key=lambda x: -x[1])[:25]):\n", + " key_list = sorted(list(key), key=lambda x: -team_to_epa[x])\n", + " print(\"|\", \"|\".join([str(i + 1), division_to_team[key_list[0]], str(key_list[0]), str(key_list[1]), percent(after[\"pairs\"][key] / num_sims), percent(after[\"einstein_pairs\"][key] / num_sims), percent(after[\"winning_pairs\"][key] / num_sims)]))\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77b67391", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/scripts/2023/Simulate Champs V4.ipynb b/scripts/2023/Simulate Champs V4.ipynb new file mode 100644 index 00000000..eed323cf --- /dev/null +++ b/scripts/2023/Simulate Champs V4.ipynb @@ -0,0 +1,4185 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b698f107", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "from functools import lru_cache\n", + "import random\n", + "import requests\n", + "from requests import Session\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import statbotics\n", + "\n", + "%matplotlib notebook\n", + "\n", + "sb = statbotics.Statbotics()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4568bf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3286" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_teams = sb.get_team_years(year=2023, limit=10000)\n", + "all_teams_dict = {t[\"team\"]: t for t in all_teams}\n", + "len(all_teams)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "4a08ee65", + "metadata": {}, + "outputs": [], + "source": [ + "AUTH_KEY = \"XeUIxlvO4CPc44NlLE3ncevDg7bAhp6CRy6zC9M2aQb2zGfys0M30eKwavFJSEJr\"\n", + "\n", + "read_prefix = \"https://www.thebluealliance.com/api/v3/\"\n", + "\n", + "session = Session()\n", + "session.headers.update({\"X-TBA-Auth-Key\": AUTH_KEY, \"X-TBA-Auth-Id\": \"\"})\n", + "\n", + "def get_tba(url):\n", + " response = session.get(read_prefix + url)\n", + " return response.json()\n", + "\n", + "@lru_cache()\n", + "def get_event_teams(key):\n", + " data = get_tba(f\"event/{key}/teams\")\n", + " return [int(x[\"key\"][3:]) for x in data]\n", + "\n", + "@lru_cache()\n", + "def get_event_matches(key):\n", + " data = get_tba(f\"event/{key}/matches\")\n", + " return [{\"red\": [int(y[3:]) for y in x[\"alliances\"][\"red\"][\"team_keys\"]], \"blue\": [int(y[3:]) for y in x[\"alliances\"][\"blue\"][\"team_keys\"]]} for x in data]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "f8fa559f", + "metadata": {}, + "outputs": [], + "source": [ + "divisions = [\n", + " get_event_teams(\"2023arc\"),\n", + " get_event_teams(\"2023cur\"),\n", + " get_event_teams(\"2023dal\"),\n", + " get_event_teams(\"2023gal\"),\n", + " get_event_teams(\"2023hop\"),\n", + " get_event_teams(\"2023joh\"),\n", + " get_event_teams(\"2023mil\"),\n", + " get_event_teams(\"2023new\"),\n", + "]\n", + "\n", + "champ_team_nums = []\n", + "for division in divisions:\n", + " champ_team_nums.extend(division)\n", + "\n", + "division_matches = [\n", + " get_event_matches(\"2023arc\"),\n", + " get_event_matches(\"2023cur\"),\n", + " get_event_matches(\"2023dal\"),\n", + " get_event_matches(\"2023gal\"),\n", + " get_event_matches(\"2023hop\"),\n", + " get_event_matches(\"2023joh\"),\n", + " get_event_matches(\"2023mil\"),\n", + " get_event_matches(\"2023new\"),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "7ab3cd85", + "metadata": {}, + "outputs": [], + "source": [ + "epa_breakdown = pd.read_json(\"https://raw.githubusercontent.com/avgupta456/statbotics/master/data/2023/epa_breakdown.json\", orient=\"index\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "b4529072", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "84.85 0.9931 0.5175 12.2601407515\n", + "80.19 0.9545 0.6071 11.6093456675\n" + ] + } + ], + "source": [ + "team_to_epa = {t: all_teams_dict[t][\"epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_1_epa = {t: all_teams_dict[t][\"rp_1_epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_2_epa = {t: all_teams_dict[t][\"rp_2_epa_end\"] for t in champ_team_nums}\n", + "team_to_cycles = {t: epa_breakdown.loc[t][\"total_cycles\"] for t in champ_team_nums}\n", + "\n", + "print(team_to_epa[2056], team_to_rp_1_epa[2056], team_to_rp_2_epa[2056], team_to_cycles[2056])\n", + "print(team_to_epa[254], team_to_rp_1_epa[254], team_to_rp_2_epa[254], team_to_cycles[254])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "38d2a765", + "metadata": {}, + "outputs": [], + "source": [ + "TOTAL_MEAN = 74.57\n", + "TOTAL_SD = 29.36" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "811dfb7e", + "metadata": {}, + "outputs": [], + "source": [ + "@lru_cache\n", + "def make_request(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " data = response.text\n", + " lines = data.split(\"\\n\")\n", + " return lines\n", + "\n", + "@lru_cache\n", + "def get_schedule(num_teams: int, num_matches: int):\n", + " # TODO: remove this once we have pre-generated schedules for 100+ teams\n", + " if num_teams > 100:\n", + " schedule1 = get_schedule(100, num_matches)\n", + " schedule2 = get_schedule(num_teams - 100, num_matches)\n", + " schedule2 = [\n", + " {\"red\": [team + 100 for team in match[\"red\"]], \"blue\": [team + 100 for team in match[\"blue\"]]}\n", + " for match in schedule2\n", + " ]\n", + " return schedule1 + schedule2\n", + "\n", + " # load csv from external URL using requests\n", + " lines = make_request(f\"https://raw.githubusercontent.com/Team254/cheesy-arena/main/schedules/{num_teams}_{num_matches}.csv\")\n", + " \n", + " schedule = []\n", + " for line in lines:\n", + " match = line.split(\",\")\n", + " if len(match) < 12:\n", + " continue\n", + " red = [int(match[0]), int(match[2]), int(match[4])]\n", + " blue = [int(match[6]), int(match[8]), int(match[10])]\n", + " schedule.append({\"red\": red, \"blue\": blue})\n", + " \n", + " return schedule" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "c2233c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def get_win_prob(a, b):\n", + " return 1 / (1 + 10 ** (((-5 / 8) * (a - b)) / TOTAL_SD))\n", + "\n", + "def get_rp_pred(a):\n", + " return 1 / (1 + np.e ** (-4 * (a - 0.5)))\n", + "\n", + "def sim_single_quals(teams, schedule, team_to_epa, team_to_rp_1_epa, team_to_rp_2_epa):\n", + " curr_sim_matches = {t: 0 for t in teams}\n", + " curr_sim_rps = {t: 0 for t in teams}\n", + " for m in schedule:\n", + " red_epa = sum(team_to_epa[x] for x in m[\"red\"])\n", + " blue_epa = sum(team_to_epa[x] for x in m[\"blue\"])\n", + " red_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"red\"])\n", + " blue_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"blue\"])\n", + " red_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"red\"])\n", + " blue_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"blue\"])\n", + " \n", + " win_prob = get_win_prob(red_epa, blue_epa)\n", + " red_win = 1 if random.random() < win_prob else 0\n", + "\n", + " red_rp_1_prob = get_rp_pred(0.9 * red_rp_1_epa)\n", + " red_rp_1 = 1 if random.random() < red_rp_1_prob else 0\n", + " \n", + " red_rp_2_prob = get_rp_pred(red_rp_2_epa)\n", + " red_rp_2 = 1 if random.random() < red_rp_2_prob else 0\n", + " \n", + " blue_rp_1_prob = get_rp_pred(0.9 * blue_rp_1_epa)\n", + " blue_rp_1 = 1 if random.random() < blue_rp_1_prob else 0\n", + " \n", + " blue_rp_2_prob = get_rp_pred(blue_rp_2_epa)\n", + " blue_rp_2 = 1 if random.random() < blue_rp_2_prob else 0\n", + "\n", + " red_rps = red_rp_1 + red_rp_2 + (2 if red_win else 0)\n", + " blue_rps = blue_rp_1 + blue_rp_2 + (0 if red_win else 2)\n", + " \n", + " for x in m[\"red\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += red_rps\n", + " \n", + " for x in m[\"blue\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += blue_rps\n", + " \n", + " curr_sim_ranks = sorted(curr_sim_rps.items(), key=lambda x: [-x[1], random.random()])\n", + " \n", + " return [x[0] for x in curr_sim_ranks]\n", + "\n", + "def softmax_select(options, mult=1):\n", + " exp = [np.e ** (mult * o) for o in options]\n", + " sum_exp = sum(exp)\n", + " exp = [e / sum_exp for e in exp]\n", + " rand = random.random()\n", + " curr, i = 0, 0\n", + " while curr < rand:\n", + " curr += exp[i]\n", + " i += 1\n", + " return i - 1\n", + "\n", + "def sim_alliance_selection(ranks, team_to_epa):\n", + " alliances = [[], [], [], [], [], [], [], []]\n", + " locked_teams = []\n", + " remaining_teams = [(r, team_to_epa[r]) for r in ranks]\n", + " \n", + " r1_mult = 1 / 3\n", + " r2_mult = 1 / 2\n", + " \n", + " def handle_selection(selector, reject=True):\n", + " selected = None\n", + " while selected is None:\n", + " temp_remaining_teams = [r for r in remaining_teams if r not in locked_teams]\n", + " _selected = softmax_select([r[1] for r in temp_remaining_teams], r1_mult)\n", + " _selected_team = temp_remaining_teams[_selected]\n", + " orig_rank = ranks.index(_selected_team[0]) + 1\n", + " if not reject or orig_rank > 8:\n", + " selected = _selected\n", + " continue\n", + " \n", + " selected_rank = remaining_teams.index(_selected_team) + 1\n", + " remaining_best_epas = sorted(temp_remaining_teams[_selected + 1:], key=lambda x: -x[1])\n", + " if remaining_best_epas[selected_rank][1] > selector[1] + 5:\n", + " locked_teams.append(_selected_team)\n", + " else:\n", + " selected = _selected\n", + " \n", + " return remaining_teams.index(temp_remaining_teams[selected])\n", + " \n", + " # Captain and Round 1\n", + " alliances[0].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[1].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[2].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[3].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + "\n", + " alliances[4].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[5].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[6].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[7].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 2\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 3\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " aepas = [sum(a[1] for a in alliance[:3]) for alliance in alliances]\n", + " return [[a[0] for a in alliance] for alliance in alliances], aepas\n", + "\n", + "def sim_single_elims(alliances, team_to_epa):\n", + " scores, grids = [], []\n", + " \n", + " aepas = [sum(team_to_epa[a] for a in alliance[:3]) for alliance in alliances]\n", + " ms = [[0, 7], [3, 4], [1, 6], [2, 5], [], [], [], [], [], [], [], [], []]\n", + " \n", + " def _get_win_prob(i):\n", + " return get_win_prob(aepas[ms[i][0]], aepas[ms[i][1]])\n", + "\n", + " m1_red_winner = random.random() < _get_win_prob(0)\n", + " ms[4].append(ms[0][1] if m1_red_winner else ms[0][0])\n", + " ms[6].append(ms[0][0] if m1_red_winner else ms[0][1])\n", + " \n", + " m2_red_winner = random.random() < _get_win_prob(1)\n", + " ms[4].append(ms[1][1] if m2_red_winner else ms[1][0])\n", + " ms[6].append(ms[1][0] if m2_red_winner else ms[1][1])\n", + " \n", + " m3_red_winner = random.random() < _get_win_prob(2)\n", + " ms[5].append(ms[2][1] if m3_red_winner else ms[2][0])\n", + " ms[7].append(ms[2][0] if m3_red_winner else ms[2][1])\n", + " \n", + " m4_red_winner = random.random() < _get_win_prob(3)\n", + " ms[5].append(ms[3][1] if m4_red_winner else ms[3][0])\n", + " ms[7].append(ms[3][0] if m4_red_winner else ms[3][1])\n", + " \n", + " m5_red_winner = random.random() < _get_win_prob(4)\n", + " ms[9].append(ms[4][0] if m5_red_winner else ms[4][1])\n", + " \n", + " m6_red_winner = random.random() < _get_win_prob(5)\n", + " ms[8].append(ms[5][0] if m6_red_winner else ms[5][1])\n", + " \n", + " m7_red_winner = random.random() < _get_win_prob(6)\n", + " ms[8].append(ms[6][1] if m7_red_winner else ms[6][0])\n", + " ms[10].append(ms[6][0] if m7_red_winner else ms[6][1])\n", + " \n", + " m8_red_winner = random.random() < _get_win_prob(7)\n", + " ms[9].append(ms[7][1] if m8_red_winner else ms[7][0])\n", + " ms[10].append(ms[7][0] if m8_red_winner else ms[7][1])\n", + " \n", + " m9_red_winner = random.random() < _get_win_prob(8)\n", + " ms[11].append(ms[8][0] if m9_red_winner else ms[8][1])\n", + " \n", + " m10_red_winner = random.random() < _get_win_prob(9)\n", + " ms[11].append(ms[9][0] if m10_red_winner else ms[9][1])\n", + " \n", + " m11_red_winner = random.random() < _get_win_prob(10)\n", + " ms[12].append(ms[10][1] if m11_red_winner else ms[10][0])\n", + " finalist_1 = ms[10][0] if m11_red_winner else ms[10][1]\n", + " \n", + " m12_red_winner = random.random() < _get_win_prob(11)\n", + " fourth_place = ms[11][1] if m12_red_winner else ms[11][0]\n", + " ms[12].append(ms[11][0] if m12_red_winner else ms[11][1])\n", + " \n", + " m13_red_winner = random.random() < _get_win_prob(12)\n", + " third_place = ms[12][1] if m13_red_winner else ms[12][0]\n", + " finalist_2 = ms[12][0] if m13_red_winner else ms[12][1]\n", + " \n", + " \n", + " f1_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f2_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f3_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " winner = finalist_1 if f1_red_winner + f2_red_winner + f3_red_winner >= 2 else finalist_2\n", + " second_place = finalist_2 if winner == finalist_1 else finalist_1\n", + " \n", + " return winner, second_place, third_place, fourth_place\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "62276690", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Options: Pre Divisions, Pre Schedules, Final\n", + "def run_simulation(status=\"Pre Divisions\", num_sims=1000):\n", + " overall_winner_count = defaultdict(int)\n", + " overall_finalist_count = defaultdict(int)\n", + " overall_third_place_count = defaultdict(int)\n", + " overall_fourth_place_count = defaultdict(int)\n", + "\n", + " winner_count = defaultdict(int)\n", + " finalist_count = defaultdict(int)\n", + " third_place_count = defaultdict(int)\n", + " fourth_place_count = defaultdict(int)\n", + "\n", + " winner_alliances = defaultdict(int)\n", + " winner_best_epas = []\n", + " alliance_epas = []\n", + " best_epas = []\n", + " winner_epas = []\n", + "\n", + " einstein_winner_best_epas = []\n", + " einstein_alliance_epas = []\n", + " einstein_best_epas = []\n", + " einstein_winner_epas = []\n", + "\n", + " einstein_winner = defaultdict(int)\n", + " einstein_finalist = defaultdict(int)\n", + " einstein_third = defaultdict(int)\n", + " einstein_fourth = defaultdict(int)\n", + "\n", + " einstein_pairs = defaultdict(int)\n", + " winning_pairs = defaultdict(int)\n", + " pairs = defaultdict(int)\n", + "\n", + " qual_rank_list = defaultdict(lambda: [0] * 78)\n", + "\n", + " for sim in range(num_sims):\n", + " if sim % 100 == 0:\n", + " print(sim)\n", + "\n", + " noise = 4.5\n", + " curr_team_to_epa = {k : v + np.random.normal(0, noise) for k, v in team_to_epa.items()}\n", + "\n", + " rp_noise = 0.1\n", + " curr_team_to_rp_1_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_1_epa.items()}\n", + " curr_team_to_rp_2_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_2_epa.items()}\n", + "\n", + " einstein_alliances = []\n", + " einstein_aepas = []\n", + " \n", + " if status == \"Pre Divisions\":\n", + " random.shuffle(champ_team_nums)\n", + " division_1 = champ_team_nums[:78]\n", + " division_2 = champ_team_nums[78:156]\n", + " division_3 = champ_team_nums[156:233]\n", + " division_4 = champ_team_nums[233:310]\n", + " division_5 = champ_team_nums[310:388]\n", + " division_6 = champ_team_nums[388:466]\n", + " division_7 = champ_team_nums[466:543]\n", + " division_8 = champ_team_nums[543:620]\n", + " curr_divisions = [division_1, division_2, division_3, division_4, division_5, division_6, division_7, division_8]\n", + " else:\n", + " curr_divisions = divisions\n", + " \n", + " for division, matches in zip(curr_divisions, division_matches):\n", + " random.shuffle(division)\n", + " \n", + " if status == \"Final\":\n", + " schedule = matches\n", + " else:\n", + " schedule = get_schedule(len(division), 10)\n", + " schedule = [\n", + " {\n", + " \"red\": [division[x - 1] for x in m[\"red\"]],\n", + " \"blue\": [division[x - 1] for x in m[\"blue\"]],\n", + " }\n", + " for m in schedule\n", + " ]\n", + " \n", + " qual_ranks = sim_single_quals(division, schedule, curr_team_to_epa, curr_team_to_rp_1_epa, curr_team_to_rp_2_epa)\n", + " for i, t in enumerate(qual_ranks):\n", + " qual_rank_list[t][i] += 1\n", + "\n", + " alliances, aepas = sim_alliance_selection(qual_ranks, curr_team_to_epa)\n", + " for alliance in alliances:\n", + " pairs[frozenset((alliance[0], alliance[1]))] += 1\n", + " \n", + " winner, finalist, third_place, fourth_place = sim_single_elims(alliances, curr_team_to_epa)\n", + " einstein_alliances.append(alliances[winner])\n", + " einstein_aepas.append(aepas[winner])\n", + "\n", + " einstein_pairs[frozenset((alliances[winner][0], alliances[winner][1]))] += 1\n", + "\n", + " winner_alliances[winner] += 1\n", + " best_epa = max(aepas)\n", + " winner_epa = aepas[winner]\n", + " winner_best_epas.append(best_epa == winner_epa)\n", + " alliance_epas.extend(aepas)\n", + " best_epas.append(best_epa)\n", + " winner_epas.append(winner_epa)\n", + "\n", + " for t in alliances[winner]:\n", + " winner_count[t] += 1\n", + "\n", + " for t in alliances[finalist]:\n", + " finalist_count[t] += 1\n", + "\n", + " for t in alliances[third_place]:\n", + " third_place_count[t] += 1\n", + "\n", + " for t in alliances[fourth_place]:\n", + " fourth_place_count[t] += 1\n", + "\n", + " winner, finalist, third_place, fourth_place = sim_single_elims(einstein_alliances, curr_team_to_epa)\n", + " einstein_winner[winner] += 1\n", + " einstein_finalist[finalist] += 1\n", + " einstein_third[third_place] += 1\n", + " einstein_fourth[fourth_place] += 1\n", + "\n", + " winning_pairs[frozenset((einstein_alliances[winner][0], einstein_alliances[winner][1]))] += 1\n", + "\n", + " einstein_best_epa = max(einstein_aepas)\n", + " einstein_winner_epa = einstein_aepas[winner]\n", + " einstein_winner_best_epas.append(einstein_best_epa == einstein_winner_epa)\n", + " einstein_alliance_epas.extend(einstein_aepas)\n", + " einstein_best_epas.append(einstein_best_epa)\n", + " einstein_winner_epas.append(einstein_winner_epa)\n", + "\n", + " for t in einstein_alliances[winner]:\n", + " overall_winner_count[t] += 1\n", + "\n", + " for t in einstein_alliances[finalist]:\n", + " overall_finalist_count[t] += 1\n", + "\n", + " for t in einstein_alliances[third_place]:\n", + " overall_third_place_count[t] += 1\n", + "\n", + " for t in einstein_alliances[fourth_place]:\n", + " overall_fourth_place_count[t] += 1\n", + " \n", + " avg_ranks = {t: sum(((i + 1) * qual_rank_list[t][i]) for i in range(78)) / num_sims for t in qual_rank_list}\n", + " top_1 = {t: sum(qual_rank_list[t][i] for i in range(1)) / num_sims for t in qual_rank_list}\n", + " top_4 = {t: sum(qual_rank_list[t][i] for i in range(4)) / num_sims for t in qual_rank_list}\n", + " top_8 = {t: sum(qual_rank_list[t][i] for i in range(8)) / num_sims for t in qual_rank_list}\n", + " top_16 = {t: sum(qual_rank_list[t][i] for i in range(16)) / num_sims for t in qual_rank_list}\n", + " \n", + " return {\n", + " \"overall_winner_count\": overall_winner_count,\n", + " \"overall_finalist_count\": overall_finalist_count,\n", + " \"overall_third_place_count\": overall_third_place_count,\n", + " \"overall_fourth_place_count\": overall_fourth_place_count,\n", + " \"winner_count\": winner_count,\n", + " \"finalist_count\": finalist_count,\n", + " \"third_place_count\": third_place_count,\n", + " \"fourth_place_count\": fourth_place_count,\n", + " \"winner_alliances\": winner_alliances,\n", + " \"winner_best_epas\": winner_best_epas,\n", + " \"alliance_epas\": alliance_epas,\n", + " \"best_epas\": best_epas,\n", + " \"winner_epas\": winner_epas,\n", + " \"einstein_winner_best_epas\": einstein_winner_best_epas,\n", + " \"einstein_alliance_epas\": einstein_alliance_epas,\n", + " \"einstein_best_epas\": einstein_best_epas,\n", + " \"einstein_winner_epas\": einstein_winner_epas,\n", + " \"einstein_winner\": einstein_winner,\n", + " \"einstein_finalist\": einstein_finalist,\n", + " \"einstein_third\": einstein_third,\n", + " \"einstein_fourth\": einstein_fourth,\n", + " \"pairs\": pairs,\n", + " \"einstein_pairs\": einstein_pairs,\n", + " \"winning_pairs\": winning_pairs,\n", + " \"qual_rank_list\": qual_rank_list,\n", + " \"avg_ranks\": avg_ranks,\n", + " \"top_1\": top_1,\n", + " \"top_4\": top_4,\n", + " \"top_8\": top_8,\n", + " \"top_16\": top_16,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "01332858", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n" + ] + } + ], + "source": [ + "before = run_simulation(\"Pre Divisions\", 100000)\n", + "after = run_simulation(\"Pre Schedule\", 100000)\n", + "final = run_simulation(\"Final\", 100000)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "991e8ce8", + "metadata": {}, + "outputs": [], + "source": [ + "num_sims = 100000" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "1d053d42", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "

Chance of winning Einstein

\n", + "\n", + "| Division | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| --- | :-: | :-: | :-: |\n", + "| Archimedes|12.77%|49.81%|50.05%|\n", + "| Curie|12.63%|4.0%|3.83%|\n", + "| Daly|12.37%|2.63%|2.56%|\n", + "| Galileo|12.27%|13.11%|15.01%|\n", + "| Hopper|12.68%|12.32%|12.2%|\n", + "| Johnson|12.66%|5.93%|5.12%|\n", + "| Milstein|12.46%|8.37%|8.14%|\n", + "| Newton|12.16%|3.82%|3.11%|\n", + "\n", + "\n", + "

Chance of Ranking High

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Mean Rank | Pre-Schedule Mean Rank | Post-Schedule Mean Rank |\n", + "| --- | --- | --- | :-: | :-: | :-: |\n", + "| 1|1678|Galileo|8.11|8.2|2.48 |\n", + "| 2|1323|Hopper|6.01|5.35|5.19 |\n", + "| 3|2056|Archimedes|5.69|6.8|5.21 |\n", + "| 4|1619|Archimedes|13.99|16.14|5.28 |\n", + "| 5|2338|Hopper|14.14|12.6|6.11 |\n", + "| 6|3357|Hopper|16.33|14.21|6.11 |\n", + "| 7|254|Archimedes|6.44|7.77|6.27 |\n", + "| 8|3539|Galileo|23.46|24.57|6.9 |\n", + "| 9|4143|Newton|25.13|23.31|7.6 |\n", + "| 10|3937|Milstein|20.86|22.6|7.7 |\n", + "| 11|2767|Daly|14.06|13.46|7.86 |\n", + "| 12|3310|Curie|18.89|17.02|8.13 |\n", + "| 13|2539|Milstein|14.27|15.65|8.2 |\n", + "| 14|359|Johnson|15.86|15.13|8.43 |\n", + "| 15|1727|Hopper|17.58|15.91|8.47 |\n", + "| 16|2687|Archimedes|16.16|18.36|8.5 |\n", + "| 17|6672|Milstein|13.65|14.71|8.98 |\n", + "| 18|51|Johnson|19.91|19.43|8.98 |\n", + "| 19|3467|Galileo|13.35|13.86|9.13 |\n", + "| 20|4613|Daly|17.64|17.18|9.2 |\n", + "| 21|3940|Newton|29.96|27.75|9.64 |\n", + "| 22|2075|Johnson|20.3|19.57|9.77 |\n", + "| 23|1114|Galileo|19.72|20.65|9.82 |\n", + "| 24|3175|Johnson|15.14|14.6|9.83 |\n", + "| 25|195|Newton|12.32|9.86|9.89 |\n", + "\n", + "\n", + "See Statbotics event pages for individual event simulations\n", + "\n", + "

Chance of winning division

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|64.65%|58.7%|59.45%|\n", + "| 2|1323|Hopper|55.6%|56.14%|56.39%|\n", + "| 3|1678|Galileo|38.27%|37.9%|48.5%|\n", + "| 4|254|Archimedes|54.55%|47.01%|48.32%|\n", + "| 5|3005|Galileo|35.34%|35.31%|38.87%|\n", + "| 6|5940|Curie|27.97%|34.24%|33.69%|\n", + "| 7|971|Johnson|28.82%|33.93%|31.88%|\n", + "| 8|3538|Newton|28.36%|35.63%|30.15%|\n", + "| 9|195|Newton|19.65%|25.87%|24.33%|\n", + "| 10|6672|Milstein|22.63%|21.82%|24.32%|\n", + "| 11|2338|Hopper|17.65%|17.7%|22.69%|\n", + "| 12|7157|Johnson|22.03%|26.19%|22.53%|\n", + "| 13|2767|Daly|15.36%|19.54%|21.09%|\n", + "| 14|359|Johnson|15.5%|17.59%|19.92%|\n", + "| 15|930|Milstein|23.3%|22.12%|19.36%|\n", + "| 16|7890|Curie|14.51%|18.64%|19.28%|\n", + "| 17|1987|Hopper|20.13%|20.97%|18.39%|\n", + "| 18|2539|Milstein|16.21%|15.62%|18.18%|\n", + "| 19|4907|Daly|13.77%|18.01%|18.12%|\n", + "| 20|1619|Archimedes|19.77%|10.11%|17.97%|\n", + "| 21|148|Curie|12.99%|15.94%|17.39%|\n", + "| 22|3683|Milstein|17.96%|17.84%|17.15%|\n", + "| 23|1756|Curie|13.65%|17.25%|17.04%|\n", + "| 24|4499|Johnson|15.42%|17.93%|16.8%|\n", + "| 25|3310|Curie|11.66%|13.92%|16.71%|\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|64.65%|58.7%|59.45%|\n", + "| 2|254|Archimedes|54.55%|47.01%|48.32%|\n", + "| 3|1619|Archimedes|19.77%|10.11%|17.97%|\n", + "| 4|111|Archimedes|29.17%|16.97%|15.56%|\n", + "| 5|6036|Archimedes|27.33%|15.33%|13.29%|\n", + "| 6|4362|Archimedes|10.31%|8.9%|9.8%|\n", + "| 7|70|Archimedes|9.29%|8.93%|9.77%|\n", + "| 8|7211|Archimedes|9.14%|8.87%|9.43%|\n", + "| 9|1768|Archimedes|8.89%|8.26%|9.43%|\n", + "| 10|6002|Archimedes|10.26%|8.98%|9.34%|\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|5940|Curie|27.97%|34.24%|33.69%|\n", + "| 2|7890|Curie|14.51%|18.64%|19.28%|\n", + "| 3|148|Curie|12.99%|15.94%|17.39%|\n", + "| 4|1756|Curie|13.65%|17.25%|17.04%|\n", + "| 5|3310|Curie|11.66%|13.92%|16.71%|\n", + "| 6|6329|Curie|13.41%|16.59%|15.25%|\n", + "| 7|2451|Curie|11.47%|13.38%|14.14%|\n", + "| 8|4253|Curie|10.62%|12.28%|13.07%|\n", + "| 9|4270|Curie|11.21%|12.9%|11.89%|\n", + "| 10|7021|Curie|10.78%|12.2%|11.35%|\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2767|Daly|15.36%|19.54%|21.09%|\n", + "| 2|4907|Daly|13.77%|18.01%|18.12%|\n", + "| 3|4613|Daly|11.69%|14.43%|15.57%|\n", + "| 4|2363|Daly|12.89%|16.47%|15.21%|\n", + "| 5|230|Daly|11.82%|15.0%|14.32%|\n", + "| 6|3314|Daly|11.25%|13.85%|14.06%|\n", + "| 7|870|Daly|11.89%|14.81%|13.91%|\n", + "| 8|1325|Daly|12.25%|15.26%|13.91%|\n", + "| 9|6424|Daly|10.79%|12.91%|13.18%|\n", + "| 10|7769|Daly|11.24%|13.56%|13.15%|\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|1678|Galileo|38.27%|37.9%|48.5%|\n", + "| 2|3005|Galileo|35.34%|35.31%|38.87%|\n", + "| 3|3467|Galileo|17.51%|15.97%|16.46%|\n", + "| 4|2910|Galileo|18.58%|16.73%|13.46%|\n", + "| 5|1591|Galileo|16.33%|14.73%|12.67%|\n", + "| 6|3476|Galileo|11.65%|10.6%|11.04%|\n", + "| 7|4381|Galileo|13.09%|11.93%|10.75%|\n", + "| 8|5199|Galileo|10.59%|10.01%|10.38%|\n", + "| 9|401|Galileo|10.82%|10.35%|10.33%|\n", + "| 10|5987|Galileo|10.28%|9.96%|10.12%|\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|1323|Hopper|55.6%|56.14%|56.39%|\n", + "| 2|2338|Hopper|17.65%|17.7%|22.69%|\n", + "| 3|1987|Hopper|20.13%|20.97%|18.39%|\n", + "| 4|1727|Hopper|13.65%|11.97%|15.18%|\n", + "| 5|1706|Hopper|14.94%|14.09%|15.06%|\n", + "| 6|4414|Hopper|17.21%|16.9%|14.29%|\n", + "| 7|3357|Hopper|11.94%|10.32%|13.08%|\n", + "| 8|4213|Hopper|5.99%|9.65%|10.8%|\n", + "| 9|245|Hopper|9.54%|9.65%|10.55%|\n", + "| 10|4336|Hopper|8.97%|10.51%|10.33%|\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|971|Johnson|28.82%|33.93%|31.88%|\n", + "| 2|7157|Johnson|22.03%|26.19%|22.53%|\n", + "| 3|359|Johnson|15.5%|17.59%|19.92%|\n", + "| 4|4499|Johnson|15.42%|17.93%|16.8%|\n", + "| 5|2075|Johnson|12.26%|13.51%|15.71%|\n", + "| 6|1718|Johnson|11.86%|13.08%|14.88%|\n", + "| 7|51|Johnson|11.58%|12.55%|14.59%|\n", + "| 8|3175|Johnson|12.48%|13.55%|14.53%|\n", + "| 9|1339|Johnson|10.2%|10.85%|11.13%|\n", + "| 10|1391|Johnson|10.9%|11.08%|10.52%|\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|6672|Milstein|22.63%|21.82%|24.32%|\n", + "| 2|930|Milstein|23.3%|22.12%|19.36%|\n", + "| 3|2539|Milstein|16.21%|15.62%|18.18%|\n", + "| 4|3683|Milstein|17.96%|17.84%|17.15%|\n", + "| 5|176|Milstein|17.89%|17.34%|15.55%|\n", + "| 6|987|Milstein|14.61%|14.43%|14.73%|\n", + "| 7|5913|Milstein|14.2%|13.95%|14.47%|\n", + "| 8|604|Milstein|13.47%|13.39%|13.74%|\n", + "| 9|5895|Milstein|12.87%|12.89%|13.63%|\n", + "| 10|6090|Milstein|14.61%|14.21%|12.9%|\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|3538|Newton|28.36%|35.63%|30.15%|\n", + "| 2|195|Newton|19.65%|25.87%|24.33%|\n", + "| 3|4143|Newton|10.67%|11.39%|15.39%|\n", + "| 4|1538|Newton|13.46%|16.71%|14.74%|\n", + "| 5|857|Newton|11.59%|13.05%|14.62%|\n", + "| 6|3184|Newton|12.27%|13.92%|14.14%|\n", + "| 7|1757|Newton|12.55%|14.86%|14.03%|\n", + "| 8|4522|Newton|13.33%|16.2%|13.67%|\n", + "| 9|494|Newton|10.7%|11.73%|13.59%|\n", + "| 10|2992|Newton|10.45%|10.96%|12.27%|\n", + "\n", + "[/details]\n", + "\n", + "

Chance of winning Einstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|28.39%|37.23%|37.84% |\n", + "| 2|254|Archimedes|18.68%|29.5%|30.0% |\n", + "| 3|1678|Galileo|8.92%|7.88%|11.51% |\n", + "| 4|1323|Hopper|19.59%|10.8%|10.74% |\n", + "| 5|3005|Galileo|7.82%|7.22%|9.18% |\n", + "| 6|1619|Archimedes|2.46%|3.94%|7.69% |\n", + "| 7|111|Archimedes|5.23%|7.77%|7.08% |\n", + "| 8|6036|Archimedes|4.6%|6.87%|5.63% |\n", + "| 9|70|Archimedes|1.06%|4.33%|4.88% |\n", + "| 10|4362|Archimedes|1.01%|4.19%|4.81% |\n", + "| 11|7211|Archimedes|1.01%|4.31%|4.8% |\n", + "| 12|1768|Archimedes|0.96%|4.02%|4.78% |\n", + "| 13|5232|Archimedes|1.01%|4.25%|4.68% |\n", + "| 14|4476|Archimedes|1.01%|4.48%|4.56% |\n", + "| 15|1189|Archimedes|1.0%|4.23%|4.56% |\n", + "| 16|6002|Archimedes|1.07%|4.19%|4.46% |\n", + "| 17|972|Archimedes|0.96%|3.97%|4.28% |\n", + "| 18|33|Archimedes|1.04%|4.23%|4.24% |\n", + "| 19|624|Archimedes|1.01%|4.14%|4.0% |\n", + "| 20|4903|Archimedes|0.95%|3.89%|3.95% |\n", + "| 21|4373|Archimedes|0.92%|4.04%|3.83% |\n", + "| 22|1574|Archimedes|0.86%|3.44%|3.8% |\n", + "| 23|3663|Archimedes|1.03%|3.71%|3.79% |\n", + "| 24|6328|Archimedes|1.03%|3.58%|3.79% |\n", + "| 25|3015|Archimedes|1.1%|3.25%|3.62% |\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|28.39%|37.23%|37.84% |\n", + "| 2|254|Archimedes|18.68%|29.5%|30.0% |\n", + "| 3|1619|Archimedes|2.46%|3.94%|7.69% |\n", + "| 4|111|Archimedes|5.23%|7.77%|7.08% |\n", + "| 5|6036|Archimedes|4.6%|6.87%|5.63% |\n", + "| 6|70|Archimedes|1.06%|4.33%|4.88% |\n", + "| 7|4362|Archimedes|1.01%|4.19%|4.81% |\n", + "| 8|7211|Archimedes|1.01%|4.31%|4.8% |\n", + "| 9|1768|Archimedes|0.96%|4.02%|4.78% |\n", + "| 10|5232|Archimedes|1.01%|4.25%|4.68% |\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|5940|Curie|4.86%|2.5%|2.38% |\n", + "| 2|7890|Curie|1.39%|0.93%|0.96% |\n", + "| 3|148|Curie|1.15%|0.69%|0.74% |\n", + "| 4|3310|Curie|1.05%|0.51%|0.73% |\n", + "| 5|1756|Curie|1.29%|0.8%|0.71% |\n", + "| 6|6329|Curie|1.24%|0.72%|0.63% |\n", + "| 7|2451|Curie|1.05%|0.51%|0.51% |\n", + "| 8|4253|Curie|1.02%|0.45%|0.39% |\n", + "| 9|5907|Curie|0.92%|0.29%|0.39% |\n", + "| 10|7021|Curie|1.06%|0.4%|0.36% |\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|2767|Daly|1.59%|0.71%|0.8% |\n", + "| 2|4907|Daly|1.31%|0.62%|0.61% |\n", + "| 3|2363|Daly|1.16%|0.55%|0.47% |\n", + "| 4|4613|Daly|1.04%|0.4%|0.44% |\n", + "| 5|1325|Daly|1.1%|0.46%|0.41% |\n", + "| 6|230|Daly|1.11%|0.44%|0.4% |\n", + "| 7|3314|Daly|1.11%|0.39%|0.37% |\n", + "| 8|870|Daly|1.03%|0.43%|0.37% |\n", + "| 9|7769|Daly|1.05%|0.36%|0.35% |\n", + "| 10|6424|Daly|1.03%|0.31%|0.32% |\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|1678|Galileo|8.92%|7.88%|11.51% |\n", + "| 2|3005|Galileo|7.82%|7.22%|9.18% |\n", + "| 3|3467|Galileo|2.03%|1.9%|2.08% |\n", + "| 4|2910|Galileo|2.17%|2.14%|1.68% |\n", + "| 5|1591|Galileo|1.78%|1.76%|1.44% |\n", + "| 6|5199|Galileo|1.05%|1.15%|1.41% |\n", + "| 7|5987|Galileo|1.08%|1.17%|1.38% |\n", + "| 8|6722|Galileo|1.05%|1.16%|1.36% |\n", + "| 9|1690|Galileo|1.03%|1.03%|1.34% |\n", + "| 10|401|Galileo|1.05%|1.1%|1.32% |\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|1323|Hopper|19.59%|10.8%|10.74% |\n", + "| 2|2338|Hopper|2.0%|2.27%|3.24% |\n", + "| 3|1987|Hopper|2.54%|3.02%|2.37% |\n", + "| 4|1706|Hopper|1.44%|1.57%|1.67% |\n", + "| 5|1727|Hopper|1.33%|1.15%|1.61% |\n", + "| 6|4414|Hopper|1.92%|2.07%|1.5% |\n", + "| 7|4213|Hopper|0.61%|1.17%|1.38% |\n", + "| 8|4265|Hopper|0.69%|1.24%|1.34% |\n", + "| 9|245|Hopper|1.05%|1.12%|1.24% |\n", + "| 10|4336|Hopper|0.95%|1.25%|1.24% |\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|971|Johnson|5.31%|3.33%|2.75% |\n", + "| 2|7157|Johnson|3.12%|2.4%|1.49% |\n", + "| 3|359|Johnson|1.53%|1.18%|1.21% |\n", + "| 4|4499|Johnson|1.65%|1.21%|0.91% |\n", + "| 5|2075|Johnson|1.16%|0.7%|0.81% |\n", + "| 6|51|Johnson|1.07%|0.63%|0.74% |\n", + "| 7|1718|Johnson|1.09%|0.64%|0.71% |\n", + "| 8|3175|Johnson|1.12%|0.69%|0.66% |\n", + "| 9|2521|Johnson|1.04%|0.52%|0.49% |\n", + "| 10|9312|Johnson|0.97%|0.47%|0.46% |\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|6672|Milstein|3.28%|2.56%|2.86% |\n", + "| 2|930|Milstein|3.28%|2.62%|2.1% |\n", + "| 3|2539|Milstein|1.69%|1.4%|1.7% |\n", + "| 4|3683|Milstein|2.13%|1.74%|1.65% |\n", + "| 5|176|Milstein|2.04%|1.65%|1.38% |\n", + "| 6|5913|Milstein|1.44%|1.14%|1.22% |\n", + "| 7|987|Milstein|1.44%|1.22%|1.22% |\n", + "| 8|5895|Milstein|1.15%|0.97%|1.16% |\n", + "| 9|604|Milstein|1.3%|1.12%|1.08% |\n", + "| 10|6090|Milstein|1.39%|1.15%|0.97% |\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: |\n", + "| 1|3538|Newton|5.16%|2.52%|1.63% |\n", + "| 2|195|Newton|2.37%|1.51%|1.22% |\n", + "| 3|1538|Newton|1.34%|0.71%|0.45% |\n", + "| 4|857|Newton|1.07%|0.42%|0.43% |\n", + "| 5|4143|Newton|1.05%|0.34%|0.43% |\n", + "| 6|1757|Newton|1.12%|0.53%|0.43% |\n", + "| 7|3184|Newton|1.07%|0.48%|0.41% |\n", + "| 8|4522|Newton|1.24%|0.57%|0.39% |\n", + "| 9|494|Newton|1.04%|0.35%|0.37% |\n", + "| 10|7285|Newton|1.04%|0.37%|0.34% |\n", + "\n", + "[/details]\n", + "\n", + "

Most likely pairings

\n", + "\n", + "| Rank | Division        | Team 1          | Team 2          | On Alliance     | Win Division    | Win Einstein    |\n", + "| --- | --- | --- | --- | :-: | :-: | :-: |\n", + "| 1|Archimedes|2056|254|34.48%|28.65%|21.48%\n", + "| 2|Galileo|1678|3005|36.81%|24.3%|7.36%\n", + "| 3|Archimedes|2056|1619|17.0%|8.65%|4.59%\n", + "| 4|Archimedes|2056|111|8.77%|5.66%|3.59%\n", + "| 5|Hopper|1323|2338|21.03%|13.06%|2.79%\n", + "| 6|Archimedes|2056|6036|6.97%|4.36%|2.71%\n", + "| 7|Archimedes|254|111|7.37%|3.55%|1.94%\n", + "| 8|Archimedes|254|1619|11.84%|4.3%|1.87%\n", + "| 9|Hopper|1323|1987|11.89%|7.85%|1.86%\n", + "| 10|Archimedes|254|6036|6.04%|2.85%|1.51%\n", + "| 11|Hopper|1323|1706|10.2%|6.24%|1.27%\n", + "| 12|Hopper|1323|1727|12.35%|6.93%|1.24%\n", + "| 13|Hopper|1323|4414|7.77%|5.0%|1.09%\n", + "| 14|Archimedes|2056|2687|5.38%|2.22%|1.05%\n", + "| 15|Archimedes|2056|4028|3.1%|1.67%|0.92%\n", + "| 16|Galileo|1678|2910|9.05%|4.39%|0.92%\n", + "| 17|Galileo|1678|3467|8.86%|4.26%|0.87%\n", + "| 18|Hopper|1323|3357|12.08%|6.02%|0.83%\n", + "| 19|Archimedes|2056|1577|3.02%|1.51%|0.8%\n", + "| 20|Galileo|1678|1591|7.57%|3.54%|0.72%\n", + "| 21|Archimedes|2056|2468|2.71%|1.29%|0.65%\n", + "| 22|Archimedes|254|2687|6.11%|1.52%|0.55%\n", + "| 23|Newton|3538|195|10.69%|5.69%|0.55%\n", + "| 24|Johnson|971|359|11.14%|4.77%|0.54%\n", + "| 25|Galileo|3005|3467|7.32%|2.92%|0.52%\n" + ] + } + ], + "source": [ + "def pad(s, length = 15):\n", + " return s + \" \" * (length - len(s))\n", + "\n", + "def percent(x):\n", + " return str(round(100 * x, 2)) + \"%\"\n", + "\n", + "division_names = [\"Archimedes\", \"Curie\", \"Daly\", \"Galileo\", \"Hopper\", \"Johnson\", \"Milstein\", \"Newton\"]\n", + "division_to_team = {}\n", + "for i, division in enumerate(divisions):\n", + " for t in division:\n", + " division_to_team[t] = division_names[i]\n", + "\n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print(\"| Division | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" |\")\n", + "print(\"| --- | :-: | :-: | :-: |\")\n", + "for i in range(8):\n", + " print(\"|\", \"|\".join([division_names[i], percent(before[\"einstein_winner\"][i] / num_sims), percent(after[\"einstein_winner\"][i] / num_sims), percent(final[\"einstein_winner\"][i] / num_sims)]) + \"|\")\n", + "print()\n", + "print()\n", + "\n", + "def print_ranks(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Mean Rank\"), \" | \", pad(\"Pre-Schedule Mean Rank\"), \" | \", pad(\"Post-Schedule Mean Rank\"), \" |\")\n", + " print(\"| --- | --- | --- | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(final[\"avg_ranks\"].items(), key=lambda x: (filter(x[0]), x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], str(round(before[\"avg_ranks\"][key], 2)), str(round(after[\"avg_ranks\"][key], 2)), str(round(final[\"avg_ranks\"][key], 2))]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of Ranking High

\")\n", + "print()\n", + " \n", + "print_ranks()\n", + "\n", + "print()\n", + "print(\"See Statbotics event pages for individual event simulations\")\n", + "print()\n", + "\n", + "\n", + "def print_divisions(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(final[\"winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"winner_count\"][key] / num_sims), percent(after[\"winner_count\"][key] / num_sims), percent(final[\"winner_count\"][key] / num_sims)]) + \"|\")\n", + " print()\n", + "\n", + "print(\"

Chance of winning division

\")\n", + "print()\n", + " \n", + "print_divisions()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_divisions(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "def print_einstein(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(final[\"overall_winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"overall_winner_count\"][key] / num_sims), percent(after[\"overall_winner_count\"][key] / num_sims), percent(final[\"overall_winner_count\"][key] / num_sims)]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print_einstein()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_einstein(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "print(\"

Most likely pairings

\")\n", + "print()\n", + "\n", + "print(\"| Rank | \", pad(\"Division\"), \"|\", pad(\"Team 1\"), \"|\", pad(\"Team 2\"), \"|\", pad(\"On Alliance\"), \"|\", pad(\"Win Division\"), \"|\", pad(\"Win Einstein\"), \"|\")\n", + "print(\"| --- | --- | --- | --- | :-: | :-: | :-: |\")\n", + "for i, (key, _) in enumerate(sorted(final[\"winning_pairs\"].items(), key=lambda x: -x[1])[:25]):\n", + " key_list = sorted(list(key), key=lambda x: -team_to_epa[x])\n", + " print(\"|\", \"|\".join([str(i + 1), division_to_team[key_list[0]], str(key_list[0]), str(key_list[1]), percent(final[\"pairs\"][key] / num_sims), percent(final[\"einstein_pairs\"][key] / num_sims), percent(final[\"winning_pairs\"][key] / num_sims)]))\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77b67391", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/scripts/2023/Simulate Champs V5.ipynb b/scripts/2023/Simulate Champs V5.ipynb new file mode 100644 index 00000000..cb282803 --- /dev/null +++ b/scripts/2023/Simulate Champs V5.ipynb @@ -0,0 +1,5199 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b698f107", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "from functools import lru_cache\n", + "import random\n", + "import requests\n", + "from requests import Session\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import statbotics\n", + "\n", + "%matplotlib notebook\n", + "\n", + "sb = statbotics.Statbotics()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4568bf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3286" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_teams = sb.get_team_years(year=2023, limit=10000)\n", + "all_teams_dict = {t[\"team\"]: t for t in all_teams}\n", + "len(all_teams)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4a08ee65", + "metadata": {}, + "outputs": [], + "source": [ + "AUTH_KEY = \"XeUIxlvO4CPc44NlLE3ncevDg7bAhp6CRy6zC9M2aQb2zGfys0M30eKwavFJSEJr\"\n", + "\n", + "read_prefix = \"https://www.thebluealliance.com/api/v3/\"\n", + "\n", + "session = Session()\n", + "session.headers.update({\"X-TBA-Auth-Key\": AUTH_KEY, \"X-TBA-Auth-Id\": \"\"})\n", + "\n", + "def get_tba(url):\n", + " response = session.get(read_prefix + url)\n", + " return response.json()\n", + "\n", + "@lru_cache()\n", + "def get_event_teams(key):\n", + " data = get_tba(f\"event/{key}/teams\")\n", + " return [int(x[\"key\"][3:]) for x in data]\n", + "\n", + "@lru_cache()\n", + "def get_event_matches(key):\n", + " data = get_tba(f\"event/{key}/matches\")\n", + " return [{\"red\": [int(y[3:]) for y in x[\"alliances\"][\"red\"][\"team_keys\"]], \"blue\": [int(y[3:]) for y in x[\"alliances\"][\"blue\"][\"team_keys\"]]} for x in data]\n", + "\n", + "@lru_cache()\n", + "def get_event_rankings(key):\n", + " data = get_tba(f\"event/{key}/rankings\")\n", + " return [int(x[\"team_key\"][3:]) for x in data[\"rankings\"]]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f8fa559f", + "metadata": {}, + "outputs": [], + "source": [ + "divisions = [\n", + " get_event_teams(\"2023arc\"),\n", + " get_event_teams(\"2023cur\"),\n", + " get_event_teams(\"2023dal\"),\n", + " get_event_teams(\"2023gal\"),\n", + " get_event_teams(\"2023hop\"),\n", + " get_event_teams(\"2023joh\"),\n", + " get_event_teams(\"2023mil\"),\n", + " get_event_teams(\"2023new\"),\n", + "]\n", + "\n", + "champ_team_nums = []\n", + "for division in divisions:\n", + " champ_team_nums.extend(division)\n", + "\n", + "division_matches = [\n", + " get_event_matches(\"2023arc\"),\n", + " get_event_matches(\"2023cur\"),\n", + " get_event_matches(\"2023dal\"),\n", + " get_event_matches(\"2023gal\"),\n", + " get_event_matches(\"2023hop\"),\n", + " get_event_matches(\"2023joh\"),\n", + " get_event_matches(\"2023mil\"),\n", + " get_event_matches(\"2023new\"),\n", + "]\n", + "\n", + "division_ranks = [\n", + " get_event_rankings(\"2023arc\"),\n", + " get_event_rankings(\"2023cur\"),\n", + " get_event_rankings(\"2023dal\"),\n", + " get_event_rankings(\"2023gal\"),\n", + " get_event_rankings(\"2023hop\"),\n", + " get_event_rankings(\"2023joh\"),\n", + " get_event_rankings(\"2023mil\"),\n", + " get_event_rankings(\"2023new\"),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "b4529072", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "83.98 1.029 0.6023\n", + "80.14 0.9967 0.4425\n" + ] + } + ], + "source": [ + "team_to_pre_champs_epa = {t: all_teams_dict[t][\"epa_pre_champs\"] for t in champ_team_nums}\n", + "team_to_end_epa = {t: all_teams_dict[t][\"epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_1_epa = {t: all_teams_dict[t][\"rp_1_epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_2_epa = {t: all_teams_dict[t][\"rp_2_epa_end\"] for t in champ_team_nums}\n", + "\n", + "print(team_to_epa[2056], team_to_rp_1_epa[2056], team_to_rp_2_epa[2056])\n", + "print(team_to_epa[254], team_to_rp_1_epa[254], team_to_rp_2_epa[254])" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "38d2a765", + "metadata": {}, + "outputs": [], + "source": [ + "TOTAL_MEAN = 74.57\n", + "TOTAL_SD = 29.36" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "811dfb7e", + "metadata": {}, + "outputs": [], + "source": [ + "@lru_cache\n", + "def make_request(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " data = response.text\n", + " lines = data.split(\"\\n\")\n", + " return lines\n", + "\n", + "@lru_cache\n", + "def get_schedule(num_teams: int, num_matches: int):\n", + " # TODO: remove this once we have pre-generated schedules for 100+ teams\n", + " if num_teams > 100:\n", + " schedule1 = get_schedule(100, num_matches)\n", + " schedule2 = get_schedule(num_teams - 100, num_matches)\n", + " schedule2 = [\n", + " {\"red\": [team + 100 for team in match[\"red\"]], \"blue\": [team + 100 for team in match[\"blue\"]]}\n", + " for match in schedule2\n", + " ]\n", + " return schedule1 + schedule2\n", + "\n", + " # load csv from external URL using requests\n", + " lines = make_request(f\"https://raw.githubusercontent.com/Team254/cheesy-arena/main/schedules/{num_teams}_{num_matches}.csv\")\n", + " \n", + " schedule = []\n", + " for line in lines:\n", + " match = line.split(\",\")\n", + " if len(match) < 12:\n", + " continue\n", + " red = [int(match[0]), int(match[2]), int(match[4])]\n", + " blue = [int(match[6]), int(match[8]), int(match[10])]\n", + " schedule.append({\"red\": red, \"blue\": blue})\n", + " \n", + " return schedule" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c2233c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def get_win_prob(a, b):\n", + " return 1 / (1 + 10 ** (((-5 / 8) * (a - b)) / TOTAL_SD))\n", + "\n", + "def get_rp_pred(a):\n", + " return 1 / (1 + np.e ** (-4 * (a - 0.5)))\n", + "\n", + "def sim_single_quals(teams, schedule, team_to_epa, team_to_rp_1_epa, team_to_rp_2_epa):\n", + " curr_sim_matches = {t: 0 for t in teams}\n", + " curr_sim_rps = {t: 0 for t in teams}\n", + " for m in schedule:\n", + " red_epa = sum(team_to_epa[x] for x in m[\"red\"])\n", + " blue_epa = sum(team_to_epa[x] for x in m[\"blue\"])\n", + " red_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"red\"])\n", + " blue_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"blue\"])\n", + " red_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"red\"])\n", + " blue_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"blue\"])\n", + " \n", + " win_prob = get_win_prob(red_epa, blue_epa)\n", + " red_win = 1 if random.random() < win_prob else 0\n", + "\n", + " red_rp_1_prob = get_rp_pred(0.9 * red_rp_1_epa)\n", + " red_rp_1 = 1 if random.random() < red_rp_1_prob else 0\n", + " \n", + " red_rp_2_prob = get_rp_pred(red_rp_2_epa)\n", + " red_rp_2 = 1 if random.random() < red_rp_2_prob else 0\n", + " \n", + " blue_rp_1_prob = get_rp_pred(0.9 * blue_rp_1_epa)\n", + " blue_rp_1 = 1 if random.random() < blue_rp_1_prob else 0\n", + " \n", + " blue_rp_2_prob = get_rp_pred(blue_rp_2_epa)\n", + " blue_rp_2 = 1 if random.random() < blue_rp_2_prob else 0\n", + "\n", + " red_rps = red_rp_1 + red_rp_2 + (2 if red_win else 0)\n", + " blue_rps = blue_rp_1 + blue_rp_2 + (0 if red_win else 2)\n", + " \n", + " for x in m[\"red\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += red_rps\n", + " \n", + " for x in m[\"blue\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += blue_rps\n", + " \n", + " curr_sim_ranks = sorted(curr_sim_rps.items(), key=lambda x: [-x[1], random.random()])\n", + " \n", + " return [x[0] for x in curr_sim_ranks]\n", + "\n", + "def softmax_select(options, mult=1):\n", + " exp = [np.e ** (mult * o) for o in options]\n", + " sum_exp = sum(exp)\n", + " exp = [e / sum_exp for e in exp]\n", + " rand = random.random()\n", + " curr, i = 0, 0\n", + " while curr < rand:\n", + " curr += exp[i]\n", + " i += 1\n", + " return i - 1\n", + "\n", + "def sim_alliance_selection(ranks, team_to_epa):\n", + " alliances = [[], [], [], [], [], [], [], []]\n", + " locked_teams = []\n", + " remaining_teams = [(r, team_to_epa[r]) for r in ranks]\n", + " \n", + " r1_mult = 1 / 3\n", + " r2_mult = 1 / 2\n", + " \n", + " def handle_selection(selector, reject=True):\n", + " selected = None\n", + " while selected is None:\n", + " temp_remaining_teams = [r for r in remaining_teams if r not in locked_teams]\n", + " _selected = softmax_select([r[1] for r in temp_remaining_teams], r1_mult)\n", + " _selected_team = temp_remaining_teams[_selected]\n", + " orig_rank = ranks.index(_selected_team[0]) + 1\n", + " if not reject or orig_rank > 8:\n", + " selected = _selected\n", + " continue\n", + " \n", + " selected_rank = remaining_teams.index(_selected_team) + 1\n", + " remaining_best_epas = sorted(temp_remaining_teams[_selected + 1:], key=lambda x: -x[1])\n", + " if remaining_best_epas[selected_rank][1] > selector[1] + 5:\n", + " locked_teams.append(_selected_team)\n", + " else:\n", + " selected = _selected\n", + " \n", + " return remaining_teams.index(temp_remaining_teams[selected])\n", + " \n", + " # Captain and Round 1\n", + " alliances[0].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[1].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[2].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[3].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + "\n", + " alliances[4].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[5].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[6].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[7].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 2\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 3\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " aepas = [sum(a[1] for a in alliance[:3]) for alliance in alliances]\n", + " return [[a[0] for a in alliance] for alliance in alliances], aepas\n", + "\n", + "def sim_single_elims(alliances, team_to_epa):\n", + " scores, grids = [], []\n", + " \n", + " aepas = [sum(team_to_epa[a] for a in alliance[:3]) for alliance in alliances]\n", + " ms = [[0, 7], [3, 4], [1, 6], [2, 5], [], [], [], [], [], [], [], [], []]\n", + " \n", + " def _get_win_prob(i):\n", + " return get_win_prob(aepas[ms[i][0]], aepas[ms[i][1]])\n", + "\n", + " m1_red_winner = random.random() < _get_win_prob(0)\n", + " ms[4].append(ms[0][1] if m1_red_winner else ms[0][0])\n", + " ms[6].append(ms[0][0] if m1_red_winner else ms[0][1])\n", + " \n", + " m2_red_winner = random.random() < _get_win_prob(1)\n", + " ms[4].append(ms[1][1] if m2_red_winner else ms[1][0])\n", + " ms[6].append(ms[1][0] if m2_red_winner else ms[1][1])\n", + " \n", + " m3_red_winner = random.random() < _get_win_prob(2)\n", + " ms[5].append(ms[2][1] if m3_red_winner else ms[2][0])\n", + " ms[7].append(ms[2][0] if m3_red_winner else ms[2][1])\n", + " \n", + " m4_red_winner = random.random() < _get_win_prob(3)\n", + " ms[5].append(ms[3][1] if m4_red_winner else ms[3][0])\n", + " ms[7].append(ms[3][0] if m4_red_winner else ms[3][1])\n", + " \n", + " m5_red_winner = random.random() < _get_win_prob(4)\n", + " ms[9].append(ms[4][0] if m5_red_winner else ms[4][1])\n", + " \n", + " m6_red_winner = random.random() < _get_win_prob(5)\n", + " ms[8].append(ms[5][0] if m6_red_winner else ms[5][1])\n", + " \n", + " m7_red_winner = random.random() < _get_win_prob(6)\n", + " ms[8].append(ms[6][1] if m7_red_winner else ms[6][0])\n", + " ms[10].append(ms[6][0] if m7_red_winner else ms[6][1])\n", + " \n", + " m8_red_winner = random.random() < _get_win_prob(7)\n", + " ms[9].append(ms[7][1] if m8_red_winner else ms[7][0])\n", + " ms[10].append(ms[7][0] if m8_red_winner else ms[7][1])\n", + " \n", + " m9_red_winner = random.random() < _get_win_prob(8)\n", + " ms[11].append(ms[8][0] if m9_red_winner else ms[8][1])\n", + " \n", + " m10_red_winner = random.random() < _get_win_prob(9)\n", + " ms[11].append(ms[9][0] if m10_red_winner else ms[9][1])\n", + " \n", + " m11_red_winner = random.random() < _get_win_prob(10)\n", + " ms[12].append(ms[10][1] if m11_red_winner else ms[10][0])\n", + " finalist_1 = ms[10][0] if m11_red_winner else ms[10][1]\n", + " \n", + " m12_red_winner = random.random() < _get_win_prob(11)\n", + " fourth_place = ms[11][1] if m12_red_winner else ms[11][0]\n", + " ms[12].append(ms[11][0] if m12_red_winner else ms[11][1])\n", + " \n", + " m13_red_winner = random.random() < _get_win_prob(12)\n", + " third_place = ms[12][1] if m13_red_winner else ms[12][0]\n", + " finalist_2 = ms[12][0] if m13_red_winner else ms[12][1]\n", + " \n", + " \n", + " f1_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f2_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f3_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " winner = finalist_1 if f1_red_winner + f2_red_winner + f3_red_winner >= 2 else finalist_2\n", + " second_place = finalist_2 if winner == finalist_1 else finalist_1\n", + " \n", + " return winner, second_place, third_place, fourth_place\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "62276690", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Options: Pre Divisions, Pre Schedules, Final, Post Quals\n", + "def run_simulation(status=\"Pre Divisions\", num_sims=1000):\n", + " overall_winner_count = defaultdict(int)\n", + " overall_finalist_count = defaultdict(int)\n", + " overall_third_place_count = defaultdict(int)\n", + " overall_fourth_place_count = defaultdict(int)\n", + "\n", + " winner_count = defaultdict(int)\n", + " finalist_count = defaultdict(int)\n", + " third_place_count = defaultdict(int)\n", + " fourth_place_count = defaultdict(int)\n", + "\n", + " winner_alliances = defaultdict(int)\n", + " winner_best_epas = []\n", + " alliance_epas = []\n", + " best_epas = []\n", + " winner_epas = []\n", + "\n", + " einstein_winner_best_epas = []\n", + " einstein_alliance_epas = []\n", + " einstein_best_epas = []\n", + " einstein_winner_epas = []\n", + "\n", + " einstein_winner = defaultdict(int)\n", + " einstein_finalist = defaultdict(int)\n", + " einstein_third = defaultdict(int)\n", + " einstein_fourth = defaultdict(int)\n", + "\n", + " einstein_pairs = defaultdict(int)\n", + " winning_pairs = defaultdict(int)\n", + " pairs = defaultdict(int)\n", + "\n", + " qual_rank_list = defaultdict(lambda: [0] * 78)\n", + "\n", + " for sim in range(num_sims):\n", + " if sim % 100 == 0:\n", + " print(sim)\n", + "\n", + " noise = 4.5\n", + " if status == \"Post Quals\":\n", + " curr_team_to_epa = {k: v + np.random.normal(0, noise) for k, v in team_to_end_epa.items()}\n", + " else:\n", + " curr_team_to_epa = {k : v + np.random.normal(0, noise) for k, v in team_to_pre_champs_epa.items()}\n", + "\n", + " rp_noise = 0.1\n", + " curr_team_to_rp_1_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_1_epa.items()}\n", + " curr_team_to_rp_2_epa = {k : v + np.random.normal(0, rp_noise) for k, v in team_to_rp_2_epa.items()}\n", + "\n", + " einstein_alliances = []\n", + " einstein_aepas = []\n", + " \n", + " if status == \"Pre Divisions\":\n", + " random.shuffle(champ_team_nums)\n", + " division_1 = champ_team_nums[:78]\n", + " division_2 = champ_team_nums[78:156]\n", + " division_3 = champ_team_nums[156:233]\n", + " division_4 = champ_team_nums[233:310]\n", + " division_5 = champ_team_nums[310:388]\n", + " division_6 = champ_team_nums[388:466]\n", + " division_7 = champ_team_nums[466:543]\n", + " division_8 = champ_team_nums[543:620]\n", + " curr_divisions = [division_1, division_2, division_3, division_4, division_5, division_6, division_7, division_8]\n", + " else:\n", + " curr_divisions = divisions\n", + " \n", + " for division, matches, ranks in zip(curr_divisions, division_matches, division_ranks):\n", + " random.shuffle(division)\n", + " \n", + " if status == \"Final\":\n", + " schedule = matches\n", + " else:\n", + " schedule = get_schedule(len(division), 10)\n", + " schedule = [\n", + " {\n", + " \"red\": [division[x - 1] for x in m[\"red\"]],\n", + " \"blue\": [division[x - 1] for x in m[\"blue\"]],\n", + " }\n", + " for m in schedule\n", + " ]\n", + " \n", + " if status != \"Post Quals\":\n", + " qual_ranks = sim_single_quals(division, schedule, curr_team_to_epa, curr_team_to_rp_1_epa, curr_team_to_rp_2_epa)\n", + " else:\n", + " qual_ranks = ranks\n", + " \n", + " for i, t in enumerate(qual_ranks):\n", + " qual_rank_list[t][i] += 1\n", + "\n", + " alliances, aepas = sim_alliance_selection(qual_ranks, curr_team_to_epa)\n", + " for alliance in alliances:\n", + " pairs[frozenset((alliance[0], alliance[1]))] += 1\n", + " \n", + " winner, finalist, third_place, fourth_place = sim_single_elims(alliances, curr_team_to_epa)\n", + " einstein_alliances.append(alliances[winner])\n", + " einstein_aepas.append(aepas[winner])\n", + "\n", + " einstein_pairs[frozenset((alliances[winner][0], alliances[winner][1]))] += 1\n", + "\n", + " winner_alliances[winner] += 1\n", + " best_epa = max(aepas)\n", + " winner_epa = aepas[winner]\n", + " winner_best_epas.append(best_epa == winner_epa)\n", + " alliance_epas.extend(aepas)\n", + " best_epas.append(best_epa)\n", + " winner_epas.append(winner_epa)\n", + "\n", + " for t in alliances[winner]:\n", + " winner_count[t] += 1\n", + "\n", + " for t in alliances[finalist]:\n", + " finalist_count[t] += 1\n", + "\n", + " for t in alliances[third_place]:\n", + " third_place_count[t] += 1\n", + "\n", + " for t in alliances[fourth_place]:\n", + " fourth_place_count[t] += 1\n", + "\n", + " winner, finalist, third_place, fourth_place = sim_single_elims(einstein_alliances, curr_team_to_epa)\n", + " einstein_winner[winner] += 1\n", + " einstein_finalist[finalist] += 1\n", + " einstein_third[third_place] += 1\n", + " einstein_fourth[fourth_place] += 1\n", + "\n", + " winning_pairs[frozenset((einstein_alliances[winner][0], einstein_alliances[winner][1]))] += 1\n", + "\n", + " einstein_best_epa = max(einstein_aepas)\n", + " einstein_winner_epa = einstein_aepas[winner]\n", + " einstein_winner_best_epas.append(einstein_best_epa == einstein_winner_epa)\n", + " einstein_alliance_epas.extend(einstein_aepas)\n", + " einstein_best_epas.append(einstein_best_epa)\n", + " einstein_winner_epas.append(einstein_winner_epa)\n", + "\n", + " for t in einstein_alliances[winner]:\n", + " overall_winner_count[t] += 1\n", + "\n", + " for t in einstein_alliances[finalist]:\n", + " overall_finalist_count[t] += 1\n", + "\n", + " for t in einstein_alliances[third_place]:\n", + " overall_third_place_count[t] += 1\n", + "\n", + " for t in einstein_alliances[fourth_place]:\n", + " overall_fourth_place_count[t] += 1\n", + " \n", + " avg_ranks = {t: sum(((i + 1) * qual_rank_list[t][i]) for i in range(78)) / num_sims for t in qual_rank_list}\n", + " top_1 = {t: sum(qual_rank_list[t][i] for i in range(1)) / num_sims for t in qual_rank_list}\n", + " top_4 = {t: sum(qual_rank_list[t][i] for i in range(4)) / num_sims for t in qual_rank_list}\n", + " top_8 = {t: sum(qual_rank_list[t][i] for i in range(8)) / num_sims for t in qual_rank_list}\n", + " top_16 = {t: sum(qual_rank_list[t][i] for i in range(16)) / num_sims for t in qual_rank_list}\n", + " \n", + " return {\n", + " \"overall_winner_count\": overall_winner_count,\n", + " \"overall_finalist_count\": overall_finalist_count,\n", + " \"overall_third_place_count\": overall_third_place_count,\n", + " \"overall_fourth_place_count\": overall_fourth_place_count,\n", + " \"winner_count\": winner_count,\n", + " \"finalist_count\": finalist_count,\n", + " \"third_place_count\": third_place_count,\n", + " \"fourth_place_count\": fourth_place_count,\n", + " \"winner_alliances\": winner_alliances,\n", + " \"winner_best_epas\": winner_best_epas,\n", + " \"alliance_epas\": alliance_epas,\n", + " \"best_epas\": best_epas,\n", + " \"winner_epas\": winner_epas,\n", + " \"einstein_winner_best_epas\": einstein_winner_best_epas,\n", + " \"einstein_alliance_epas\": einstein_alliance_epas,\n", + " \"einstein_best_epas\": einstein_best_epas,\n", + " \"einstein_winner_epas\": einstein_winner_epas,\n", + " \"einstein_winner\": einstein_winner,\n", + " \"einstein_finalist\": einstein_finalist,\n", + " \"einstein_third\": einstein_third,\n", + " \"einstein_fourth\": einstein_fourth,\n", + " \"pairs\": pairs,\n", + " \"einstein_pairs\": einstein_pairs,\n", + " \"winning_pairs\": winning_pairs,\n", + " \"qual_rank_list\": qual_rank_list,\n", + " \"avg_ranks\": avg_ranks,\n", + " \"top_1\": top_1,\n", + " \"top_4\": top_4,\n", + " \"top_8\": top_8,\n", + " \"top_16\": top_16,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "01332858", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n", + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n" + ] + } + ], + "source": [ + "post_quals = run_simulation(\"Post Quals\", 100000)\n", + "final = run_simulation(\"Final\", 100000)\n", + "after = run_simulation(\"Pre Schedule\", 100000)\n", + "before = run_simulation(\"Pre Divisions\", 100000)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "991e8ce8", + "metadata": {}, + "outputs": [], + "source": [ + "num_sims = 100000" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "1d053d42", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "

Chance of winning Einstein

\n", + "\n", + "| Division | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| --- | :-: | :-: | :-: | :-: |\n", + "| Archimedes|12.67%|51.32%|51.76%|56.09%|\n", + "| Curie|12.65%|3.79%|3.58%|8.05%|\n", + "| Daly|12.31%|2.56%|2.33%|2.71%|\n", + "| Galileo|12.7%|13.04%|14.86%|9.47%|\n", + "| Hopper|12.6%|12.25%|12.24%|15.14%|\n", + "| Johnson|12.55%|5.38%|4.65%|2.04%|\n", + "| Milstein|12.4%|8.1%|7.84%|3.89%|\n", + "| Newton|12.11%|3.57%|2.74%|2.61%|\n", + "\n", + "\n", + "

Chance of Ranking High

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Mean Rank | Pre-Schedule Mean Rank | Post-Schedule Mean Rank | Post-Quals Mean Rank |\n", + "| --- | --- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|4.54|5.88|4.3|1.0 |\n", + "| 2|5940|Curie|10.09|8.64|10.04|1.0 |\n", + "| 3|5472|Daly|19.74|20.32|11.17|1.0 |\n", + "| 4|1678|Galileo|7.03|6.92|2.14|1.0 |\n", + "| 5|1323|Hopper|4.9|4.27|3.76|1.0 |\n", + "| 6|2075|Johnson|17.62|16.5|8.08|1.0 |\n", + "| 7|2539|Milstein|12.23|12.57|6.67|1.0 |\n", + "| 8|4143|Newton|21.16|19.01|5.43|1.0 |\n", + "| 9|118|Archimedes|13.14|16.3|10.58|2.0 |\n", + "| 10|1756|Curie|16.12|14.68|11.38|2.0 |\n", + "| 11|2767|Daly|12.63|12.8|7.6|2.0 |\n", + "| 12|1114|Galileo|19.45|20.22|10.43|2.0 |\n", + "| 13|4265|Hopper|27.99|24.96|22.55|2.0 |\n", + "| 14|1730|Johnson|27.49|26.8|25.49|2.0 |\n", + "| 15|3655|Milstein|22.8|23.96|15.17|2.0 |\n", + "| 16|3940|Newton|25.94|23.48|6.06|2.0 |\n", + "| 17|2607|Archimedes|27.49|30.56|10.88|3.0 |\n", + "| 18|6329|Curie|14.13|12.26|11.82|3.0 |\n", + "| 19|3314|Daly|17.15|17.52|13.63|3.0 |\n", + "| 20|103|Galileo|25.95|27.14|28.83|3.0 |\n", + "| 21|2338|Hopper|11.44|10.0|4.88|3.0 |\n", + "| 22|3175|Johnson|12.99|11.78|7.67|3.0 |\n", + "| 23|3937|Milstein|22.41|23.39|8.65|3.0 |\n", + "| 24|4329|Newton|34.5|32.92|15.51|3.0 |\n", + "| 25|254|Archimedes|6.84|8.49|7.78|4.0 |\n", + "\n", + "\n", + "See Statbotics event pages for individual event simulations\n", + "\n", + "

Chance of winning division

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|67.08%|61.08%|62.36%|76.44%|\n", + "| 2|1323|Hopper|57.29%|57.46%|58.12%|65.69%|\n", + "| 3|254|Archimedes|54.62%|47.37%|47.63%|61.29%|\n", + "| 4|5940|Curie|29.27%|35.44%|34.0%|60.07%|\n", + "| 5|1678|Galileo|39.54%|39.88%|50.31%|50.46%|\n", + "| 6|4143|Newton|10.61%|11.88%|17.63%|42.54%|\n", + "| 7|3005|Galileo|35.86%|36.77%|39.52%|35.72%|\n", + "| 8|3538|Newton|28.56%|35.42%|28.53%|32.23%|\n", + "| 9|2539|Milstein|17.14%|16.71%|20.19%|32.1%|\n", + "| 10|1756|Curie|14.39%|18.16%|18.26%|30.41%|\n", + "| 11|2767|Daly|15.85%|19.6%|21.43%|29.54%|\n", + "| 12|2075|Johnson|12.67%|14.0%|16.95%|28.97%|\n", + "| 13|930|Milstein|24.27%|23.18%|20.14%|23.84%|\n", + "| 14|6329|Curie|13.98%|17.66%|17.0%|22.1%|\n", + "| 15|3476|Galileo|11.67%|10.55%|10.82%|21.23%|\n", + "| 16|1987|Hopper|19.75%|20.82%|17.79%|19.68%|\n", + "| 17|1325|Daly|12.31%|15.45%|14.12%|19.52%|\n", + "| 18|2046|Hopper|11.34%|9.68%|8.6%|19.21%|\n", + "| 19|2363|Daly|12.99%|16.75%|15.1%|17.91%|\n", + "| 20|7157|Johnson|22.09%|26.38%|21.65%|17.5%|\n", + "| 21|51|Johnson|11.63%|12.57%|14.61%|17.45%|\n", + "| 22|3314|Daly|11.47%|14.26%|14.47%|17.28%|\n", + "| 23|3655|Milstein|10.67%|11.04%|11.28%|17.22%|\n", + "| 24|1731|Daly|7.58%|8.07%|8.17%|15.67%|\n", + "| 25|3175|Johnson|12.47%|14.49%|16.09%|15.57%|\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|67.08%|61.08%|62.36%|76.44%|\n", + "| 2|254|Archimedes|54.62%|47.37%|47.63%|61.29%|\n", + "| 3|111|Archimedes|30.02%|17.07%|16.41%|14.85%|\n", + "| 4|6036|Archimedes|27.55%|14.88%|12.59%|10.98%|\n", + "| 5|118|Archimedes|11.87%|8.42%|7.44%|10.68%|\n", + "| 6|33|Archimedes|10.86%|8.92%|8.68%|10.56%|\n", + "| 7|4476|Archimedes|9.19%|8.82%|9.33%|10.41%|\n", + "| 8|1768|Archimedes|8.77%|8.3%|9.13%|10.37%|\n", + "| 9|6328|Archimedes|11.13%|8.34%|8.4%|10.28%|\n", + "| 10|3015|Archimedes|11.79%|8.0%|8.21%|10.18%|\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|5940|Curie|29.27%|35.44%|34.0%|60.07%|\n", + "| 2|1756|Curie|14.39%|18.16%|18.26%|30.41%|\n", + "| 3|6329|Curie|13.98%|17.66%|17.0%|22.1%|\n", + "| 4|4738|Curie|8.07%|8.27%|8.05%|11.98%|\n", + "| 5|5727|Curie|4.36%|4.58%|4.71%|11.94%|\n", + "| 6|180|Curie|10.37%|11.56%|10.68%|10.85%|\n", + "| 7|1771|Curie|8.99%|9.59%|9.59%|10.39%|\n", + "| 8|302|Curie|10.31%|11.31%|10.92%|10.35%|\n", + "| 9|4003|Curie|8.09%|8.38%|8.76%|10.19%|\n", + "| 10|1868|Curie|9.88%|10.4%|10.39%|10.14%|\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2767|Daly|15.85%|19.6%|21.43%|29.54%|\n", + "| 2|1325|Daly|12.31%|15.45%|14.12%|19.52%|\n", + "| 3|2363|Daly|12.99%|16.75%|15.1%|17.91%|\n", + "| 4|3314|Daly|11.47%|14.26%|14.47%|17.28%|\n", + "| 5|1731|Daly|7.58%|8.07%|8.17%|15.67%|\n", + "| 6|695|Daly|11.15%|13.52%|12.96%|12.45%|\n", + "| 7|5472|Daly|10.36%|11.7%|12.25%|12.18%|\n", + "| 8|4272|Daly|7.34%|7.17%|7.22%|11.84%|\n", + "| 9|125|Daly|10.24%|11.65%|11.69%|11.61%|\n", + "| 10|3641|Daly|10.9%|13.05%|13.13%|11.3%|\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|1678|Galileo|39.54%|39.88%|50.31%|50.46%|\n", + "| 2|3005|Galileo|35.86%|36.77%|39.52%|35.72%|\n", + "| 3|3476|Galileo|11.67%|10.55%|10.82%|21.23%|\n", + "| 4|1114|Galileo|10.79%|10.55%|9.47%|14.72%|\n", + "| 5|2910|Galileo|18.81%|17.28%|13.54%|12.89%|\n", + "| 6|3467|Galileo|17.68%|15.66%|16.4%|10.41%|\n", + "| 7|5166|Galileo|9.17%|8.46%|8.55%|10.11%|\n", + "| 8|67|Galileo|10.93%|10.25%|10.01%|10.1%|\n", + "| 9|461|Galileo|12.07%|10.8%|10.12%|10.03%|\n", + "| 10|59|Galileo|4.03%|2.97%|2.71%|10.0%|\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|1323|Hopper|57.29%|57.46%|58.12%|65.69%|\n", + "| 2|1987|Hopper|19.75%|20.82%|17.79%|19.68%|\n", + "| 3|2046|Hopper|11.34%|9.68%|8.6%|19.21%|\n", + "| 4|2338|Hopper|18.89%|19.63%|25.45%|15.07%|\n", + "| 5|4414|Hopper|16.79%|15.9%|13.81%|14.86%|\n", + "| 6|1796|Hopper|9.88%|9.33%|10.08%|12.7%|\n", + "| 7|2481|Hopper|11.28%|9.2%|8.72%|12.61%|\n", + "| 8|4336|Hopper|8.91%|10.66%|10.03%|12.07%|\n", + "| 9|341|Hopper|11.97%|9.61%|9.1%|11.39%|\n", + "| 10|7407|Hopper|9.7%|9.4%|10.13%|11.34%|\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2075|Johnson|12.67%|14.0%|16.95%|28.97%|\n", + "| 2|7157|Johnson|22.09%|26.38%|21.65%|17.5%|\n", + "| 3|51|Johnson|11.63%|12.57%|14.61%|17.45%|\n", + "| 4|3175|Johnson|12.47%|14.49%|16.09%|15.57%|\n", + "| 5|973|Johnson|10.52%|11.08%|10.36%|15.19%|\n", + "| 6|4499|Johnson|15.28%|18.08%|16.68%|14.78%|\n", + "| 7|1730|Johnson|6.47%|6.71%|6.72%|13.01%|\n", + "| 8|971|Johnson|26.95%|31.97%|30.01%|12.65%|\n", + "| 9|2521|Johnson|10.35%|11.15%|10.15%|12.23%|\n", + "| 10|1718|Johnson|12.23%|12.91%|14.67%|12.14%|\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2539|Milstein|17.14%|16.71%|20.19%|32.1%|\n", + "| 2|930|Milstein|24.27%|23.18%|20.14%|23.84%|\n", + "| 3|3655|Milstein|10.67%|11.04%|11.28%|17.22%|\n", + "| 4|3937|Milstein|10.76%|11.13%|11.7%|15.57%|\n", + "| 5|176|Milstein|17.83%|17.21%|15.62%|15.04%|\n", + "| 6|319|Milstein|10.44%|10.68%|10.96%|14.85%|\n", + "| 7|604|Milstein|13.87%|13.61%|14.59%|13.86%|\n", + "| 8|3683|Milstein|16.88%|16.6%|16.02%|12.5%|\n", + "| 9|6672|Milstein|22.39%|22.12%|23.7%|12.48%|\n", + "| 10|1923|Milstein|10.43%|10.61%|10.88%|11.97%|\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|4143|Newton|10.61%|11.88%|17.63%|42.54%|\n", + "| 2|3538|Newton|28.56%|35.42%|28.53%|32.23%|\n", + "| 3|1538|Newton|14.2%|17.75%|15.33%|15.34%|\n", + "| 4|4522|Newton|13.4%|16.48%|14.02%|14.72%|\n", + "| 5|195|Newton|19.06%|24.83%|22.86%|12.25%|\n", + "| 6|3039|Newton|6.43%|7.06%|7.3%|12.05%|\n", + "| 7|3184|Newton|11.8%|13.68%|13.8%|11.0%|\n", + "| 8|3940|Newton|5.9%|6.68%|7.56%|10.64%|\n", + "| 9|177|Newton|10.47%|11.27%|11.74%|10.38%|\n", + "| 10|7285|Newton|10.49%|11.32%|11.78%|10.11%|\n", + "\n", + "[/details]\n", + "\n", + "

Chance of winning Einstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|30.84%|39.66%|40.78%|51.68% |\n", + "| 2|254|Archimedes|18.65%|30.34%|30.46%|41.39% |\n", + "| 3|1323|Hopper|20.7%|10.86%|10.86%|14.26% |\n", + "| 4|1678|Galileo|9.31%|8.35%|11.62%|7.69% |\n", + "| 5|5940|Curie|5.16%|2.5%|2.2%|7.47% |\n", + "| 6|111|Archimedes|5.41%|8.02%|7.69%|6.68% |\n", + "| 7|4476|Archimedes|0.98%|4.42%|4.8%|5.89% |\n", + "| 8|6328|Archimedes|1.07%|3.81%|3.98%|5.88% |\n", + "| 9|33|Archimedes|1.06%|4.18%|4.23%|5.87% |\n", + "| 10|1768|Archimedes|0.93%|4.07%|4.72%|5.82% |\n", + "| 11|3015|Archimedes|1.08%|3.42%|3.81%|5.75% |\n", + "| 12|972|Archimedes|0.96%|4.1%|4.51%|5.63% |\n", + "| 13|7211|Archimedes|1.0%|4.25%|4.85%|5.4% |\n", + "| 14|1189|Archimedes|1.04%|4.31%|5.0%|5.36% |\n", + "| 15|70|Archimedes|0.93%|4.3%|5.09%|5.35% |\n", + "| 16|3005|Galileo|7.84%|7.5%|9.07%|5.21% |\n", + "| 17|6002|Archimedes|1.05%|4.55%|4.49%|5.02% |\n", + "| 18|6036|Archimedes|4.64%|6.77%|5.48%|4.72% |\n", + "| 19|4903|Archimedes|0.94%|4.04%|4.26%|4.38% |\n", + "| 20|4362|Archimedes|0.97%|4.18%|4.86%|4.34% |\n", + "| 21|5232|Archimedes|1.0%|4.36%|4.81%|4.03% |\n", + "| 22|3061|Archimedes|0.24%|0.72%|0.91%|3.6% |\n", + "| 23|1987|Hopper|2.4%|2.91%|2.27%|3.56% |\n", + "| 24|324|Archimedes|0.53%|1.84%|2.05%|3.46% |\n", + "| 25|27|Archimedes|1.0%|4.39%|3.39%|3.41% |\n", + "\n", + "[details='By Division']\n", + "

Archimedes

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2056|Archimedes|30.84%|39.66%|40.78%|51.68% |\n", + "| 2|254|Archimedes|18.65%|30.34%|30.46%|41.39% |\n", + "| 3|111|Archimedes|5.41%|8.02%|7.69%|6.68% |\n", + "| 4|4476|Archimedes|0.98%|4.42%|4.8%|5.89% |\n", + "| 5|6328|Archimedes|1.07%|3.81%|3.98%|5.88% |\n", + "| 6|33|Archimedes|1.06%|4.18%|4.23%|5.87% |\n", + "| 7|1768|Archimedes|0.93%|4.07%|4.72%|5.82% |\n", + "| 8|3015|Archimedes|1.08%|3.42%|3.81%|5.75% |\n", + "| 9|972|Archimedes|0.96%|4.1%|4.51%|5.63% |\n", + "| 10|7211|Archimedes|1.0%|4.25%|4.85%|5.4% |\n", + "\n", + "

Curie

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|5940|Curie|5.16%|2.5%|2.2%|7.47% |\n", + "| 2|1756|Curie|1.33%|0.77%|0.77%|3.25% |\n", + "| 3|6329|Curie|1.28%|0.76%|0.68%|1.92% |\n", + "| 4|5727|Curie|0.41%|0.13%|0.16%|0.85% |\n", + "| 5|180|Curie|1.03%|0.38%|0.36%|0.74% |\n", + "| 6|302|Curie|0.99%|0.35%|0.31%|0.74% |\n", + "| 7|7021|Curie|0.98%|0.38%|0.35%|0.74% |\n", + "| 8|4270|Curie|1.03%|0.43%|0.34%|0.71% |\n", + "| 9|1868|Curie|1.07%|0.37%|0.35%|0.71% |\n", + "| 10|1100|Curie|0.4%|0.11%|0.13%|0.7% |\n", + "\n", + "

Daly

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2767|Daly|1.58%|0.73%|0.78%|1.41% |\n", + "| 2|1325|Daly|1.15%|0.46%|0.37%|0.73% |\n", + "| 3|2363|Daly|1.14%|0.52%|0.37%|0.6% |\n", + "| 4|3314|Daly|1.03%|0.35%|0.36%|0.51% |\n", + "| 5|1731|Daly|0.75%|0.18%|0.18%|0.37% |\n", + "| 6|695|Daly|1.0%|0.38%|0.27%|0.34% |\n", + "| 7|4272|Daly|0.81%|0.17%|0.14%|0.32% |\n", + "| 8|230|Daly|1.03%|0.43%|0.34%|0.3% |\n", + "| 9|125|Daly|1.02%|0.28%|0.24%|0.29% |\n", + "| 10|6424|Daly|1.0%|0.33%|0.33%|0.29% |\n", + "\n", + "

Galileo

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|1678|Galileo|9.31%|8.35%|11.62%|7.69% |\n", + "| 2|3005|Galileo|7.84%|7.5%|9.07%|5.21% |\n", + "| 3|3476|Galileo|1.08%|1.04%|1.0%|1.97% |\n", + "| 4|2910|Galileo|2.21%|2.18%|1.65%|1.06% |\n", + "| 5|8033|Galileo|0.99%|1.04%|1.31%|0.95% |\n", + "| 6|1318|Galileo|0.93%|0.98%|1.3%|0.92% |\n", + "| 7|5166|Galileo|1.06%|1.02%|1.24%|0.91% |\n", + "| 8|5987|Galileo|1.07%|1.1%|1.38%|0.9% |\n", + "| 9|2337|Galileo|1.17%|1.17%|1.14%|0.9% |\n", + "| 10|59|Galileo|0.4%|0.35%|0.36%|0.89% |\n", + "\n", + "

Hopper

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|1323|Hopper|20.7%|10.86%|10.86%|14.26% |\n", + "| 2|1987|Hopper|2.4%|2.91%|2.27%|3.56% |\n", + "| 3|2046|Hopper|0.94%|0.83%|0.81%|2.95% |\n", + "| 4|4414|Hopper|1.78%|1.93%|1.52%|2.28% |\n", + "| 5|1796|Hopper|1.01%|0.96%|1.08%|2.0% |\n", + "| 6|4336|Hopper|0.95%|1.23%|1.13%|1.84% |\n", + "| 7|7407|Hopper|0.99%|1.0%|1.17%|1.81% |\n", + "| 8|341|Hopper|1.1%|0.8%|0.74%|1.74% |\n", + "| 9|2481|Hopper|1.05%|0.83%|0.78%|1.73% |\n", + "| 10|245|Hopper|0.96%|0.99%|1.28%|1.73% |\n", + "\n", + "

Johnson

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2075|Johnson|1.12%|0.71%|0.84%|1.12% |\n", + "| 2|7157|Johnson|2.99%|2.13%|1.33%|0.49% |\n", + "| 3|51|Johnson|1.03%|0.55%|0.64%|0.41% |\n", + "| 4|4499|Johnson|1.53%|1.11%|0.85%|0.31% |\n", + "| 5|3175|Johnson|1.13%|0.7%|0.77%|0.3% |\n", + "| 6|973|Johnson|1.0%|0.49%|0.4%|0.29% |\n", + "| 7|2521|Johnson|0.98%|0.49%|0.38%|0.26% |\n", + "| 8|971|Johnson|4.6%|2.91%|2.22%|0.25% |\n", + "| 9|4607|Johnson|1.01%|0.42%|0.4%|0.21% |\n", + "| 10|6045|Johnson|0.96%|0.44%|0.34%|0.21% |\n", + "\n", + "

Milstein

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|2539|Milstein|1.81%|1.46%|1.96%|2.23% |\n", + "| 2|930|Milstein|3.46%|2.6%|2.08%|1.42% |\n", + "| 3|176|Milstein|1.93%|1.6%|1.27%|0.6% |\n", + "| 4|3655|Milstein|1.02%|0.82%|0.8%|0.57% |\n", + "| 5|604|Milstein|1.26%|1.01%|1.1%|0.52% |\n", + "| 6|6672|Milstein|3.13%|2.52%|2.8%|0.48% |\n", + "| 7|3937|Milstein|1.0%|0.84%|0.72%|0.47% |\n", + "| 8|3683|Milstein|1.89%|1.53%|1.45%|0.47% |\n", + "| 9|694|Milstein|1.17%|1.02%|0.98%|0.45% |\n", + "| 10|1923|Milstein|1.08%|0.76%|0.81%|0.45% |\n", + "\n", + "

Newton

\n", + "\n", + "| Rank | Team            | Division        | Pre-Divisions Winner | Pre-Schedule Winner | Post-Schedule Winner | Post-Quals Winner |\n", + "| ---- | ---- | --- | :-: | :-: | :-: | :-: |\n", + "| 1|4143|Newton|1.01%|0.32%|0.5%|2.13% |\n", + "| 2|3538|Newton|4.83%|2.27%|1.41%|1.54% |\n", + "| 3|1538|Newton|1.37%|0.71%|0.43%|0.34% |\n", + "| 4|4522|Newton|1.19%|0.61%|0.36%|0.31% |\n", + "| 5|1757|Newton|1.06%|0.45%|0.31%|0.26% |\n", + "| 6|195|Newton|2.37%|1.39%|1.0%|0.25% |\n", + "| 7|1468|Newton|1.07%|0.32%|0.25%|0.24% |\n", + "| 8|8592|Newton|1.01%|0.29%|0.29%|0.24% |\n", + "| 9|179|Newton|1.0%|0.28%|0.27%|0.24% |\n", + "| 10|7285|Newton|1.06%|0.31%|0.29%|0.23% |\n", + "\n", + "[/details]\n", + "\n", + "

Most likely pairings

\n", + "\n", + "| Rank | Division        | Team 1          | Team 2          | On Alliance     | Win Division    | Win Einstein    |\n", + "| --- | --- | --- | --- | :-: | :-: | :-: |\n", + "| 1|Archimedes|2056|254|69.81%|56.55%|40.03%\n", + "| 2|Archimedes|2056|111|11.54%|8.22%|5.1%\n", + "| 3|Galileo|3005|1678|45.61%|26.81%|4.73%\n", + "| 4|Archimedes|2056|6036|9.27%|6.42%|3.84%\n", + "| 5|Hopper|1323|1987|18.73%|13.33%|3.31%\n", + "| 6|Curie|5940|1756|27.32%|18.87%|2.98%\n", + "| 7|Hopper|1323|2046|16.1%|11.21%|2.68%\n", + "| 8|Hopper|1323|4414|13.16%|9.01%|2.0%\n", + "| 9|Curie|5940|6329|17.84%|11.79%|1.68%\n", + "| 10|Hopper|1323|2481|10.43%|7.03%|1.58%\n", + "| 11|Newton|3538|4143|48.64%|24.48%|1.45%\n", + "| 12|Hopper|1323|2338|9.84%|6.66%|1.44%\n", + "| 13|Galileo|1678|3476|17.06%|8.97%|1.36%\n", + "| 14|Archimedes|2056|2468|3.49%|2.2%|1.25%\n", + "| 15|Archimedes|254|118|19.02%|3.62%|1.1%\n", + "| 16|Milstein|930|2539|29.49%|11.84%|1.02%\n", + "| 17|Hopper|1323|4391|5.93%|3.78%|0.76%\n", + "| 18|Hopper|1323|4265|5.41%|3.45%|0.69%\n", + "| 19|Archimedes|111|118|27.2%|2.71%|0.66%\n", + "| 20|Galileo|1678|2910|9.06%|4.35%|0.6%\n", + "| 21|Curie|5940|4738|6.92%|4.2%|0.49%\n", + "| 22|Archimedes|6036|118|23.13%|2.11%|0.48%\n", + "| 23|Archimedes|2056|1577|1.5%|0.87%|0.46%\n", + "| 24|Curie|5940|5727|6.52%|3.88%|0.46%\n", + "| 25|Daly|2767|1325|18.94%|7.16%|0.42%\n" + ] + } + ], + "source": [ + "def pad(s, length = 15):\n", + " return s + \" \" * (length - len(s))\n", + "\n", + "def percent(x):\n", + " return str(round(100 * x, 2)) + \"%\"\n", + "\n", + "division_names = [\"Archimedes\", \"Curie\", \"Daly\", \"Galileo\", \"Hopper\", \"Johnson\", \"Milstein\", \"Newton\"]\n", + "division_to_team = {}\n", + "for i, division in enumerate(divisions):\n", + " for t in division:\n", + " division_to_team[t] = division_names[i]\n", + "\n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print(\"| Division | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" | \", pad(\"Post-Quals Winner\"), \" |\")\n", + "print(\"| --- | :-: | :-: | :-: | :-: |\")\n", + "for i in range(8):\n", + " print(\"|\", \"|\".join([division_names[i], percent(before[\"einstein_winner\"][i] / num_sims), percent(after[\"einstein_winner\"][i] / num_sims), percent(final[\"einstein_winner\"][i] / num_sims), percent(post_quals[\"einstein_winner\"][i] / num_sims)]) + \"|\")\n", + "print()\n", + "print()\n", + "\n", + "def print_ranks(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Mean Rank\"), \" | \", pad(\"Pre-Schedule Mean Rank\"), \" | \", pad(\"Post-Schedule Mean Rank\"), \" | \", pad(\"Post-Quals Mean Rank\"), \" |\")\n", + " print(\"| --- | --- | --- | :-: | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(post_quals[\"avg_ranks\"].items(), key=lambda x: (filter(x[0]), x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], str(round(before[\"avg_ranks\"][key], 2)), str(round(after[\"avg_ranks\"][key], 2)), str(round(final[\"avg_ranks\"][key], 2)), str(round(post_quals[\"avg_ranks\"][key], 2))]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of Ranking High

\")\n", + "print()\n", + " \n", + "print_ranks()\n", + "\n", + "print()\n", + "print(\"See Statbotics event pages for individual event simulations\")\n", + "print()\n", + "\n", + "\n", + "def print_divisions(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" | \", pad(\"Post-Quals Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(post_quals[\"winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"winner_count\"][key] / num_sims), percent(after[\"winner_count\"][key] / num_sims), percent(final[\"winner_count\"][key] / num_sims), percent(post_quals[\"winner_count\"][key] / num_sims)]) + \"|\")\n", + " print()\n", + "\n", + "print(\"

Chance of winning division

\")\n", + "print()\n", + " \n", + "print_divisions()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_divisions(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "def print_einstein(filter=lambda x: True, limit=25):\n", + " print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Division\"), \" | \", pad(\"Pre-Divisions Winner\"), \" | \", pad(\"Pre-Schedule Winner\"), \" | \", pad(\"Post-Schedule Winner\"), \" | \", pad(\"Post-Quals Winner\"), \" |\")\n", + " print(\"| ---- | ---- | --- | :-: | :-: | :-: | :-: |\")\n", + " for i, (key, _) in enumerate(sorted(post_quals[\"overall_winner_count\"].items(), key=lambda x: (filter(x[0]), -x[1]))[:limit]):\n", + " print(\"|\", \"|\".join([str(i + 1), str(key), division_to_team[key], percent(before[\"overall_winner_count\"][key] / num_sims), percent(after[\"overall_winner_count\"][key] / num_sims), percent(final[\"overall_winner_count\"][key] / num_sims), percent(post_quals[\"overall_winner_count\"][key] / num_sims)]), \"|\")\n", + " print()\n", + " \n", + "print(\"

Chance of winning Einstein

\")\n", + "print()\n", + " \n", + "print_einstein()\n", + "\n", + "print(\"[details='By Division']\")\n", + "\n", + "for i in range(8):\n", + " print(\"

\" + division_names[i] + \"

\")\n", + " print()\n", + " print_einstein(filter=lambda x: 0 if x in divisions[i] else 1, limit=10)\n", + " \n", + "print(\"[/details]\")\n", + "print()\n", + " \n", + "print(\"

Most likely pairings

\")\n", + "print()\n", + "\n", + "print(\"| Rank | \", pad(\"Division\"), \"|\", pad(\"Team 1\"), \"|\", pad(\"Team 2\"), \"|\", pad(\"On Alliance\"), \"|\", pad(\"Win Division\"), \"|\", pad(\"Win Einstein\"), \"|\")\n", + "print(\"| --- | --- | --- | --- | :-: | :-: | :-: |\")\n", + "for i, (key, _) in enumerate(sorted(post_quals[\"winning_pairs\"].items(), key=lambda x: -x[1])[:25]):\n", + " key_list = sorted(list(key), key=lambda x: -team_to_epa[x])\n", + " print(\"|\", \"|\".join([str(i + 1), division_to_team[key_list[0]], str(key_list[0]), str(key_list[1]), percent(post_quals[\"pairs\"][key] / num_sims), percent(post_quals[\"einstein_pairs\"][key] / num_sims), percent(post_quals[\"winning_pairs\"][key] / num_sims)]))\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77b67391", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/scripts/2023/Simulate Champs.ipynb b/scripts/2023/Simulate Champs.ipynb new file mode 100644 index 00000000..4934dcab --- /dev/null +++ b/scripts/2023/Simulate Champs.ipynb @@ -0,0 +1,2064 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 191, + "id": "b698f107", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "from functools import lru_cache\n", + "import random\n", + "import requests\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import statbotics\n", + "\n", + "%matplotlib notebook\n", + "\n", + "sb = statbotics.Statbotics()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "4568bf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3286" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_teams = sb.get_team_years(year=2023, limit=10000)\n", + "all_teams_dict = {t[\"team\"]: t for t in all_teams}\n", + "len(all_teams)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "e2046e7e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "620\n" + ] + } + ], + "source": [ + "champ_teams = sb.get_team_events(event=\"2023cmptx\", limit=10000)\n", + "champ_team_nums = [t[\"team\"] for t in champ_teams]\n", + "champ_team_nums += [333, 449, 999, 2170, 2337, 4779, 4976, 5123, 7174, 7534, 8013, 9152, 9244]\n", + "\n", + "print(len(set(champ_team_nums)))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "b4529072", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "84.85 0.9931 0.5175\n" + ] + } + ], + "source": [ + "team_to_epa = {t: all_teams_dict[t][\"epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_1_epa = {t: all_teams_dict[t][\"rp_1_epa_end\"] for t in champ_team_nums}\n", + "team_to_rp_2_epa = {t: all_teams_dict[t][\"rp_2_epa_end\"] for t in champ_team_nums}\n", + "\n", + "print(team_to_epa[2056], team_to_rp_1_epa[2056], team_to_rp_2_epa[2056])" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "38d2a765", + "metadata": {}, + "outputs": [], + "source": [ + "TOTAL_MEAN = 74.57\n", + "TOTAL_SD = 29.36" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "811dfb7e", + "metadata": {}, + "outputs": [], + "source": [ + "@lru_cache\n", + "def make_request(url):\n", + " response = requests.get(url)\n", + " response.raise_for_status()\n", + " data = response.text\n", + " lines = data.split(\"\\n\")\n", + " return lines\n", + "\n", + "@lru_cache\n", + "def get_schedule(num_teams: int, num_matches: int):\n", + " # TODO: remove this once we have pre-generated schedules for 100+ teams\n", + " if num_teams > 100:\n", + " schedule1 = get_schedule(100, num_matches)\n", + " schedule2 = get_schedule(num_teams - 100, num_matches)\n", + " schedule2 = [\n", + " {\"red\": [team + 100 for team in match[\"red\"]], \"blue\": [team + 100 for team in match[\"blue\"]]}\n", + " for match in schedule2\n", + " ]\n", + " return schedule1 + schedule2\n", + "\n", + " # load csv from external URL using requests\n", + " lines = make_request(f\"https://raw.githubusercontent.com/Team254/cheesy-arena/main/schedules/{num_teams}_{num_matches}.csv\")\n", + " \n", + " schedule = []\n", + " for line in lines:\n", + " match = line.split(\",\")\n", + " if len(match) < 12:\n", + " continue\n", + " red = [int(match[0]), int(match[2]), int(match[4])]\n", + " blue = [int(match[6]), int(match[8]), int(match[10])]\n", + " schedule.append({\"red\": red, \"blue\": blue})\n", + " \n", + " return schedule" + ] + }, + { + "cell_type": "code", + "execution_count": 381, + "id": "c2233c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def get_win_prob(a, b):\n", + " return 1 / (1 + 10 ** (((-5 / 8) * (a - b)) / TOTAL_SD))\n", + "\n", + "def get_rp_pred(a):\n", + " return 1 / (1 + np.e ** (-4 * (a - 0.5)))\n", + "\n", + "def sim_single_quals(teams, schedule):\n", + " curr_sim_matches = {t: 0 for t in teams}\n", + " curr_sim_rps = {t: 0 for t in teams}\n", + " for m in schedule:\n", + " red_epa = sum(team_to_epa[x] for x in m[\"red\"])\n", + " blue_epa = sum(team_to_epa[x] for x in m[\"blue\"])\n", + " red_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"red\"])\n", + " blue_rp_1_epa = sum(team_to_rp_1_epa[x] for x in m[\"blue\"])\n", + " red_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"red\"])\n", + " blue_rp_2_epa = sum(team_to_rp_2_epa[x] for x in m[\"blue\"])\n", + " \n", + " win_prob = get_win_prob(red_epa, blue_epa)\n", + " red_win = 1 if random.random() < win_prob else 0\n", + "\n", + " red_rp_1_prob = get_rp_pred(0.9 * red_rp_1_epa)\n", + " red_rp_1 = 1 if random.random() < red_rp_1_prob else 0\n", + " \n", + " red_rp_2_prob = get_rp_pred(red_rp_2_epa)\n", + " red_rp_2 = 1 if random.random() < red_rp_2_prob else 0\n", + " \n", + " blue_rp_1_prob = get_rp_pred(0.9 * blue_rp_1_epa)\n", + " blue_rp_1 = 1 if random.random() < blue_rp_1_prob else 0\n", + " \n", + " blue_rp_2_prob = get_rp_pred(blue_rp_2_epa)\n", + " blue_rp_2 = 1 if random.random() < blue_rp_2_prob else 0\n", + "\n", + " red_rps = red_rp_1 + red_rp_2 + (2 if red_win else 0)\n", + " blue_rps = blue_rp_1 + blue_rp_2 + (0 if red_win else 2)\n", + " \n", + " for x in m[\"red\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += red_rps\n", + " \n", + " for x in m[\"blue\"]:\n", + " curr_sim_matches[x] += 1\n", + " if curr_sim_matches[x] <= 10:\n", + " curr_sim_rps[x] += blue_rps\n", + " \n", + " curr_sim_ranks = sorted(curr_sim_rps.items(), key=lambda x: [-x[1], random.random()])\n", + " \n", + " return [x[0] for x in curr_sim_ranks]\n", + "\n", + "def softmax_select(options, mult=1):\n", + " exp = [np.e ** (mult * o) for o in options]\n", + " sum_exp = sum(exp)\n", + " exp = [e / sum_exp for e in exp]\n", + " rand = random.random()\n", + " curr, i = 0, 0\n", + " while curr < rand:\n", + " curr += exp[i]\n", + " i += 1\n", + " return i - 1\n", + "\n", + "def sim_alliance_selection(ranks):\n", + " alliances = [[], [], [], [], [], [], [], []]\n", + " locked_teams = []\n", + " remaining_teams = [(r, team_to_epa[r]) for r in ranks]\n", + " \n", + " r1_mult = 1 / 3\n", + " r2_mult = 1 / 2\n", + " \n", + " def handle_selection(selector, reject=True):\n", + " selected = None\n", + " while selected is None:\n", + " temp_remaining_teams = [r for r in remaining_teams if r not in locked_teams]\n", + " _selected = softmax_select([r[1] for r in temp_remaining_teams], r1_mult)\n", + " _selected_team = temp_remaining_teams[_selected]\n", + " orig_rank = ranks.index(_selected_team[0]) + 1\n", + " if not reject or orig_rank > 8:\n", + " selected = _selected\n", + " continue\n", + " \n", + " selected_rank = remaining_teams.index(_selected_team) + 1\n", + " remaining_best_epas = sorted(temp_remaining_teams[_selected + 1:], key=lambda x: -x[1])\n", + " if remaining_best_epas[selected_rank][1] > selector[1] + 5:\n", + " locked_teams.append(_selected_team)\n", + " else:\n", + " selected = _selected\n", + " \n", + " return remaining_teams.index(temp_remaining_teams[selected])\n", + " \n", + " # Captain and Round 1\n", + " alliances[0].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[1].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[2].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[3].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + "\n", + " alliances[4].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[5].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[6].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " \n", + " alliances[7].append(remaining_teams.pop(0))\n", + " selected = handle_selection(alliances[0][0])\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 2\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " \n", + " # Round 3\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[0].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[1].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[2].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[3].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[4].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[5].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[6].append(remaining_teams.pop(selected))\n", + " selected = softmax_select([r[1] for r in remaining_teams], r2_mult)\n", + " alliances[7].append(remaining_teams.pop(selected))\n", + " \n", + " aepas = [sum(a[1] for a in alliance[:3]) for alliance in alliances]\n", + " return [[a[0] for a in alliance] for alliance in alliances], aepas\n", + "\n", + "def sim_single_elims(alliances):\n", + " aepas = [sum(team_to_epa[a] for a in alliance[:3]) for alliance in alliances]\n", + " ms = [[0, 7], [3, 4], [1, 6], [2, 5], [], [], [], [], [], [], [], [], []]\n", + " \n", + " def _get_win_prob(i):\n", + " return get_win_prob(aepas[ms[i][0]], aepas[ms[i][1]])\n", + "\n", + " m1_red_winner = random.random() < _get_win_prob(0)\n", + " ms[4].append(ms[0][1] if m1_red_winner else ms[0][0])\n", + " ms[6].append(ms[0][0] if m1_red_winner else ms[0][1])\n", + " \n", + " m2_red_winner = random.random() < _get_win_prob(1)\n", + " ms[4].append(ms[1][1] if m2_red_winner else ms[1][0])\n", + " ms[6].append(ms[1][0] if m2_red_winner else ms[1][1])\n", + " \n", + " m3_red_winner = random.random() < _get_win_prob(2)\n", + " ms[5].append(ms[2][1] if m3_red_winner else ms[2][0])\n", + " ms[7].append(ms[2][0] if m3_red_winner else ms[2][1])\n", + " \n", + " m4_red_winner = random.random() < _get_win_prob(3)\n", + " ms[5].append(ms[3][1] if m4_red_winner else ms[3][0])\n", + " ms[7].append(ms[3][0] if m4_red_winner else ms[3][1])\n", + " \n", + " m5_red_winner = random.random() < _get_win_prob(4)\n", + " ms[9].append(ms[4][0] if m5_red_winner else ms[4][1])\n", + " \n", + " m6_red_winner = random.random() < _get_win_prob(5)\n", + " ms[8].append(ms[5][0] if m6_red_winner else ms[5][1])\n", + " \n", + " m7_red_winner = random.random() < _get_win_prob(6)\n", + " ms[8].append(ms[6][1] if m7_red_winner else ms[6][0])\n", + " ms[10].append(ms[6][0] if m7_red_winner else ms[6][1])\n", + " \n", + " m8_red_winner = random.random() < _get_win_prob(7)\n", + " ms[9].append(ms[7][1] if m8_red_winner else ms[7][0])\n", + " ms[10].append(ms[7][0] if m8_red_winner else ms[7][1])\n", + " \n", + " m9_red_winner = random.random() < _get_win_prob(8)\n", + " ms[11].append(ms[8][0] if m9_red_winner else ms[8][1])\n", + " \n", + " m10_red_winner = random.random() < _get_win_prob(9)\n", + " ms[11].append(ms[9][0] if m10_red_winner else ms[9][1])\n", + " \n", + " m11_red_winner = random.random() < _get_win_prob(10)\n", + " ms[12].append(ms[10][1] if m11_red_winner else ms[10][0])\n", + " finalist_1 = ms[10][0] if m11_red_winner else ms[10][1]\n", + " \n", + " m12_red_winner = random.random() < _get_win_prob(11)\n", + " fourth_place = ms[11][1] if m12_red_winner else ms[11][0]\n", + " ms[12].append(ms[11][0] if m12_red_winner else ms[11][1])\n", + " \n", + " m13_red_winner = random.random() < _get_win_prob(12)\n", + " third_place = ms[12][1] if m13_red_winner else ms[12][0]\n", + " finalist_2 = ms[12][0] if m13_red_winner else ms[12][1]\n", + " \n", + " \n", + " f1_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f2_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " f3_red_winner = random.random() < get_win_prob(aepas[finalist_1], aepas[finalist_2])\n", + " winner = finalist_1 if f1_red_winner + f2_red_winner + f3_red_winner >= 2 else finalist_2\n", + " second_place = finalist_2 if winner == finalist_1 else finalist_1\n", + " \n", + " return winner, second_place, third_place, fourth_place\n" + ] + }, + { + "cell_type": "code", + "execution_count": 383, + "id": "62276690", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "100\n", + "200\n", + "300\n", + "400\n", + "500\n", + "600\n", + "700\n", + "800\n", + "900\n", + "1000\n", + "1100\n", + "1200\n", + "1300\n", + "1400\n", + "1500\n", + "1600\n", + "1700\n", + "1800\n", + "1900\n", + "2000\n", + "2100\n", + "2200\n", + "2300\n", + "2400\n", + "2500\n", + "2600\n", + "2700\n", + "2800\n", + "2900\n", + "3000\n", + "3100\n", + "3200\n", + "3300\n", + "3400\n", + "3500\n", + "3600\n", + "3700\n", + "3800\n", + "3900\n", + "4000\n", + "4100\n", + "4200\n", + "4300\n", + "4400\n", + "4500\n", + "4600\n", + "4700\n", + "4800\n", + "4900\n", + "5000\n", + "5100\n", + "5200\n", + "5300\n", + "5400\n", + "5500\n", + "5600\n", + "5700\n", + "5800\n", + "5900\n", + "6000\n", + "6100\n", + "6200\n", + "6300\n", + "6400\n", + "6500\n", + "6600\n", + "6700\n", + "6800\n", + "6900\n", + "7000\n", + "7100\n", + "7200\n", + "7300\n", + "7400\n", + "7500\n", + "7600\n", + "7700\n", + "7800\n", + "7900\n", + "8000\n", + "8100\n", + "8200\n", + "8300\n", + "8400\n", + "8500\n", + "8600\n", + "8700\n", + "8800\n", + "8900\n", + "9000\n", + "9100\n", + "9200\n", + "9300\n", + "9400\n", + "9500\n", + "9600\n", + "9700\n", + "9800\n", + "9900\n", + "10000\n", + "10100\n", + "10200\n", + "10300\n", + "10400\n", + "10500\n", + "10600\n", + "10700\n", + "10800\n", + "10900\n", + "11000\n", + "11100\n", + "11200\n", + "11300\n", + "11400\n", + "11500\n", + "11600\n", + "11700\n", + "11800\n", + "11900\n", + "12000\n", + "12100\n", + "12200\n", + "12300\n", + "12400\n", + "12500\n", + "12600\n", + "12700\n", + "12800\n", + "12900\n", + "13000\n", + "13100\n", + "13200\n", + "13300\n", + "13400\n", + "13500\n", + "13600\n", + "13700\n", + "13800\n", + "13900\n", + "14000\n", + "14100\n", + "14200\n", + "14300\n", + "14400\n", + "14500\n", + "14600\n", + "14700\n", + "14800\n", + "14900\n", + "15000\n", + "15100\n", + "15200\n", + "15300\n", + "15400\n", + "15500\n", + "15600\n", + "15700\n", + "15800\n", + "15900\n", + "16000\n", + "16100\n", + "16200\n", + "16300\n", + "16400\n", + "16500\n", + "16600\n", + "16700\n", + "16800\n", + "16900\n", + "17000\n", + "17100\n", + "17200\n", + "17300\n", + "17400\n", + "17500\n", + "17600\n", + "17700\n", + "17800\n", + "17900\n", + "18000\n", + "18100\n", + "18200\n", + "18300\n", + "18400\n", + "18500\n", + "18600\n", + "18700\n", + "18800\n", + "18900\n", + "19000\n", + "19100\n", + "19200\n", + "19300\n", + "19400\n", + "19500\n", + "19600\n", + "19700\n", + "19800\n", + "19900\n", + "20000\n", + "20100\n", + "20200\n", + "20300\n", + "20400\n", + "20500\n", + "20600\n", + "20700\n", + "20800\n", + "20900\n", + "21000\n", + "21100\n", + "21200\n", + "21300\n", + "21400\n", + "21500\n", + "21600\n", + "21700\n", + "21800\n", + "21900\n", + "22000\n", + "22100\n", + "22200\n", + "22300\n", + "22400\n", + "22500\n", + "22600\n", + "22700\n", + "22800\n", + "22900\n", + "23000\n", + "23100\n", + "23200\n", + "23300\n", + "23400\n", + "23500\n", + "23600\n", + "23700\n", + "23800\n", + "23900\n", + "24000\n", + "24100\n", + "24200\n", + "24300\n", + "24400\n", + "24500\n", + "24600\n", + "24700\n", + "24800\n", + "24900\n", + "25000\n", + "25100\n", + "25200\n", + "25300\n", + "25400\n", + "25500\n", + "25600\n", + "25700\n", + "25800\n", + "25900\n", + "26000\n", + "26100\n", + "26200\n", + "26300\n", + "26400\n", + "26500\n", + "26600\n", + "26700\n", + "26800\n", + "26900\n", + "27000\n", + "27100\n", + "27200\n", + "27300\n", + "27400\n", + "27500\n", + "27600\n", + "27700\n", + "27800\n", + "27900\n", + "28000\n", + "28100\n", + "28200\n", + "28300\n", + "28400\n", + "28500\n", + "28600\n", + "28700\n", + "28800\n", + "28900\n", + "29000\n", + "29100\n", + "29200\n", + "29300\n", + "29400\n", + "29500\n", + "29600\n", + "29700\n", + "29800\n", + "29900\n", + "30000\n", + "30100\n", + "30200\n", + "30300\n", + "30400\n", + "30500\n", + "30600\n", + "30700\n", + "30800\n", + "30900\n", + "31000\n", + "31100\n", + "31200\n", + "31300\n", + "31400\n", + "31500\n", + "31600\n", + "31700\n", + "31800\n", + "31900\n", + "32000\n", + "32100\n", + "32200\n", + "32300\n", + "32400\n", + "32500\n", + "32600\n", + "32700\n", + "32800\n", + "32900\n", + "33000\n", + "33100\n", + "33200\n", + "33300\n", + "33400\n", + "33500\n", + "33600\n", + "33700\n", + "33800\n", + "33900\n", + "34000\n", + "34100\n", + "34200\n", + "34300\n", + "34400\n", + "34500\n", + "34600\n", + "34700\n", + "34800\n", + "34900\n", + "35000\n", + "35100\n", + "35200\n", + "35300\n", + "35400\n", + "35500\n", + "35600\n", + "35700\n", + "35800\n", + "35900\n", + "36000\n", + "36100\n", + "36200\n", + "36300\n", + "36400\n", + "36500\n", + "36600\n", + "36700\n", + "36800\n", + "36900\n", + "37000\n", + "37100\n", + "37200\n", + "37300\n", + "37400\n", + "37500\n", + "37600\n", + "37700\n", + "37800\n", + "37900\n", + "38000\n", + "38100\n", + "38200\n", + "38300\n", + "38400\n", + "38500\n", + "38600\n", + "38700\n", + "38800\n", + "38900\n", + "39000\n", + "39100\n", + "39200\n", + "39300\n", + "39400\n", + "39500\n", + "39600\n", + "39700\n", + "39800\n", + "39900\n", + "40000\n", + "40100\n", + "40200\n", + "40300\n", + "40400\n", + "40500\n", + "40600\n", + "40700\n", + "40800\n", + "40900\n", + "41000\n", + "41100\n", + "41200\n", + "41300\n", + "41400\n", + "41500\n", + "41600\n", + "41700\n", + "41800\n", + "41900\n", + "42000\n", + "42100\n", + "42200\n", + "42300\n", + "42400\n", + "42500\n", + "42600\n", + "42700\n", + "42800\n", + "42900\n", + "43000\n", + "43100\n", + "43200\n", + "43300\n", + "43400\n", + "43500\n", + "43600\n", + "43700\n", + "43800\n", + "43900\n", + "44000\n", + "44100\n", + "44200\n", + "44300\n", + "44400\n", + "44500\n", + "44600\n", + "44700\n", + "44800\n", + "44900\n", + "45000\n", + "45100\n", + "45200\n", + "45300\n", + "45400\n", + "45500\n", + "45600\n", + "45700\n", + "45800\n", + "45900\n", + "46000\n", + "46100\n", + "46200\n", + "46300\n", + "46400\n", + "46500\n", + "46600\n", + "46700\n", + "46800\n", + "46900\n", + "47000\n", + "47100\n", + "47200\n", + "47300\n", + "47400\n", + "47500\n", + "47600\n", + "47700\n", + "47800\n", + "47900\n", + "48000\n", + "48100\n", + "48200\n", + "48300\n", + "48400\n", + "48500\n", + "48600\n", + "48700\n", + "48800\n", + "48900\n", + "49000\n", + "49100\n", + "49200\n", + "49300\n", + "49400\n", + "49500\n", + "49600\n", + "49700\n", + "49800\n", + "49900\n", + "50000\n", + "50100\n", + "50200\n", + "50300\n", + "50400\n", + "50500\n", + "50600\n", + "50700\n", + "50800\n", + "50900\n", + "51000\n", + "51100\n", + "51200\n", + "51300\n", + "51400\n", + "51500\n", + "51600\n", + "51700\n", + "51800\n", + "51900\n", + "52000\n", + "52100\n", + "52200\n", + "52300\n", + "52400\n", + "52500\n", + "52600\n", + "52700\n", + "52800\n", + "52900\n", + "53000\n", + "53100\n", + "53200\n", + "53300\n", + "53400\n", + "53500\n", + "53600\n", + "53700\n", + "53800\n", + "53900\n", + "54000\n", + "54100\n", + "54200\n", + "54300\n", + "54400\n", + "54500\n", + "54600\n", + "54700\n", + "54800\n", + "54900\n", + "55000\n", + "55100\n", + "55200\n", + "55300\n", + "55400\n", + "55500\n", + "55600\n", + "55700\n", + "55800\n", + "55900\n", + "56000\n", + "56100\n", + "56200\n", + "56300\n", + "56400\n", + "56500\n", + "56600\n", + "56700\n", + "56800\n", + "56900\n", + "57000\n", + "57100\n", + "57200\n", + "57300\n", + "57400\n", + "57500\n", + "57600\n", + "57700\n", + "57800\n", + "57900\n", + "58000\n", + "58100\n", + "58200\n", + "58300\n", + "58400\n", + "58500\n", + "58600\n", + "58700\n", + "58800\n", + "58900\n", + "59000\n", + "59100\n", + "59200\n", + "59300\n", + "59400\n", + "59500\n", + "59600\n", + "59700\n", + "59800\n", + "59900\n", + "60000\n", + "60100\n", + "60200\n", + "60300\n", + "60400\n", + "60500\n", + "60600\n", + "60700\n", + "60800\n", + "60900\n", + "61000\n", + "61100\n", + "61200\n", + "61300\n", + "61400\n", + "61500\n", + "61600\n", + "61700\n", + "61800\n", + "61900\n", + "62000\n", + "62100\n", + "62200\n", + "62300\n", + "62400\n", + "62500\n", + "62600\n", + "62700\n", + "62800\n", + "62900\n", + "63000\n", + "63100\n", + "63200\n", + "63300\n", + "63400\n", + "63500\n", + "63600\n", + "63700\n", + "63800\n", + "63900\n", + "64000\n", + "64100\n", + "64200\n", + "64300\n", + "64400\n", + "64500\n", + "64600\n", + "64700\n", + "64800\n", + "64900\n", + "65000\n", + "65100\n", + "65200\n", + "65300\n", + "65400\n", + "65500\n", + "65600\n", + "65700\n", + "65800\n", + "65900\n", + "66000\n", + "66100\n", + "66200\n", + "66300\n", + "66400\n", + "66500\n", + "66600\n", + "66700\n", + "66800\n", + "66900\n", + "67000\n", + "67100\n", + "67200\n", + "67300\n", + "67400\n", + "67500\n", + "67600\n", + "67700\n", + "67800\n", + "67900\n", + "68000\n", + "68100\n", + "68200\n", + "68300\n", + "68400\n", + "68500\n", + "68600\n", + "68700\n", + "68800\n", + "68900\n", + "69000\n", + "69100\n", + "69200\n", + "69300\n", + "69400\n", + "69500\n", + "69600\n", + "69700\n", + "69800\n", + "69900\n", + "70000\n", + "70100\n", + "70200\n", + "70300\n", + "70400\n", + "70500\n", + "70600\n", + "70700\n", + "70800\n", + "70900\n", + "71000\n", + "71100\n", + "71200\n", + "71300\n", + "71400\n", + "71500\n", + "71600\n", + "71700\n", + "71800\n", + "71900\n", + "72000\n", + "72100\n", + "72200\n", + "72300\n", + "72400\n", + "72500\n", + "72600\n", + "72700\n", + "72800\n", + "72900\n", + "73000\n", + "73100\n", + "73200\n", + "73300\n", + "73400\n", + "73500\n", + "73600\n", + "73700\n", + "73800\n", + "73900\n", + "74000\n", + "74100\n", + "74200\n", + "74300\n", + "74400\n", + "74500\n", + "74600\n", + "74700\n", + "74800\n", + "74900\n", + "75000\n", + "75100\n", + "75200\n", + "75300\n", + "75400\n", + "75500\n", + "75600\n", + "75700\n", + "75800\n", + "75900\n", + "76000\n", + "76100\n", + "76200\n", + "76300\n", + "76400\n", + "76500\n", + "76600\n", + "76700\n", + "76800\n", + "76900\n", + "77000\n", + "77100\n", + "77200\n", + "77300\n", + "77400\n", + "77500\n", + "77600\n", + "77700\n", + "77800\n", + "77900\n", + "78000\n", + "78100\n", + "78200\n", + "78300\n", + "78400\n", + "78500\n", + "78600\n", + "78700\n", + "78800\n", + "78900\n", + "79000\n", + "79100\n", + "79200\n", + "79300\n", + "79400\n", + "79500\n", + "79600\n", + "79700\n", + "79800\n", + "79900\n", + "80000\n", + "80100\n", + "80200\n", + "80300\n", + "80400\n", + "80500\n", + "80600\n", + "80700\n", + "80800\n", + "80900\n", + "81000\n", + "81100\n", + "81200\n", + "81300\n", + "81400\n", + "81500\n", + "81600\n", + "81700\n", + "81800\n", + "81900\n", + "82000\n", + "82100\n", + "82200\n", + "82300\n", + "82400\n", + "82500\n", + "82600\n", + "82700\n", + "82800\n", + "82900\n", + "83000\n", + "83100\n", + "83200\n", + "83300\n", + "83400\n", + "83500\n", + "83600\n", + "83700\n", + "83800\n", + "83900\n", + "84000\n", + "84100\n", + "84200\n", + "84300\n", + "84400\n", + "84500\n", + "84600\n", + "84700\n", + "84800\n", + "84900\n", + "85000\n", + "85100\n", + "85200\n", + "85300\n", + "85400\n", + "85500\n", + "85600\n", + "85700\n", + "85800\n", + "85900\n", + "86000\n", + "86100\n", + "86200\n", + "86300\n", + "86400\n", + "86500\n", + "86600\n", + "86700\n", + "86800\n", + "86900\n", + "87000\n", + "87100\n", + "87200\n", + "87300\n", + "87400\n", + "87500\n", + "87600\n", + "87700\n", + "87800\n", + "87900\n", + "88000\n", + "88100\n", + "88200\n", + "88300\n", + "88400\n", + "88500\n", + "88600\n", + "88700\n", + "88800\n", + "88900\n", + "89000\n", + "89100\n", + "89200\n", + "89300\n", + "89400\n", + "89500\n", + "89600\n", + "89700\n", + "89800\n", + "89900\n", + "90000\n", + "90100\n", + "90200\n", + "90300\n", + "90400\n", + "90500\n", + "90600\n", + "90700\n", + "90800\n", + "90900\n", + "91000\n", + "91100\n", + "91200\n", + "91300\n", + "91400\n", + "91500\n", + "91600\n", + "91700\n", + "91800\n", + "91900\n", + "92000\n", + "92100\n", + "92200\n", + "92300\n", + "92400\n", + "92500\n", + "92600\n", + "92700\n", + "92800\n", + "92900\n", + "93000\n", + "93100\n", + "93200\n", + "93300\n", + "93400\n", + "93500\n", + "93600\n", + "93700\n", + "93800\n", + "93900\n", + "94000\n", + "94100\n", + "94200\n", + "94300\n", + "94400\n", + "94500\n", + "94600\n", + "94700\n", + "94800\n", + "94900\n", + "95000\n", + "95100\n", + "95200\n", + "95300\n", + "95400\n", + "95500\n", + "95600\n", + "95700\n", + "95800\n", + "95900\n", + "96000\n", + "96100\n", + "96200\n", + "96300\n", + "96400\n", + "96500\n", + "96600\n", + "96700\n", + "96800\n", + "96900\n", + "97000\n", + "97100\n", + "97200\n", + "97300\n", + "97400\n", + "97500\n", + "97600\n", + "97700\n", + "97800\n", + "97900\n", + "98000\n", + "98100\n", + "98200\n", + "98300\n", + "98400\n", + "98500\n", + "98600\n", + "98700\n", + "98800\n", + "98900\n", + "99000\n", + "99100\n", + "99200\n", + "99300\n", + "99400\n", + "99500\n", + "99600\n", + "99700\n", + "99800\n", + "99900\n" + ] + } + ], + "source": [ + "overall_winner_count = defaultdict(int)\n", + "overall_finalist_count = defaultdict(int)\n", + "overall_third_place_count = defaultdict(int)\n", + "overall_fourth_place_count = defaultdict(int)\n", + "\n", + "winner_count = defaultdict(int)\n", + "finalist_count = defaultdict(int)\n", + "third_place_count = defaultdict(int)\n", + "fourth_place_count = defaultdict(int)\n", + "\n", + "winner_alliances = defaultdict(int)\n", + "winner_best_epas = []\n", + "alliance_epas = []\n", + "best_epas = []\n", + "winner_epas = []\n", + "\n", + "einstein_winner_best_epas = []\n", + "einstein_alliance_epas = []\n", + "einstein_best_epas = []\n", + "einstein_winner_epas = []\n", + "\n", + "qual_rank_list = defaultdict(lambda: [0] * 78)\n", + "\n", + "num_sims = 100000\n", + "\n", + "def pre_sim(all_teams):\n", + " for sim in range(num_sims):\n", + " if sim % 100 == 0:\n", + " print(sim)\n", + " \n", + " random.shuffle(all_teams)\n", + "\n", + " division_1 = all_teams[:78]\n", + " division_2 = all_teams[78:156]\n", + " division_3 = all_teams[156:233]\n", + " division_4 = all_teams[233:310]\n", + " division_5 = all_teams[310:388]\n", + " division_6 = all_teams[388:466]\n", + " division_7 = all_teams[466:543]\n", + " division_8 = all_teams[543:620]\n", + "\n", + " divisions = [division_1, division_2, division_3, division_4, division_5, division_6, division_7, division_8]\n", + "\n", + " einstein_alliances = []\n", + " einstein_aepas = []\n", + " for division in divisions:\n", + " random.shuffle(division)\n", + " schedule = get_schedule(len(division), 10)\n", + " schedule = [\n", + " {\n", + " \"red\": [division[x - 1] for x in m[\"red\"]],\n", + " \"blue\": [division[x - 1] for x in m[\"blue\"]],\n", + " }\n", + " for m in schedule\n", + " ]\n", + " qual_ranks = sim_single_quals(division, schedule)\n", + " for i, t in enumerate(qual_ranks):\n", + " qual_rank_list[t][i] += 1\n", + " \n", + " alliances, aepas = sim_alliance_selection(qual_ranks)\n", + " winner, finalist, third_place, fourth_place = sim_single_elims(alliances)\n", + " einstein_alliances.append(alliances[winner])\n", + " einstein_aepas.append(aepas[winner])\n", + " \n", + " winner_alliances[winner] += 1\n", + " best_epa = max(aepas)\n", + " winner_epa = aepas[winner]\n", + " winner_best_epas.append(best_epa == winner_epa)\n", + " alliance_epas.extend(aepas)\n", + " best_epas.append(best_epa)\n", + " winner_epas.append(winner_epa)\n", + " \n", + " for t in alliances[winner]:\n", + " winner_count[t] += 1\n", + " \n", + " for t in alliances[finalist]:\n", + " finalist_count[t] += 1\n", + " \n", + " for t in alliances[third_place]:\n", + " third_place_count[t] += 1\n", + " \n", + " for t in alliances[fourth_place]:\n", + " fourth_place_count[t] += 1\n", + " \n", + " winner, finalist, third_place, fourth_place = sim_single_elims(einstein_alliances)\n", + "\n", + " einstein_best_epa = max(einstein_aepas)\n", + " einstein_winner_epa = einstein_aepas[winner]\n", + " einstein_winner_best_epas.append(einstein_best_epa == einstein_winner_epa)\n", + " einstein_alliance_epas.extend(einstein_aepas)\n", + " einstein_best_epas.append(einstein_best_epa)\n", + " einstein_winner_epas.append(einstein_winner_epa)\n", + "\n", + " for t in einstein_alliances[winner]:\n", + " overall_winner_count[t] += 1\n", + " \n", + " for t in einstein_alliances[finalist]:\n", + " overall_finalist_count[t] += 1\n", + " \n", + " for t in einstein_alliances[third_place]:\n", + " overall_third_place_count[t] += 1\n", + " \n", + " for t in einstein_alliances[fourth_place]:\n", + " overall_fourth_place_count[t] += 1\n", + " \n", + "pre_sim(champ_team_nums)" + ] + }, + { + "cell_type": "code", + "execution_count": 406, + "id": "1d053d42", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Division\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 67.4% | 11.7% | 7.0% | 4.8% |\n", + "| 2 | 1323 | 58.5% | 14.0% | 9.0% | 6.0% |\n", + "| 3 | 254 | 58.0% | 14.3% | 9.0% | 6.1% |\n", + "| 4 | 1678 | 41.5% | 16.9% | 11.9% | 8.8% |\n", + "| 5 | 3005 | 38.6% | 17.1% | 12.4% | 9.2% |\n", + "| 6 | 111 | 32.0% | 17.5% | 13.2% | 10.3% |\n", + "| 7 | 971 | 31.7% | 17.3% | 13.1% | 10.5% |\n", + "| 8 | 3538 | 30.9% | 17.5% | 13.3% | 10.5% |\n", + "| 9 | 5940 | 30.2% | 17.6% | 13.3% | 10.6% |\n", + "| 10 | 6036 | 29.5% | 17.5% | 13.5% | 10.4% |\n", + "| 11 | 930 | 25.0% | 17.2% | 13.9% | 11.3% |\n", + "| 12 | 6672 | 24.5% | 17.0% | 13.8% | 11.5% |\n", + "| 13 | 7157 | 23.8% | 16.9% | 13.9% | 11.5% |\n", + "| 14 | 1987 | 21.1% | 16.5% | 13.9% | 12.1% |\n", + "| 15 | 1619 | 20.9% | 16.5% | 13.9% | 12.1% |\n", + "| 16 | 195 | 20.6% | 16.4% | 13.9% | 12.2% |\n", + "| 17 | 2910 | 19.5% | 16.1% | 14.0% | 12.3% |\n", + "| 18 | 3683 | 19.0% | 16.1% | 14.0% | 12.3% |\n", + "| 19 | 176 | 18.7% | 15.6% | 13.9% | 12.5% |\n", + "| 20 | 4028 | 18.6% | 15.9% | 13.8% | 12.4% |\n", + "| 21 | 2338 | 18.5% | 15.9% | 13.8% | 12.6% |\n", + "| 22 | 1577 | 18.3% | 15.7% | 14.0% | 12.5% |\n", + "| 23 | 3467 | 18.1% | 15.8% | 13.9% | 12.5% |\n", + "| 24 | 4414 | 17.4% | 15.8% | 14.0% | 12.7% |\n", + "| 25 | 1591 | 16.9% | 15.4% | 14.0% | 12.6% |\n", + "\n", + "Division\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 67.4% | 11.7% | 7.0% | 4.8% |\n", + "| 2 | 1323 | 58.5% | 14.0% | 9.0% | 6.0% |\n", + "| 3 | 254 | 58.0% | 14.3% | 9.0% | 6.1% |\n", + "| 4 | 1678 | 41.5% | 16.9% | 11.9% | 8.8% |\n", + "| 5 | 3005 | 38.6% | 17.1% | 12.4% | 9.2% |\n", + "| 6 | 111 | 32.0% | 17.5% | 13.2% | 10.3% |\n", + "| 7 | 971 | 31.7% | 17.3% | 13.1% | 10.5% |\n", + "| 8 | 3538 | 30.9% | 17.5% | 13.3% | 10.5% |\n", + "| 9 | 5940 | 30.2% | 17.6% | 13.3% | 10.6% |\n", + "| 10 | 6036 | 29.5% | 17.5% | 13.5% | 10.4% |\n", + "| 11 | 930 | 25.0% | 17.2% | 13.9% | 11.3% |\n", + "| 12 | 6672 | 24.5% | 17.0% | 13.8% | 11.5% |\n", + "| 13 | 7157 | 23.8% | 16.9% | 13.9% | 11.5% |\n", + "| 14 | 1987 | 21.1% | 16.5% | 13.9% | 12.1% |\n", + "| 15 | 1619 | 20.9% | 16.5% | 13.9% | 12.1% |\n", + "| 16 | 195 | 20.6% | 16.4% | 13.9% | 12.2% |\n", + "| 17 | 2910 | 19.5% | 16.1% | 14.0% | 12.3% |\n", + "| 18 | 3683 | 19.0% | 16.1% | 14.0% | 12.3% |\n", + "| 19 | 176 | 18.7% | 15.6% | 13.9% | 12.5% |\n", + "| 20 | 4028 | 18.6% | 15.9% | 13.8% | 12.4% |\n", + "| 21 | 2338 | 18.5% | 15.9% | 13.8% | 12.6% |\n", + "| 22 | 1577 | 18.3% | 15.7% | 14.0% | 12.5% |\n", + "| 23 | 3467 | 18.1% | 15.8% | 13.9% | 12.5% |\n", + "| 24 | 4414 | 17.4% | 15.8% | 14.0% | 12.7% |\n", + "| 25 | 1591 | 16.9% | 15.4% | 14.0% | 12.6% |\n", + "| 26 | 2539 | 16.3% | 15.3% | 14.0% | 12.9% |\n", + "| 27 | 4499 | 15.8% | 14.9% | 13.8% | 12.9% |\n", + "| 28 | 359 | 15.4% | 15.0% | 13.7% | 13.0% |\n", + "| 29 | 2468 | 15.3% | 14.9% | 14.0% | 12.8% |\n", + "| 30 | 1706 | 15.0% | 14.9% | 13.9% | 12.9% |\n", + "| 31 | 2767 | 15.0% | 14.9% | 13.9% | 13.0% |\n", + "| 32 | 7890 | 14.6% | 14.5% | 13.4% | 13.1% |\n", + "| 33 | 6090 | 14.6% | 14.7% | 13.7% | 13.1% |\n", + "| 34 | 987 | 14.2% | 14.9% | 13.7% | 13.1% |\n", + "| 35 | 2687 | 13.8% | 14.2% | 13.5% | 13.1% |\n", + "| 36 | 5913 | 13.7% | 14.3% | 13.7% | 12.9% |\n", + "| 37 | 1756 | 13.4% | 14.1% | 13.5% | 13.0% |\n", + "| 38 | 4907 | 13.4% | 14.2% | 13.7% | 13.0% |\n", + "| 39 | 1727 | 13.2% | 14.1% | 13.6% | 13.1% |\n", + "| 40 | 1538 | 13.2% | 14.4% | 13.5% | 13.1% |\n", + "| 41 | 604 | 12.9% | 13.9% | 13.4% | 13.0% |\n", + "| 42 | 4522 | 12.7% | 14.0% | 13.5% | 12.8% |\n", + "| 43 | 6329 | 12.5% | 14.0% | 13.3% | 13.1% |\n", + "| 44 | 4381 | 12.4% | 14.0% | 13.3% | 13.2% |\n", + "| 45 | 694 | 12.4% | 14.1% | 13.4% | 13.2% |\n", + "| 46 | 148 | 12.3% | 13.6% | 13.3% | 13.1% |\n", + "| 47 | 179 | 12.2% | 12.3% | 12.3% | 12.2% |\n", + "| 48 | 3847 | 12.2% | 12.3% | 12.5% | 12.4% |\n", + "| 49 | 70 | 12.1% | 12.2% | 12.4% | 12.2% |\n", + "| 50 | 4635 | 12.1% | 12.2% | 12.2% | 12.2% |\n", + "| 51 | 2930 | 12.1% | 12.2% | 12.6% | 12.5% |\n", + "| 52 | 5460 | 12.1% | 12.1% | 12.2% | 12.6% |\n", + "| 53 | 4607 | 12.1% | 11.8% | 12.0% | 11.8% |\n", + "| 54 | 2337 | 12.1% | 13.8% | 13.5% | 13.2% |\n", + "| 55 | 1868 | 12.1% | 12.3% | 12.4% | 12.4% |\n", + "| 56 | 2883 | 12.0% | 12.2% | 12.1% | 12.4% |\n", + "| 57 | 5166 | 12.0% | 12.1% | 12.2% | 12.2% |\n", + "| 58 | 2363 | 12.0% | 13.8% | 13.4% | 13.4% |\n", + "| 59 | 1468 | 12.0% | 11.6% | 11.9% | 11.9% |\n", + "| 60 | 4336 | 12.0% | 11.7% | 11.8% | 12.0% |\n", + "| 61 | 3668 | 12.0% | 12.1% | 12.4% | 12.6% |\n", + "| 62 | 876 | 12.0% | 11.8% | 12.1% | 12.1% |\n", + "| 63 | 5712 | 12.0% | 12.4% | 12.3% | 12.5% |\n", + "| 64 | 9312 | 11.9% | 12.3% | 12.4% | 12.3% |\n", + "| 65 | 4020 | 11.9% | 12.4% | 12.6% | 12.3% |\n", + "| 66 | 245 | 11.9% | 12.4% | 12.4% | 12.3% |\n", + "| 67 | 5895 | 11.9% | 13.6% | 13.4% | 13.3% |\n", + "| 68 | 1189 | 11.9% | 11.8% | 11.9% | 11.7% |\n", + "| 69 | 7211 | 11.9% | 11.8% | 12.0% | 12.0% |\n", + "| 70 | 3539 | 11.8% | 12.1% | 12.3% | 12.4% |\n", + "| 71 | 3647 | 11.8% | 12.2% | 12.4% | 12.6% |\n", + "| 72 | 1318 | 11.8% | 12.5% | 12.5% | 12.3% |\n", + "| 73 | 5804 | 11.7% | 12.4% | 12.6% | 12.6% |\n", + "| 74 | 7407 | 11.7% | 12.3% | 12.5% | 12.6% |\n", + "| 75 | 4476 | 11.7% | 12.1% | 12.2% | 12.3% |\n", + "| 76 | 5406 | 11.7% | 12.2% | 12.7% | 12.6% |\n", + "| 77 | 1771 | 11.6% | 11.9% | 12.2% | 11.9% |\n", + "| 78 | 4481 | 11.6% | 12.7% | 12.5% | 12.5% |\n", + "| 79 | 1403 | 11.6% | 12.6% | 12.4% | 12.8% |\n", + "| 80 | 862 | 11.6% | 12.3% | 12.5% | 12.7% |\n", + "| 81 | 461 | 11.5% | 13.2% | 13.3% | 13.3% |\n", + "| 82 | 5010 | 11.5% | 12.5% | 12.4% | 12.7% |\n", + "| 83 | 5232 | 11.5% | 11.7% | 11.8% | 11.9% |\n", + "| 84 | 1796 | 11.5% | 12.4% | 12.7% | 12.5% |\n", + "| 85 | 972 | 11.5% | 11.8% | 11.9% | 11.8% |\n", + "| 86 | 6919 | 11.4% | 11.7% | 12.0% | 12.0% |\n", + "| 87 | 2659 | 11.4% | 11.6% | 11.9% | 11.8% |\n", + "| 88 | 1732 | 11.3% | 12.3% | 12.5% | 12.5% |\n", + "| 89 | 1325 | 11.3% | 13.3% | 13.1% | 13.0% |\n", + "| 90 | 4362 | 11.3% | 12.5% | 12.8% | 12.8% |\n", + "| 91 | 5472 | 11.3% | 12.4% | 12.6% | 12.7% |\n", + "| 92 | 2974 | 11.3% | 12.6% | 12.6% | 12.9% |\n", + "| 93 | 3175 | 11.3% | 13.1% | 13.2% | 13.2% |\n", + "| 94 | 2075 | 11.3% | 13.3% | 13.2% | 13.3% |\n", + "| 95 | 1768 | 11.3% | 12.0% | 12.0% | 12.4% |\n", + "| 96 | 1241 | 11.3% | 12.4% | 12.7% | 12.7% |\n", + "| 97 | 6722 | 11.2% | 12.3% | 12.6% | 12.7% |\n", + "| 98 | 599 | 11.2% | 11.2% | 11.1% | 11.2% |\n", + "| 99 | 1757 | 11.2% | 13.6% | 13.3% | 13.3% |\n", + "| 100 | 3015 | 11.2% | 13.3% | 13.3% | 13.1% |\n", + "\n", + "Einstein\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 31.8% | 11.4% | 7.3% | 5.6% |\n", + "| 2 | 1323 | 21.7% | 10.7% | 7.4% | 5.9% |\n", + "| 3 | 254 | 21.2% | 10.8% | 7.4% | 5.8% |\n", + "| 4 | 1678 | 10.0% | 7.5% | 5.9% | 5.0% |\n", + "| 5 | 3005 | 8.6% | 6.9% | 5.5% | 4.7% |\n", + "| 6 | 111 | 5.9% | 5.3% | 4.6% | 4.2% |\n", + "| 7 | 971 | 5.7% | 5.3% | 4.6% | 4.1% |\n", + "| 8 | 3538 | 5.6% | 5.1% | 4.3% | 4.0% |\n", + "| 9 | 5940 | 5.2% | 5.1% | 4.4% | 4.0% |\n", + "| 10 | 6036 | 5.1% | 4.7% | 4.3% | 3.9% |\n", + "| 11 | 930 | 3.6% | 3.8% | 3.6% | 3.4% |\n", + "| 12 | 6672 | 3.3% | 3.8% | 3.5% | 3.4% |\n", + "| 13 | 7157 | 3.2% | 3.6% | 3.4% | 3.2% |\n", + "| 14 | 1619 | 2.4% | 2.9% | 3.0% | 2.8% |\n", + "| 15 | 1987 | 2.4% | 3.0% | 3.0% | 2.8% |\n", + "| 16 | 195 | 2.3% | 3.1% | 2.8% | 2.8% |\n", + "| 17 | 3683 | 2.1% | 2.6% | 2.6% | 2.6% |\n", + "| 18 | 2910 | 2.0% | 2.7% | 2.6% | 2.6% |\n", + "| 19 | 4028 | 1.9% | 2.5% | 2.6% | 2.5% |\n", + "| 20 | 1577 | 1.9% | 2.5% | 2.5% | 2.4% |\n", + "| 21 | 2338 | 1.9% | 2.4% | 2.5% | 2.6% |\n", + "| 22 | 176 | 1.9% | 2.6% | 2.5% | 2.6% |\n", + "| 23 | 3467 | 1.8% | 2.3% | 2.5% | 2.5% |\n", + "| 24 | 3847 | 1.7% | 1.5% | 1.5% | 1.5% |\n", + "| 25 | 179 | 1.6% | 1.6% | 1.5% | 1.5% |\n", + "\n", + "Einstein\n", + "| Rank | Team            | Winner          | Finalist        | 3rd Place       | 4th Place       |\n", + "| ---- | ---- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 31.8% | 11.4% | 7.3% | 5.6% |\n", + "| 2 | 1323 | 21.7% | 10.7% | 7.4% | 5.9% |\n", + "| 3 | 254 | 21.2% | 10.8% | 7.4% | 5.8% |\n", + "| 4 | 1678 | 10.0% | 7.5% | 5.9% | 5.0% |\n", + "| 5 | 3005 | 8.6% | 6.9% | 5.5% | 4.7% |\n", + "| 6 | 111 | 5.9% | 5.3% | 4.6% | 4.2% |\n", + "| 7 | 971 | 5.7% | 5.3% | 4.6% | 4.1% |\n", + "| 8 | 3538 | 5.6% | 5.1% | 4.3% | 4.0% |\n", + "| 9 | 5940 | 5.2% | 5.1% | 4.4% | 4.0% |\n", + "| 10 | 6036 | 5.1% | 4.7% | 4.3% | 3.9% |\n", + "| 11 | 930 | 3.6% | 3.8% | 3.6% | 3.4% |\n", + "| 12 | 6672 | 3.3% | 3.8% | 3.5% | 3.4% |\n", + "| 13 | 7157 | 3.2% | 3.6% | 3.4% | 3.2% |\n", + "| 14 | 1619 | 2.4% | 2.9% | 3.0% | 2.8% |\n", + "| 15 | 1987 | 2.4% | 3.0% | 3.0% | 2.8% |\n", + "| 16 | 195 | 2.3% | 3.1% | 2.8% | 2.8% |\n", + "| 17 | 3683 | 2.1% | 2.6% | 2.6% | 2.6% |\n", + "| 18 | 2910 | 2.0% | 2.7% | 2.6% | 2.6% |\n", + "| 19 | 4028 | 1.9% | 2.5% | 2.6% | 2.5% |\n", + "| 20 | 1577 | 1.9% | 2.5% | 2.5% | 2.4% |\n", + "| 21 | 2338 | 1.9% | 2.4% | 2.5% | 2.6% |\n", + "| 22 | 176 | 1.9% | 2.6% | 2.5% | 2.6% |\n", + "| 23 | 3467 | 1.8% | 2.3% | 2.5% | 2.5% |\n", + "| 24 | 3847 | 1.7% | 1.5% | 1.5% | 1.5% |\n", + "| 25 | 179 | 1.6% | 1.6% | 1.5% | 1.5% |\n", + "| 26 | 4414 | 1.6% | 2.3% | 2.4% | 2.4% |\n", + "| 27 | 1591 | 1.6% | 2.2% | 2.2% | 2.3% |\n", + "| 28 | 5460 | 1.6% | 1.5% | 1.4% | 1.5% |\n", + "| 29 | 4635 | 1.6% | 1.5% | 1.5% | 1.5% |\n", + "| 30 | 1468 | 1.6% | 1.5% | 1.6% | 1.4% |\n", + "| 31 | 2883 | 1.6% | 1.5% | 1.5% | 1.4% |\n", + "| 32 | 245 | 1.6% | 1.6% | 1.5% | 1.5% |\n", + "| 33 | 4336 | 1.6% | 1.5% | 1.5% | 1.4% |\n", + "| 34 | 5166 | 1.6% | 1.4% | 1.4% | 1.5% |\n", + "| 35 | 1868 | 1.6% | 1.6% | 1.5% | 1.4% |\n", + "| 36 | 2930 | 1.6% | 1.5% | 1.5% | 1.5% |\n", + "| 37 | 3668 | 1.6% | 1.4% | 1.5% | 1.5% |\n", + "| 38 | 70 | 1.6% | 1.5% | 1.4% | 1.5% |\n", + "| 39 | 9312 | 1.6% | 1.5% | 1.6% | 1.4% |\n", + "| 40 | 4476 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 41 | 5406 | 1.5% | 1.4% | 1.5% | 1.4% |\n", + "| 42 | 7407 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 43 | 5712 | 1.5% | 1.5% | 1.5% | 1.5% |\n", + "| 44 | 3539 | 1.5% | 1.5% | 1.5% | 1.4% |\n", + "| 45 | 3647 | 1.5% | 1.4% | 1.5% | 1.4% |\n", + "| 46 | 876 | 1.5% | 1.5% | 1.5% | 1.5% |\n", + "| 47 | 4020 | 1.5% | 1.4% | 1.4% | 1.5% |\n", + "| 48 | 1189 | 1.5% | 1.5% | 1.5% | 1.4% |\n", + "| 49 | 5804 | 1.5% | 1.5% | 1.4% | 1.5% |\n", + "| 50 | 4607 | 1.5% | 1.4% | 1.5% | 1.6% |\n", + "| 51 | 5232 | 1.5% | 1.5% | 1.4% | 1.4% |\n", + "| 52 | 4481 | 1.5% | 1.4% | 1.4% | 1.5% |\n", + "| 53 | 1732 | 1.5% | 1.4% | 1.4% | 1.4% |\n", + "| 54 | 1796 | 1.4% | 1.3% | 1.3% | 1.5% |\n", + "| 55 | 1318 | 1.4% | 1.5% | 1.4% | 1.4% |\n", + "| 56 | 972 | 1.4% | 1.4% | 1.5% | 1.4% |\n", + "| 57 | 2539 | 1.4% | 2.1% | 2.2% | 2.2% |\n", + "| 58 | 1403 | 1.4% | 1.5% | 1.4% | 1.4% |\n", + "| 59 | 599 | 1.4% | 1.4% | 1.4% | 1.3% |\n", + "| 60 | 1771 | 1.4% | 1.4% | 1.4% | 1.5% |\n", + "| 61 | 7211 | 1.4% | 1.5% | 1.4% | 1.5% |\n", + "| 62 | 5010 | 1.4% | 1.4% | 1.3% | 1.4% |\n", + "| 63 | 6045 | 1.4% | 1.3% | 1.3% | 1.4% |\n", + "| 64 | 3478 | 1.4% | 1.3% | 1.4% | 1.4% |\n", + "| 65 | 862 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 66 | 2659 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 67 | 1466 | 1.4% | 1.3% | 1.4% | 1.4% |\n", + "| 68 | 1241 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 69 | 4499 | 1.4% | 2.0% | 2.1% | 2.1% |\n", + "| 70 | 6919 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 71 | 1768 | 1.4% | 1.4% | 1.4% | 1.4% |\n", + "| 72 | 359 | 1.4% | 2.0% | 2.1% | 2.1% |\n", + "| 73 | 4373 | 1.3% | 1.4% | 1.3% | 1.5% |\n", + "| 74 | 1745 | 1.3% | 1.4% | 1.4% | 1.3% |\n", + "| 75 | 2240 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 76 | 2974 | 1.3% | 1.3% | 1.4% | 1.4% |\n", + "| 77 | 1706 | 1.3% | 1.9% | 1.9% | 2.0% |\n", + "| 78 | 4362 | 1.3% | 1.3% | 1.4% | 1.4% |\n", + "| 79 | 1690 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 80 | 8592 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 81 | 2468 | 1.3% | 1.9% | 2.1% | 2.1% |\n", + "| 82 | 5472 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 83 | 4422 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 84 | 6722 | 1.3% | 1.4% | 1.4% | 1.4% |\n", + "| 85 | 3218 | 1.3% | 1.3% | 1.4% | 1.4% |\n", + "| 86 | 316 | 1.3% | 1.3% | 1.4% | 1.4% |\n", + "| 87 | 4903 | 1.3% | 1.4% | 1.5% | 1.4% |\n", + "| 88 | 333 | 1.3% | 1.4% | 1.3% | 1.3% |\n", + "| 89 | 6002 | 1.3% | 1.3% | 1.3% | 1.4% |\n", + "| 90 | 5987 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 91 | 2767 | 1.3% | 1.9% | 2.0% | 2.0% |\n", + "| 92 | 6377 | 1.3% | 1.3% | 1.3% | 1.3% |\n", + "| 93 | 5907 | 1.2% | 1.3% | 1.4% | 1.4% |\n", + "| 94 | 4738 | 1.2% | 1.3% | 1.2% | 1.2% |\n", + "| 95 | 180 | 1.2% | 1.3% | 1.3% | 1.3% |\n", + "| 96 | 1807 | 1.2% | 1.2% | 1.3% | 1.2% |\n", + "| 97 | 8177 | 1.2% | 1.2% | 1.2% | 1.2% |\n", + "| 98 | 8033 | 1.2% | 1.3% | 1.3% | 1.4% |\n", + "| 99 | 1701 | 1.2% | 1.2% | 1.3% | 1.2% |\n", + "| 100 | 422 | 1.2% | 1.3% | 1.3% | 1.4% |\n", + "\n", + "| Alliance | Win Probability |\n", + "| --- | --- |\n", + "| 1 | 34.24% |\n", + "| 2 | 16.7% |\n", + "| 3 | 12.11% |\n", + "| 4 | 9.57% |\n", + "| 5 | 8.11% |\n", + "| 6 | 7.13% |\n", + "| 7 | 6.34% |\n", + "| 8 | 5.8% |\n", + "\n", + "Probability 'Favorite' Wins: 0.4628\n", + "Average Division Alliance EPA: 168.9\n", + "Average Division 'Favorite' EPA: 187.1\n", + "Average Division Winner EPA: 180.9\n", + "\n", + "Probability Einstein 'Favorite' Wins: 0.5084\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Average Einstein Alliance EPA: 180.9\n", + "Average Einstein 'Favorite' EPA: 202.6\n", + "Average Einstein Winner EPA: 196.4\n", + "\n" + ] + } + ], + "source": [ + "def pad(s, length = 15):\n", + " return s + \" \" * (length - len(s))\n", + "\n", + "print(\"Division\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(winner_count.items(), key=lambda x: -x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Division\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(winner_count.items(), key=lambda x: -x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Einstein\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(overall_winner_count.items(), key=lambda x: -x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * overall_winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Einstein\")\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Winner\"), \" | \", pad(\"Finalist\"), \" | \", pad(\"3rd Place\"), \" | \", pad(\"4th Place\"), \" |\")\n", + "print(\"| ---- | ---- | --- | --- | --- | --- |\")\n", + "for i, (key, count) in enumerate(sorted(overall_winner_count.items(), key=lambda x: -x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", str(round(100 * overall_winner_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_finalist_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_third_place_count[key] / num_sims, 1)) + \"%\", \"|\", str(round(100 * overall_fourth_place_count[key] / num_sims, 1)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"| Alliance | Win Probability |\")\n", + "print(\"| --- | --- |\")\n", + "for i, count in sorted(winner_alliances.items(), key=lambda x: -x[1]):\n", + " print(\"|\", i + 1, \"|\", str(round(100 * count / 8 / num_sims, 2)) + \"%\", \"|\")\n", + "print()\n", + "\n", + "print(\"Probability 'Favorite' Wins:\", round(np.array(winner_best_epas).mean(), 4))\n", + "print(\"Average Division Alliance EPA:\", round(np.array(alliance_epas).mean(), 1))\n", + "print(\"Average Division 'Favorite' EPA:\", round(np.array(best_epas).mean(), 1))\n", + "print(\"Average Division Winner EPA:\", round(np.array(winner_epas).mean(), 1))\n", + "print()\n", + "\n", + "print(\"Probability Einstein 'Favorite' Wins:\", round(np.array(einstein_winner_best_epas).mean(), 4))\n", + "print(\"Average Einstein Alliance EPA:\", round(np.array(einstein_alliance_epas).mean(), 1))\n", + "print(\"Average Einstein 'Favorite' EPA:\", round(np.array(einstein_best_epas).mean(), 1))\n", + "print(\"Average Einstein Winner EPA:\", round(np.array(einstein_winner_epas).mean(), 1))\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 405, + "id": "13c5b686", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| Rank | Team            | Mean Rank       | 1st             | Top 4           | Top 8           | Top 16          |\n", + "| --- | --- | --- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 5.32 | 29.1% | 63.4% | 81.1% | 93.8% |\n", + "| 2 | 1323 | 5.68 | 27.1% | 60.7% | 79.0% | 92.9% |\n", + "| 3 | 254 | 6.09 | 25.4% | 58.4% | 77.0% | 91.7% |\n", + "| 4 | 1678 | 7.68 | 19.0% | 48.6% | 68.8% | 87.3% |\n", + "| 5 | 3538 | 9.87 | 13.3% | 38.5% | 58.8% | 80.5% |\n", + "| 6 | 971 | 11.01 | 11.2% | 34.5% | 53.8% | 76.6% |\n", + "| 7 | 930 | 11.12 | 10.8% | 33.5% | 53.2% | 76.3% |\n", + "| 8 | 3005 | 11.19 | 10.9% | 33.9% | 53.3% | 76.0% |\n", + "| 9 | 6036 | 11.21 | 10.7% | 33.4% | 53.2% | 76.2% |\n", + "| 10 | 111 | 11.36 | 10.6% | 33.1% | 52.5% | 75.6% |\n", + "| 11 | 1987 | 11.45 | 10.2% | 32.1% | 51.8% | 75.3% |\n", + "| 12 | 176 | 11.64 | 9.9% | 31.5% | 50.9% | 74.6% |\n", + "| 13 | 5940 | 11.67 | 10.2% | 32.0% | 51.4% | 74.6% |\n", + "| 14 | 195 | 11.81 | 9.5% | 30.9% | 50.2% | 74.2% |\n", + "| 15 | 4414 | 12.44 | 8.7% | 28.9% | 47.8% | 72.1% |\n", + "| 16 | 3467 | 12.84 | 8.5% | 27.8% | 46.6% | 70.7% |\n", + "| 17 | 2910 | 13.01 | 8.0% | 27.4% | 45.9% | 70.2% |\n", + "| 18 | 6672 | 13.02 | 8.3% | 27.7% | 46.2% | 70.2% |\n", + "| 19 | 7157 | 13.1 | 8.3% | 27.6% | 46.2% | 69.9% |\n", + "| 20 | 1619 | 13.51 | 7.5% | 25.9% | 44.5% | 68.7% |\n", + "| 21 | 2767 | 13.61 | 7.4% | 25.5% | 43.7% | 68.1% |\n", + "| 22 | 2338 | 13.66 | 7.5% | 25.8% | 44.0% | 68.2% |\n", + "| 23 | 2539 | 13.66 | 7.3% | 25.5% | 43.7% | 68.0% |\n", + "| 24 | 1577 | 13.81 | 7.4% | 25.3% | 43.3% | 67.5% |\n", + "| 25 | 2468 | 13.82 | 7.1% | 24.9% | 43.3% | 67.6% |\n", + "\n", + "| Rank | Team            | Mean Rank       | 1st             | Top 4           | Top 8           | Top 16          |\n", + "| --- | --- | --- | --- | --- | --- | --- |\n", + "| 1 | 2056 | 5.32 | 29.1% | 63.4% | 81.1% | 93.8% |\n", + "| 2 | 1323 | 5.68 | 27.1% | 60.7% | 79.0% | 92.9% |\n", + "| 3 | 254 | 6.09 | 25.4% | 58.4% | 77.0% | 91.7% |\n", + "| 4 | 1678 | 7.68 | 19.0% | 48.6% | 68.8% | 87.3% |\n", + "| 5 | 3538 | 9.87 | 13.3% | 38.5% | 58.8% | 80.5% |\n", + "| 6 | 971 | 11.01 | 11.2% | 34.5% | 53.8% | 76.6% |\n", + "| 7 | 930 | 11.12 | 10.8% | 33.5% | 53.2% | 76.3% |\n", + "| 8 | 3005 | 11.19 | 10.9% | 33.9% | 53.3% | 76.0% |\n", + "| 9 | 6036 | 11.21 | 10.7% | 33.4% | 53.2% | 76.2% |\n", + "| 10 | 111 | 11.36 | 10.6% | 33.1% | 52.5% | 75.6% |\n", + "| 11 | 1987 | 11.45 | 10.2% | 32.1% | 51.8% | 75.3% |\n", + "| 12 | 176 | 11.64 | 9.9% | 31.5% | 50.9% | 74.6% |\n", + "| 13 | 5940 | 11.67 | 10.2% | 32.0% | 51.4% | 74.6% |\n", + "| 14 | 195 | 11.81 | 9.5% | 30.9% | 50.2% | 74.2% |\n", + "| 15 | 4414 | 12.44 | 8.7% | 28.9% | 47.8% | 72.1% |\n", + "| 16 | 3467 | 12.84 | 8.5% | 27.8% | 46.6% | 70.7% |\n", + "| 17 | 2910 | 13.01 | 8.0% | 27.4% | 45.9% | 70.2% |\n", + "| 18 | 6672 | 13.02 | 8.3% | 27.7% | 46.2% | 70.2% |\n", + "| 19 | 7157 | 13.1 | 8.3% | 27.6% | 46.2% | 69.9% |\n", + "| 20 | 1619 | 13.51 | 7.5% | 25.9% | 44.5% | 68.7% |\n", + "| 21 | 2767 | 13.61 | 7.4% | 25.5% | 43.7% | 68.1% |\n", + "| 22 | 2338 | 13.66 | 7.5% | 25.8% | 44.0% | 68.2% |\n", + "| 23 | 2539 | 13.66 | 7.3% | 25.5% | 43.7% | 68.0% |\n", + "| 24 | 1577 | 13.81 | 7.4% | 25.3% | 43.3% | 67.5% |\n", + "| 25 | 2468 | 13.82 | 7.1% | 24.9% | 43.3% | 67.6% |\n", + "| 26 | 118 | 14.44 | 6.2% | 22.9% | 40.4% | 65.4% |\n", + "| 27 | 3175 | 14.7 | 6.1% | 22.3% | 39.7% | 64.6% |\n", + "| 28 | 4522 | 14.74 | 6.3% | 22.7% | 40.0% | 64.6% |\n", + "| 29 | 694 | 15.06 | 5.9% | 21.8% | 39.1% | 63.6% |\n", + "| 30 | 4381 | 15.12 | 6.0% | 21.8% | 38.7% | 63.2% |\n", + "| 31 | 359 | 15.27 | 5.7% | 21.6% | 38.6% | 63.1% |\n", + "| 32 | 4028 | 15.38 | 5.9% | 21.6% | 38.6% | 62.9% |\n", + "| 33 | 2337 | 15.46 | 5.6% | 20.9% | 37.7% | 62.2% |\n", + "| 34 | 6090 | 15.55 | 5.7% | 21.0% | 37.8% | 62.1% |\n", + "| 35 | 2687 | 15.61 | 5.6% | 20.7% | 37.5% | 62.0% |\n", + "| 36 | 3357 | 15.72 | 5.2% | 20.2% | 36.8% | 61.4% |\n", + "| 37 | 1706 | 15.77 | 5.5% | 20.6% | 37.2% | 61.4% |\n", + "| 38 | 3683 | 15.89 | 5.5% | 20.8% | 37.1% | 61.1% |\n", + "| 39 | 6329 | 16.1 | 5.3% | 19.7% | 35.9% | 60.2% |\n", + "| 40 | 7890 | 16.11 | 5.2% | 19.8% | 36.1% | 60.4% |\n", + "| 41 | 4907 | 16.21 | 5.3% | 19.6% | 35.8% | 59.9% |\n", + "| 42 | 3015 | 16.42 | 4.9% | 18.9% | 34.8% | 59.4% |\n", + "| 43 | 1591 | 16.47 | 5.0% | 19.3% | 35.2% | 59.4% |\n", + "| 44 | 230 | 16.67 | 4.8% | 18.5% | 34.0% | 58.6% |\n", + "| 45 | 4499 | 16.95 | 4.8% | 18.4% | 34.0% | 57.8% |\n", + "| 46 | 1727 | 17.01 | 4.7% | 18.0% | 33.5% | 57.6% |\n", + "| 47 | 4613 | 17.07 | 4.5% | 17.8% | 33.3% | 57.4% |\n", + "| 48 | 2046 | 17.18 | 4.4% | 17.3% | 32.5% | 56.7% |\n", + "| 49 | 5913 | 17.31 | 4.4% | 17.4% | 32.7% | 56.7% |\n", + "| 50 | 973 | 17.31 | 4.2% | 17.1% | 32.3% | 56.3% |\n", + "| 51 | 870 | 17.37 | 4.2% | 17.3% | 32.3% | 56.3% |\n", + "| 52 | 604 | 17.59 | 4.3% | 17.1% | 31.9% | 55.8% |\n", + "| 53 | 1757 | 17.62 | 4.2% | 16.7% | 31.9% | 55.8% |\n", + "| 54 | 4270 | 17.62 | 4.2% | 16.5% | 31.6% | 55.4% |\n", + "| 55 | 148 | 17.64 | 4.2% | 16.8% | 31.7% | 55.6% |\n", + "| 56 | 1325 | 17.68 | 4.2% | 16.7% | 31.6% | 55.5% |\n", + "| 57 | 5895 | 18.05 | 4.0% | 16.3% | 31.0% | 54.5% |\n", + "| 58 | 1756 | 18.1 | 3.9% | 16.1% | 30.9% | 54.3% |\n", + "| 59 | 3310 | 18.26 | 3.9% | 15.7% | 30.2% | 53.8% |\n", + "| 60 | 2363 | 18.29 | 3.9% | 15.9% | 30.4% | 53.8% |\n", + "| 61 | 987 | 18.53 | 3.8% | 15.6% | 29.8% | 53.3% |\n", + "| 62 | 3663 | 18.54 | 3.8% | 15.2% | 29.3% | 52.8% |\n", + "| 63 | 4391 | 18.58 | 3.8% | 15.4% | 29.4% | 52.8% |\n", + "| 64 | 341 | 18.74 | 3.6% | 14.9% | 29.0% | 52.4% |\n", + "| 65 | 7457 | 19.2 | 3.4% | 14.0% | 27.6% | 51.0% |\n", + "| 66 | 2451 | 19.21 | 3.5% | 14.0% | 27.9% | 51.0% |\n", + "| 67 | 1114 | 19.27 | 3.4% | 14.0% | 27.3% | 50.6% |\n", + "| 68 | 2481 | 19.29 | 3.4% | 14.1% | 27.6% | 50.7% |\n", + "| 69 | 2052 | 19.35 | 3.2% | 14.0% | 27.3% | 50.5% |\n", + "| 70 | 3184 | 19.36 | 3.4% | 14.1% | 27.5% | 50.6% |\n", + "| 71 | 51 | 19.38 | 3.4% | 14.1% | 27.5% | 50.6% |\n", + "| 72 | 1339 | 19.38 | 3.3% | 13.8% | 27.3% | 50.2% |\n", + "| 73 | 3314 | 19.39 | 3.2% | 13.9% | 27.5% | 50.4% |\n", + "| 74 | 2521 | 19.6 | 3.1% | 13.5% | 26.7% | 49.7% |\n", + "| 75 | 1923 | 19.6 | 3.0% | 13.4% | 26.6% | 49.7% |\n", + "| 76 | 7021 | 19.62 | 3.2% | 13.7% | 26.9% | 49.7% |\n", + "| 77 | 1690 | 19.64 | 3.0% | 13.3% | 26.7% | 49.6% |\n", + "| 78 | 2075 | 19.69 | 3.3% | 13.8% | 27.2% | 49.8% |\n", + "| 79 | 1718 | 20.21 | 3.0% | 12.9% | 25.7% | 48.2% |\n", + "| 80 | 494 | 20.21 | 2.8% | 12.6% | 25.3% | 48.0% |\n", + "| 81 | 3937 | 20.31 | 3.0% | 12.6% | 25.3% | 47.9% |\n", + "| 82 | 4362 | 20.34 | 2.9% | 12.4% | 24.9% | 47.6% |\n", + "| 83 | 695 | 20.44 | 2.8% | 12.7% | 25.2% | 47.5% |\n", + "| 84 | 8033 | 20.49 | 2.8% | 12.4% | 24.8% | 47.2% |\n", + "| 85 | 1391 | 20.61 | 2.8% | 12.2% | 24.8% | 47.1% |\n", + "| 86 | 3476 | 20.67 | 2.7% | 12.2% | 24.7% | 47.0% |\n", + "| 87 | 461 | 20.77 | 2.7% | 12.1% | 24.5% | 46.9% |\n", + "| 88 | 67 | 20.78 | 2.7% | 11.9% | 24.3% | 46.7% |\n", + "| 89 | 2974 | 20.83 | 2.7% | 11.7% | 23.9% | 46.2% |\n", + "| 90 | 7769 | 20.89 | 2.7% | 11.9% | 24.2% | 46.4% |\n", + "| 91 | 6424 | 20.92 | 2.7% | 12.0% | 24.2% | 46.2% |\n", + "| 92 | 1796 | 20.93 | 2.6% | 11.4% | 23.7% | 45.9% |\n", + "| 93 | 4946 | 21.18 | 2.6% | 11.4% | 23.5% | 45.5% |\n", + "| 94 | 6002 | 21.29 | 2.5% | 11.1% | 22.9% | 44.9% |\n", + "| 95 | 4481 | 21.34 | 2.5% | 11.1% | 23.1% | 44.7% |\n", + "| 96 | 6328 | 21.37 | 2.6% | 11.3% | 23.4% | 45.1% |\n", + "| 97 | 125 | 21.41 | 2.5% | 11.1% | 23.0% | 44.4% |\n", + "| 98 | 1732 | 21.49 | 2.4% | 10.8% | 22.5% | 44.3% |\n", + "| 99 | 2992 | 21.61 | 2.5% | 11.0% | 22.6% | 44.2% |\n", + "| 100 | 5010 | 21.64 | 2.3% | 10.7% | 22.3% | 43.9% |\n", + "\n" + ] + } + ], + "source": [ + "avg_ranks = {t: sum(((i + 1) * qual_rank_list[t][i]) for i in range(78)) / num_sims for t in qual_rank_list}\n", + "top_1 = {t: sum(qual_rank_list[t][i] for i in range(1)) / num_sims for t in qual_rank_list}\n", + "top_4 = {t: sum(qual_rank_list[t][i] for i in range(4)) / num_sims for t in qual_rank_list}\n", + "top_8 = {t: sum(qual_rank_list[t][i] for i in range(8)) / num_sims for t in qual_rank_list}\n", + "top_16 = {t: sum(qual_rank_list[t][i] for i in range(16)) / num_sims for t in qual_rank_list}\n", + "\n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Mean Rank\"), \" | \", pad(\"1st\"), \" | \", pad(\"Top 4\"), \" | \", pad(\"Top 8\"), \" | \", pad(\"Top 16\"), \" |\")\n", + "print(\"| --- | --- | --- | --- | --- | --- | --- |\")\n", + "for i, (key, avg_rank) in enumerate(sorted(avg_ranks.items(), key=lambda x: x[1])[:25]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", round(avg_rank, 2), \"|\", str(round(100 * top_1[key], 1)) + \"%\", \"|\", str(round(100 * top_4[key], 1)) + \"%\", \"|\", str(round(100 * top_8[key], 1)) + \"%\", \"|\", str(round(100 * top_16[key], 1)) + \"%\", \"|\")\n", + "print()\n", + " \n", + "print(\"| Rank | \", pad(\"Team\"), \" | \", pad(\"Mean Rank\"), \" | \", pad(\"1st\"), \" | \", pad(\"Top 4\"), \" | \", pad(\"Top 8\"), \" | \", pad(\"Top 16\"), \" |\")\n", + "print(\"| --- | --- | --- | --- | --- | --- | --- |\")\n", + "for i, (key, avg_rank) in enumerate(sorted(avg_ranks.items(), key=lambda x: x[1])[:100]):\n", + " print(\"|\", i + 1, \"|\", key, \"|\", round(avg_rank, 2), \"|\", str(round(100 * top_1[key], 1)) + \"%\", \"|\", str(round(100 * top_4[key], 1)) + \"%\", \"|\", str(round(100 * top_8[key], 1)) + \"%\", \"|\", str(round(100 * top_16[key], 1)) + \"%\", \"|\")\n", + "print()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a50b7934", + "metadata": {}, + "outputs": [], + "source": [ + "# Doesn't account for: \n", + "# supercharing, \n", + "# new link RP, \n", + "# alliance synergy / second pick defense / scorched field\n", + "# team improvement, \n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}