Skip to content

Instantly share code, notes, and snippets.

@darccio
Created January 14, 2019 23:45
Show Gist options
  • Save darccio/a50526e153355d60e39846ef25aa9f38 to your computer and use it in GitHub Desktop.
Save darccio/a50526e153355d60e39846ef25aa9f38 to your computer and use it in GitHub Desktop.
D'Hondt method
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]
}
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