Chapter 155
Ballots, Primaries, and the Spy in Riddler Nation
The Riddler for July 21, 2017. The Express is a tidy combinatorial count: candidates for at-large seats with up-to- votes per ballot, asking how many distinct ballots and how many distinct top- outcomes are possible. The Classic is the third war of Riddler Nation, now with a spy: knowing your enemy’s distribution of soldiers across castles worth points, what is the minimum army size you can guarantee a victory with?
Riddler Express
In a primary, candidates compete for at-large seats on a City Commission. Each voter may vote for at most candidates (so a ballot may name , , , or candidates, but never the same candidate twice). The election reduces the field of candidates from to for the general. How many distinct legal ballots are possible? How many distinct outcomes are there for who advances to November’s general election (ignoring ties)?
The Riddler, FiveThirtyEight, July 21, 2017(original post)
Solution
Ballot count. A ballot is an unordered subset of size , , , or drawn from distinct candidates (the order of marks does not matter, since each named candidate gets one tick). The count is the sum of binomial coefficients:
Outcome count. The primary advances exactly candidates to the general, chosen from . With ties excluded, the outcome is simply the set of advancing candidates, which is
The computation
Enumerate the ballots and outcomes directly. For ballots, iterate over every subset of the candidates whose size is at most . For outcomes, iterate over every subset of size exactly .
from itertools import combinations
CANDIDATES = list(range(11))
ballots = []
for k in range(0, 4):
ballots.extend(combinations(CANDIDATES, k))
outcomes = list(combinations(CANDIDATES, 6))
print(f"distinct ballots = {len(ballots)}")
print(f"distinct outcomes = {len(outcomes)}")
# distinct ballots = 232
# distinct outcomes = 462
The enumerated counts reproduce the boxed values exactly.
Riddler Classic
Two warlords compete to take the most points by conquering castles worth victory points. Each warlord distributes troops across the castles. The warlord with strictly more troops at a castle conquers it and earns its points; ties split the points evenly. The whole-tournament winner is whoever earns the most points overall. Your enemy has soldiers. You have a spy: you know your enemy’s full distribution before you commit. But your army is smaller. What is the smallest such that, no matter the enemy’s distribution of , you can pick a distribution of soldiers that wins?
The Riddler, FiveThirtyEight, July 21, 2017(original post)
Solution
The total point pool is . To guarantee a strict win you need at least points (since leaves the enemy ).
Best response with a spy. Knowing the enemy’s distribution , your best response is to identify a subset of castles whose point sum is at least and whose total “conquest cost” is minimised; you spend soldiers at each castle (one more than the enemy posts) and at the rest. (Tying with the enemy splits points, which we account for separately below; but the cleanest strict-majority argument uses .) The required force is
The enemy’s worst distribution. The enemy will choose to make even your best response expensive. They want every castle to be “equally inefficient” in points per soldier required. If the cost-per-point at castle is , the enemy equalises these ratios: The enemy’s troop budget is fixed at : So the enemy plays : that is , summing to . Every castle then costs exactly two soldiers per victory point.
Your minimal force. To gather at least points at a uniform cost of per point, you need at least soldiers. Concretely, conquer castles through with soldiers ( in total) to claim points; the enemy keeps castles , , with soldiers, scoring only points. A second optimal response is to attack castles , , , with soldiers, again reaching .
Sufficiency for all . For any enemy distribution summing to , your best-response cost is at most . The reason: pick the subset that maximises subject to . The enemy’s choice equalises the cost-per-point at exactly , hence achieves the maximum of the minmax. Any deviation by the enemy from creates at least one castle where the cost-per-point is less than , giving you a cheaper subset.
So the value of the spy is exactly relative to a fair fight (you can shed of your original soldiers and still guarantee a win):
The computation
Encode the problem directly. Set the worst-case enemy distribution . Brute-force the minimum-cost subset of castles whose total point sum reaches at least . Confirm the answer is . As a separate check, run many random enemy distributions and confirm soldiers always suffices and sometimes does not.
from itertools import combinations
import random
def best_response_cost(enemy, target=28):
"""Min cost to claim >= target points; cost at castle i is enemy[i]+1."""
n = len(enemy)
best = None
for size in range(1, n + 1):
for S in combinations(range(n), size):
if sum(i + 1 for i in S) >= target:
cost = sum(enemy[i] + 1 for i in S)
if best is None or cost < best:
best = cost
return best
enemy_worst = [2*i - 1 for i in range(1, 11)] # 1,3,5,...,19
print(f"worst-case enemy {enemy_worst}, sum {sum(enemy_worst)}")
print(f"best-response cost = {best_response_cost(enemy_worst)}")
# Sample random enemies; confirm 56 always suffices
rng = random.Random(0)
def random_enemy(rng):
cuts = sorted(rng.sample(range(1, 110), 9))
parts = [cuts[0]] + [cuts[i+1] - cuts[i] for i in range(8)] + [110 - cuts[8]]
return [p - 1 for p in parts] # shifts so sum = 100, non-negative
max_cost = 0
for _ in range(20_000):
e = random_enemy(rng)
if sum(e) != 100: continue
c = best_response_cost(e)
if c > max_cost: max_cost = c
print(f"max best-response cost over 20,000 random enemies = {max_cost}")
# worst-case enemy [1, 3, 5, 7, 9, 11, 13, 15, 17, 19], sum 100
# best-response cost = 56
# max best-response cost over 20,000 random enemies = 48
Brute force on the canonical worst-case distribution returns exactly . Uniform-random sampling of partitions of rarely lands near , so the sampled maximum sits well below ; that is consistent with the worst case being a sharp ridge in the distribution space, not a typical one. The spy is worth soldiers.