Created
January 14, 2019 23:45
-
-
Save darccio/a50526e153355d60e39846ef25aa9f38 to your computer and use it in GitHub Desktop.
D'Hondt method
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
package electoral | |
import ( | |
"sort" | |
) | |
// CandidatureResult is all the votes tallied for a candidature. | |
type CandidatureResult struct { | |
Name string | |
Votes int | |
} | |
// Seat is an assigned seat. | |
type Seat struct { | |
Candidature CandidatureResult | |
Quotient int | |
} | |
func quotient(votes, allocatedSeats int) int { | |
return votes / (allocatedSeats + 1) | |
} | |
// DHondt applies D'Hondt method on results for provided seats. | |
func DHondt(tally []CandidatureResult, seats int) []Seat { | |
result := make([]Seat, 0) | |
for _, r := range tally { | |
for i := 0; i < seats; i++ { | |
s := Seat{ | |
r, | |
quotient(r.Votes, i), | |
} | |
result = append(result, s) | |
} | |
} | |
sort.Slice(result[:], func(i, j int) bool { | |
return result[i].Quotient >= result[j].Quotient | |
}) | |
return result[:seats] | |
} |
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
package electoral | |
import ( | |
"testing" | |
) | |
func TestDHondt(t *testing.T) { | |
seats := 54 | |
tally := []CandidatureResult{ | |
CandidatureResult{"PP", 4074363}, | |
CandidatureResult{"PSOE", 3596324}, | |
CandidatureResult{"LA IZQUIERDA PLURAL", 1562567}, | |
CandidatureResult{"PODEMOS", 1245948}, | |
CandidatureResult{"UPyD", 1015994}, | |
CandidatureResult{"CEU", 850690}, | |
CandidatureResult{"EPDD", 629071}, | |
CandidatureResult{"C's", 495114}, | |
CandidatureResult{"LPD", 324534}, | |
CandidatureResult{"PRIMAVERA EUROPEA", 299884}, | |
CandidatureResult{"VOX", 244929}, | |
CandidatureResult{"PACMA", 176237}, | |
CandidatureResult{"EB", 115308}, | |
CandidatureResult{"MOVIMIENTO RED", 105183}, | |
CandidatureResult{"PARTIDO X", 100115}, | |
CandidatureResult{"PARTIDO ANDALUCISTA", 49251}, | |
CandidatureResult{"PIRATAS", 38422}, | |
CandidatureResult{"F.A.C.", 33826}, | |
CandidatureResult{"DISCAPACITADOS Y ENFERMEDADES RARAS", 32531}, | |
CandidatureResult{"RECORTES CERO", 30958}, | |
CandidatureResult{"P.C.P.E.", 29000}, | |
CandidatureResult{"I.Fem", 25199}, | |
CandidatureResult{"FE de las JONS", 21577}, | |
CandidatureResult{"CILUS", 18225}, | |
CandidatureResult{"ImpulsoSocial", 17774}, | |
CandidatureResult{"LEM", 16879}, | |
CandidatureResult{"PH", 15278}, | |
CandidatureResult{"D.N.", 12904}, | |
CandidatureResult{"ACNV-BAR-PRAO-R.E.P.O-UNIO", 11427}, | |
CandidatureResult{"RRUE", 10076}, | |
CandidatureResult{"PT", 9825}, | |
CandidatureResult{"ALTER", 9654}, | |
CandidatureResult{"P-LIB", 9644}, | |
CandidatureResult{"M.S.R.", 8875}, | |
CandidatureResult{"EXTREMADURA UNIDA", 8830}, | |
CandidatureResult{"PREPAL", 8783}, | |
CandidatureResult{"SAIn", 6894}, | |
CandidatureResult{"IPEX-PREX-CREX", 6110}, | |
CandidatureResult{"M.C.R.", 5084}, | |
} | |
result := DHondt(tally, seats) | |
if len(result) != seats { | |
t.Fatalf("expected %d seats, got %d", seats, len(result)) | |
} | |
tests := []struct { | |
name string | |
expected int | |
}{ | |
{"PP", 16}, | |
{"PSOE", 14}, | |
{"LA IZQUIERDA PLURAL", 6}, | |
{"PODEMOS", 5}, | |
{"UPyD", 4}, | |
{"CEU", 3}, | |
{"EPDD", 2}, | |
{"C's", 2}, | |
{"LPD", 1}, | |
{"PRIMAVERA EUROPEA", 1}, | |
{"VOX", 0}, | |
{"PACMA", 0}, | |
{"EB", 0}, | |
{"MOVIMIENTO RED", 0}, | |
{"PARTIDO X", 0}, | |
{"PARTIDO ANDALUCISTA", 0}, | |
{"PIRATAS", 0}, | |
{"F.A.C.", 0}, | |
{"DISCAPACITADOS Y ENFERMEDADES RARAS", 0}, | |
{"RECORTES CERO", 0}, | |
{"P.C.P.E.", 0}, | |
{"I.Fem", 0}, | |
{"FE de las JONS", 0}, | |
{"CILUS", 0}, | |
{"ImpulsoSocial", 0}, | |
{"LEM", 0}, | |
{"PH", 0}, | |
{"D.N.", 0}, | |
{"ACNV-BAR-PRAO-R.E.P.O-UNIO", 0}, | |
{"RRUE", 0}, | |
{"PT", 0}, | |
{"ALTER", 0}, | |
{"P-LIB", 0}, | |
{"M.S.R.", 0}, | |
{"EXTREMADURA UNIDA", 0}, | |
{"PREPAL", 0}, | |
{"SAIn", 0}, | |
{"IPEX-PREX-CREX", 0}, | |
{"M.C.R.", 0}, | |
} | |
for _, test := range tests { | |
assignedSeats := 0 | |
for _, r := range result { | |
if r.Candidature.Name == test.name { | |
assignedSeats++ | |
} | |
} | |
if assignedSeats != test.expected { | |
t.Fatalf("expected %d seats for %s, got %d", assignedSeats, test.name, test.expected) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment