# What would be the best implementation of the D'Hondt method of highest averages for allocating seats on party-list proportional representation?

The 2019 European Parliament elections are happening shortly and seat allocation will use the D'Hondt method of highest averages. In order to analyse possible scenarios and results I need a Wolfram Language implementation of the algorithm.

Given a list of votes and an integer number of seats available what would be a good Mathematica implementation of the algorithm to determine the seats allocated to each party?

The basic algorithm is (from Wikipedia)

After all the votes have been tallied, successive quotients are calculated for each party. The party with the largest quotient wins one seat, and its quotient is recalculated. This is repeated until the required number of seats is filled. The formula for the quotient is ($$V$$: total number of votes, $$s$$: number of seats that party has been allocated so far, initially $$0$$ for all parties.)

$$\text{quotient} = \frac{V}{s+1}$$

We want to define

DHondt[v_List, s_Integer]


The expected outcome is:

votes = {100000, 80000, 30000, 20000};
DHondt[votes , 8]
(* {4, 3, 1, 0} *)


I'm basically sharing my implementation here and inviting (challenging?) others to improve in elegance or performance. There is a published solution here, but I think we can do better.

## 1 Answer

This will work with data in form of List or Association

ClearAll[DHondt$$iter, DHondt ]; DHondt$$iter[LV_][LC_] := MapAt[(# + 1) &, LC, Ordering[LV/(LC + 1), -1]];
DHondt[v_List, s_Integer] := Nest[DHondt\$iter[v], Array[0 &, Length[v]], s];
DHondt[v_Association, s_Integer] := AssociationThread[Keys[v], DHondt[Values[v], s]]

votesAssoc = <|
"Red Party" -> 100000,
"Green Party" -> 80000,
"Blue Party" -> 30000,
"Violet Party" -> 20000
|> 