Skip to content

Commit

Permalink
sol: lab6/world-cup
Browse files Browse the repository at this point in the history
  • Loading branch information
jfvillablanca committed Nov 7, 2023
1 parent 4952283 commit a05a072
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions lab6/world-cup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://cs50.harvard.edu/x/2023/labs/6/
19 changes: 19 additions & 0 deletions lab6/world-cup/answers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Times:

10 simulations: 0m0.027s
100 simulations: 0m0.028s
1000 simulations: 0m0.035s
10000 simulations: 0m0.156s
100000 simulations: 0m0.768s
1000000 simulations: 0m6.765s

Questions:

Which predictions, if any, proved incorrect as you increased the number of simulations?:

With a small number of simulations, the probability of a country winning is not as correlated with the rating provided.

Suppose you're charged a fee for each second of compute time your program uses.
After how many simulations would you call the predictions "good enough"?:

I think, at around 10000 simulations, the rankings and winning percentages seem to have stabilized to based on historical data. It's fast enough that it runs in less than a second.
70 changes: 70 additions & 0 deletions lab6/world-cup/tournament.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Simulate a sports tournament

import csv
import sys
import random

# Number of simluations to run
N = 1000


def main():
# Ensure correct usage
if len(sys.argv) != 2:
sys.exit("Usage: python tournament.py FILENAME")

teams = []
# TODO: Read teams into memory from file
with open(sys.argv[1]) as file:
reader = csv.DictReader(file)
for team in reader:
team["rating"] = int(team["rating"])
teams.append(team)

counts = {}
# TODO: Simulate N tournaments and keep track of win counts
for i in range(N):
winner = simulate_tournament(teams)
if winner in counts:
counts[winner] += 1
else:
counts[winner] = 1

# Print each team's chances of winning, according to simulation
# for team in sorted(counts, key=lambda team: counts[team], reverse=True):
# print(f"{team}: {counts[team] * 100 / N:.1f}% chance of winning")


def simulate_game(team1, team2):
"""Simulate a game. Return True if team1 wins, False otherwise."""
rating1 = team1["rating"]
rating2 = team2["rating"]
probability = 1 / (1 + 10 ** ((rating2 - rating1) / 600))
return random.random() < probability


def simulate_round(teams):
"""Simulate a round. Return a list of winning teams."""
winners = []

# Simulate games for all pairs of teams
for i in range(0, len(teams), 2):
if simulate_game(teams[i], teams[i + 1]):
winners.append(teams[i])
else:
winners.append(teams[i + 1])

return winners


def simulate_tournament(teams):
"""Simulate a tournament. Return name of winning team."""
# TODO
while len(teams) > 1:
teams = simulate_round(teams)

return teams[0]["team"]


if __name__ == "__main__":
main()

0 comments on commit a05a072

Please sign in to comment.