# How Voting Systems Work 7, Exercise 1 (assumed, invented numbers): five states share 12 seats under Huntington-Hill. # Every state starts with 1 seat; each remaining seat goes to the highest priority p / sqrt(n * (n + 1)), # where n is the number of seats the state already holds. from math import sqrt pops = {"Ardan": 9100, "Brex": 5400, "Cole": 3300, "Dunn": 1900, "Eld": 900} seats = 12 alloc = {s: 1 for s in pops} gaps = {} for number in range(len(pops) + 1, seats + 1): priority = {s: pops[s] / sqrt(alloc[s] * (alloc[s] + 1)) for s in pops} best = max(sorted(priority), key=priority.get) print(f"seat {number:>2}: {best:<6} priority {priority[best]:8.1f} (runner-up {sorted(priority.values())[-2]:8.1f})") gaps[number] = priority[best] - sorted(priority.values())[-2] alloc[best] += 1 print(alloc) closest = min(gaps, key=gaps.get) print("closest call: seat", closest, "decided by a margin of", round(gaps[closest], 1)) # seat 6: Ardan priority 6434.7 (runner-up 3818.4) # seat 7: Brex priority 3818.4 (runner-up 3715.1) # seat 8: Ardan priority 3715.1 (runner-up 2333.5) # seat 9: Ardan priority 2626.9 (runner-up 2333.5) # seat 10: Cole priority 2333.5 (runner-up 2204.5) # seat 11: Brex priority 2204.5 (runner-up 2034.8) # seat 12: Ardan priority 2034.8 (runner-up 1558.8) # {'Ardan': 5, 'Brex': 3, 'Cole': 2, 'Dunn': 1, 'Eld': 1} # closest call: seat 7 decided by a margin of 103.3