Last active
May 23, 2023 22:20
-
-
Save gioiliop7/78ca78bd1daa5d39a313e9446717579d to your computer and use it in GitHub Desktop.
Calculate the seats in "Apli Analogiki" elections format, in greek elections
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
function distributeSeats(percentages, totalSeats, threshold) { | |
const validParties = percentages.filter((percentage) => percentage >= threshold); | |
const totalValidPercentages = validParties.reduce((a, b) => a + b, 0); | |
const seatDistribution = []; | |
validParties.forEach((percentage) => { | |
const seats = Math.floor((percentage / totalValidPercentages) * totalSeats); | |
seatDistribution.push(seats); | |
}); | |
const remainingSeats = totalSeats - seatDistribution.reduce((a, b) => a + b, 0); | |
const remainingParties = percentages.length - validParties.length; | |
const sumPercentageForOthers = 100 - validParties.reduce((a, b) => a + b, 0); | |
if (remainingSeats > 0 && remainingParties > 0) { | |
const remainingPercentage = sumPercentageForOthers - totalValidPercentages; | |
const seatsPerParty = Math.floor((remainingPercentage / 100) * totalSeats); | |
const extraSeats = remainingSeats - (seatsPerParty * remainingParties); | |
for (let i = 0; i < remainingParties; i++) { | |
const seats = seatsPerParty + (extraSeats > 0 ? 1 : 0); | |
seatDistribution.push(seats); | |
extraSeats--; | |
} | |
} | |
const seatSum = seatDistribution.reduce((a, b) => a + b, 0); | |
const seatsToAdd = totalSeats - seatSum; | |
// Distribute remaining seats to parties with the highest fractional parts | |
if (seatsToAdd > 0) { | |
const fractionalParts = validParties.map((percentage, index) => { | |
const seats = seatDistribution[index]; | |
const fractionalPart = percentage / totalValidPercentages - seats / totalSeats; | |
return { index, fractionalPart }; | |
}); | |
fractionalParts.sort((a, b) => b.fractionalPart - a.fractionalPart); | |
for (let i = 0; i < seatsToAdd; i++) { | |
const index = fractionalParts[i % fractionalParts.length].index; | |
seatDistribution[index]++; | |
} | |
} | |
return seatDistribution; | |
} | |
// Example usage: | |
const percentages = [41.83, 38.10, 8.15, 5.04, 3.8]; | |
const totalSeats = 300; | |
const threshold = 3; | |
const seatDistribution = distributeSeats(percentages, totalSeats, threshold); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment