# How Voting Systems Work 1, Exercise 3: how fragile is the plurality winner? # Start from the nine-voter electorate. Move k of the four A-first voters # so that they rank B first instead (A, B, C becomes B, A, C), and # report the plurality winner and the Condorcet winner each time. from collections import Counter from itertools import combinations def plurality(profile): counts = Counter(b[0] for b in profile) top = max(counts.values()) return "/".join(sorted(c for c, v in counts.items() if v == top)), dict(sorted(counts.items())) def condorcet(profile): names = sorted(profile[0]) wins = {n: 0 for n in names} for x, y in combinations(names, 2): vx = sum(1 for b in profile if b.index(x) < b.index(y)) vy = len(profile) - vx if vx > vy: wins[x] += 1 elif vy > vx: wins[y] += 1 found = [n for n in names if wins[n] == len(names) - 1] return found[0] if found else "none" for k in range(0, 5): profile = ( [("A", "B", "C")] * (4 - k) + [("B", "A", "C")] * k + [("B", "C", "A")] * 3 + [("C", "B", "A")] * 2 ) win, counts = plurality(profile) print(f"k={k}: first choices {counts} plurality: {win:3s} Condorcet: {condorcet(profile)}") # Output when run: # k=0: first choices {'A': 4, 'B': 3, 'C': 2} plurality: A Condorcet: B # k=1: first choices {'A': 3, 'B': 4, 'C': 2} plurality: B Condorcet: B # k=2: first choices {'A': 2, 'B': 5, 'C': 2} plurality: B Condorcet: B # k=3: first choices {'A': 1, 'B': 6, 'C': 2} plurality: B Condorcet: B # k=4: first choices {'B': 7, 'C': 2} plurality: B Condorcet: B