Created
January 15, 2021 03:07
-
-
Save Noble-Mushtak/2fc50b2c7321e857e75f0fa5cec889de to your computer and use it in GitHub Desktop.
Calculate the place corresponding to every possible score in the Putnam 2019 competition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Usage: python3 calc_putnam_places.py [score] | |
If score is not provided, | |
the script prints the place corresponding to every score | |
any Putnam competitor got in the Putnam 2019 competition. | |
If score is provided and is an integer, | |
the script prints the place corresponding to that score. | |
""" | |
import sys | |
# Copy and pasted from page 4 of https://www.maa.org/sites/default/files/pdf/Putnam/2019/AnnouncementOfWinners2019.pdf | |
raw_rank_table = """120 1 90 19 68 41 53 84.5 38 192 24 384 10 1088.5 | |
119 2.5 89 20 67 43.5 52 86.5 37 199 23 403 9 1235.5 | |
117 4 87 21 66 45 51 90.5 36 206 22 436 8 1368 | |
103 5 85 22 65 47 50 101 35 212 21 478.5 7 1483 | |
102 6 82 23 64 49 49 114 34 218.5 20 532 6 1558 | |
101 7.5 81 24 63 51 48 122 33 227 19 585.5 5 1606.5 | |
100 9 80 26.5 62 53.5 47 126.5 32 236.5 18 627 4 1680.5 | |
99 10 79 29.5 61 56.5 45 129.5 31 249.5 17 667 3 1831.5 | |
98 11 76 31 60 61.5 44 133.5 30 276 16 698 2 2103 | |
97 12.5 75 32 59 67 43 138 29 306.5 15 722 1 2447.5 | |
95 14 73 33 58 73 42 143.5 28 327.5 14 758.5 0 3428 | |
94 15.5 72 34.5 57 77 41 153 27 344.5 13 807.5 | |
92 17 71 37 56 79 40 168 26 360 12 879 | |
91 18 69 39 54 82 39 183.5 25 371.5 11 970""" | |
def ordinal_suffix(num): | |
""" | |
Returns suffix of num, which is expected to be a non-negative integer | |
""" | |
num %= 100 | |
if 4 <= num <= 20: | |
return "th" | |
if (num % 10) == 1: | |
return "st" | |
if (num % 10) == 2: | |
return "nd" | |
if (num % 10) == 3: | |
return "rd" | |
return "th" | |
def as_ordinal(num): | |
""" | |
Given non-negative integer num, | |
output a string representation of num as an ordinal number | |
""" | |
return str(num)+ordinal_suffix(num) | |
def main(raw_rank_table, given_score=None): | |
""" | |
Given raw_rank_table, the score-rank correspondence of Putnam scores, | |
output the places that correspond to each score. | |
If given_score is an integer rather than None, | |
output the place corresponding to score | |
""" | |
rank_table = [None]*121 | |
tokens = (token for token in raw_rank_table.split()) | |
while True: | |
try: | |
score = int(next(tokens)) | |
except StopIteration: | |
break | |
rank_table[score] = float(next(tokens)) | |
place_table = {} | |
prev_place = 0 | |
for score, rank in reversed(list(enumerate(rank_table))): | |
if rank == None: continue | |
""" | |
All the people who got score of _score_ | |
represent the people in places prev_place+1 to cur_place, inclusive. | |
We want the average of their places to be _rank_, so: | |
(prev_place+1 + cur_place) // 2 == rank | |
Then, solve for cur_place. | |
""" | |
cur_place = int(2*rank-prev_place-1) | |
place_table[score] = cur_place | |
prev_place = cur_place | |
printed_something = False | |
prev_place = 0 | |
for score, place in reversed(sorted(place_table.items(), key=lambda tpl: tpl[0])): | |
if given_score == None or given_score == score: | |
if place == prev_place+1: | |
print(f"If your score was { score }, you came in { as_ordinal(place) } place") | |
else: | |
print(f"If your score was { score }, you tied for { as_ordinal(place) } place") | |
printed_something = True | |
prev_place = place | |
# If nothing was printed, then output error message: | |
if not printed_something: | |
print(f"No one got a score of { given_score }") | |
if __name__ == "__main__": | |
if len(sys.argv) > 1: | |
try: | |
score = int(sys.argv[1]) | |
except ValueError: | |
print(f"\"{ sys.argv[1] }\" is not an integer") | |
sys.exit(1) | |
else: | |
score = None | |
main(raw_rank_table, score) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment