ecclesia
Version:
Framework for political and electoral simulations
71 lines • 2.6 kB
JavaScript
import { divmod } from "@gouvernathor/python";
import { NumberCounter } from "@gouvernathor/python/collections";
import { addThresholdToSimpleAttribution } from "../attribution/transform";
import { proportionalFromDivisorFunction, proportionalFromRankIndexFunction, rankIndexFunctionFromDivisorFunction, stationaryDivisorFunction } from "./proportionalBase";
const divisor1 = stationaryDivisorFunction(1);
export function jefferson({ nSeats }) {
return proportionalFromDivisorFunction({
nSeats,
divisorFunction: divisor1,
});
}
export const dHondt = jefferson;
const divisorPoint5 = k => 2 * k + 1; // int math is better than k + .5
export function webster({ nSeats }) {
return proportionalFromDivisorFunction({
nSeats,
divisorFunction: divisorPoint5,
});
}
export const sainteLague = webster;
export function hamilton({ nSeats }) {
const attrib = (votes, _rest = {}) => {
const seats = NumberCounter.fromEntries();
const remainders = new Map();
const sumVotes = votes.total;
for (const [party, scores] of votes) {
const [i, r] = divmod(scores * nSeats, sumVotes);
seats.set(party, i);
remainders.set(party, r);
}
seats.add([...remainders.keys()]
.sort((a, b) => remainders.get(b) - remainders.get(a))
.slice(0, nSeats - seats.total));
return seats;
};
attrib.nSeats = nSeats;
return attrib;
}
export const hareLargestRemainders = hamilton;
const huntingtonHillBaseRankIndexFunction = rankIndexFunctionFromDivisorFunction(k => Math.sqrt(k * (k + 1)));
const huntingtonHillRankIndexFunction = (t, a) => {
if (a <= 0) {
return Infinity;
}
return huntingtonHillBaseRankIndexFunction(t, a);
};
export function huntingtonHill({ nSeats, threshold, contingency = null }) {
const attrib = addThresholdToSimpleAttribution({
threshold,
contingency,
attribution: proportionalFromRankIndexFunction({
nSeats,
rankIndexFunction: huntingtonHillRankIndexFunction,
}),
});
attrib.nSeats = nSeats;
return attrib;
}
/**
* Creates a highest-averages proportional attribution method.
*
* The exact method used is an implementation detail and may change between versions.
*/
export const highestAverages = webster;
/**
* Creates a largest-remainders proportional attribution method.
*
* Implementation detail: the quota used is the Hare/Hamilton quota.
*/
export const largestRemainders = hamilton;
//# sourceMappingURL=proportionalFactory.js.map