Skip to content

Instantly share code, notes, and snippets.

@CrossEye
Last active January 3, 2022 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CrossEye/5a7ee1dd6e91f3cc0f4a12eca8128b88 to your computer and use it in GitHub Desktop.
Save CrossEye/5a7ee1dd6e91f3cc0f4a12eca8128b88 to your computer and use it in GitHub Desktop.
Changes to the Electoral College

Changes to the Electoral College

This shows how various scenarios play out in terms of Electoral College vote and the states' percentages of those votes. These are based on current apportionment rules against the 2019 Census estimates, with various House sizes of (the current) 435, 1000, and 5000. Note here that Wyoming, which has 0.18 percent of the population would have 0.51 percent of the representation under the current rules, whereas California, with 12.01 percent of the population would have 10.2 percent of the representation. With a 1000-seat House this would change to 0.35 percent and 11.19 percent, respectively. And with a 5000-seat House, they would be 0.21 percent and 11.83 percent.

This does not take into account the Banzhaf or Shapley-Shubik power indices, which could result in much different anaylses.

State Population Pop % 435 # 435 % 1000 # 1000 % 5000 # 5000 %
Alabama 4903185 1.49 9 1.68 17 1.54 77 1.51
Alaska 731545 0.22 3 0.56 4 0.36 13 0.25
Arizona 7278717 2.21 12 2.23 24 2.18 113 2.22
Arkansas 3017804 0.92 6 1.12 11 1 48 0.94
California 39512223 12.01 54 10.06 123 11.16 604 11.84
Colorado 5758736 1.75 10 1.86 20 1.81 90 1.76
Connecticut 3565287 1.08 7 1.3 13 1.18 56 1.1
Delaware 973764 0.3 3 0.56 5 0.45 17 0.33
District of Columbia 705749 0.21 3 0.56 4 0.36 11 0.22
Florida 21477737 6.53 30 5.59 68 6.17 329 6.45
Georgia 10617423 3.23 16 2.98 34 3.09 164 3.22
Hawaii 1415872 0.43 4 0.74 6 0.54 24 0.47
Idaho 1787065 0.54 4 0.74 7 0.64 29 0.57
Illinois 12671821 3.85 19 3.54 41 3.72 195 3.82
Indiana 6732219 2.05 11 2.05 23 2.09 105 2.06
Iowa 3155070 0.96 6 1.12 12 1.09 50 0.98
Kansas 2913314 0.89 6 1.12 11 1 46 0.9
Kentucky 4467673 1.36 8 1.49 16 1.45 70 1.37
Louisiana 4648794 1.41 8 1.49 16 1.45 73 1.43
Maine 1344212 0.41 4 0.74 6 0.54 22 0.43
Maryland 6045680 1.84 10 1.86 20 1.81 94 1.84
Massachusetts 6892503 2.1 11 2.05 23 2.09 107 2.1
Michigan 9986857 3.04 15 2.79 32 2.9 154 3.02
Minnesota 5639632 1.71 9 1.68 19 1.72 88 1.73
Mississippi 2976149 0.9 6 1.12 11 1 47 0.92
Missouri 6137428 1.87 10 1.86 21 1.91 96 1.88
Montana 1068778 0.32 4 0.74 5 0.45 18 0.35
Nebraska 1934408 0.59 5 0.93 8 0.73 31 0.61
Nevada 3080156 0.94 6 1.12 11 1 49 0.96
New Hampshire 1359711 0.41 4 0.74 6 0.54 23 0.45
New Jersey 8882190 2.7 14 2.61 29 2.63 137 2.69
New Mexico 2096829 0.64 5 0.93 8 0.73 34 0.67
New York 19453561 5.91 28 5.21 61 5.54 298 5.84
North Carolina 10488084 3.19 16 2.98 34 3.09 162 3.18
North Dakota 762062 0.23 3 0.56 4 0.36 14 0.27
Ohio 11689100 3.55 17 3.17 38 3.45 180 3.53
Oklahoma 3956971 1.2 7 1.3 14 1.27 62 1.22
Oregon 4217737 1.28 8 1.49 15 1.36 66 1.29
Pennsylvania 12801989 3.89 19 3.54 41 3.72 197 3.86
Rhode Island 1059361 0.32 3 0.56 5 0.45 18 0.35
South Carolina 5148714 1.57 9 1.68 18 1.63 80 1.57
South Dakota 884659 0.27 3 0.56 5 0.45 15 0.29
Tennessee 6829174 2.08 11 2.05 23 2.09 106 2.08
Texas 28995881 8.81 40 7.45 90 8.17 444 8.71
Utah 3205958 0.97 6 1.12 12 1.09 51 1
Vermont 623989 0.19 3 0.56 4 0.36 12 0.24
Virginia 8535519 2.59 13 2.42 28 2.54 132 2.59
Washington 7614893 2.31 12 2.23 25 2.27 118 2.31
West Virginia 1792147 0.54 4 0.74 7 0.64 29 0.57
Wisconsin 5822434 1.77 10 1.86 20 1.81 91 1.78
Wyoming 578759 0.18 3 0.56 4 0.36 11 0.22
const nextSeat = (seats, pops) =>
Object .entries (seats)
.map (([state, seats]) => [state, pops [state] * Math.sqrt(1 / (seats * (seats + 1)))])
.sort (([, a], [_, b]) => b - a)
[0][0] // ideally, use a better max implementation that sort/head, but low priority
const apportion = (total, pops) => {
let seats = Object .fromEntries (Object .entries (pops) .map (([s, _]) => [s, 1]))
total -= Object.values(pops).length
while (total --> 0) {
const state = nextSeat (seats, pops)
seats = {...seats, [state]: seats [state] + 1}
}
return seats
}
const electors = (
total,
pops,
seats = Object .fromEntries (Object .entries (apportion (total, pops)) .map (([n, s]) => [n, s + 2] )),
min = Math .min (... Object .values (seats))
) =>
({...seats, 'District of Columbia': min})
const sum = (ns) => ns.reduce((a, b) => a + b, 0)
const disp = (x) => Math.round(10000 * x) / 100
const report = (pops, dcPop, ...sizes) => {
const totalPop = sum ([dcPop, ...Object .values (pops)])
const data = sizes .reduce (
(a, s) => {
const totalElectors = sum(Object.values(electors (s, pops)))
return Object.entries (electors (s, pops))
.reduce((a, [state, e]) => ({
...a,
[state]: {...a[state], [s + ' #']: e, [s + ' %']: e / totalElectors}
}), a)
},
Object .fromEntries (Object .entries (pops) .map(([s, p]) => [s, {population: p, 'pop %': p / totalPop}]))
)
console.log(
`| State | Population | Pop % | `
+ sizes.map(s => `${s} # | ${s} % `).join(' | ') + ' |'
)
console.log(
`|-------|------------|-------|`
+ sizes.map(s => `-------|-------`).join('|') + ' |'
)
Object .keys (data) .sort().forEach(state => {
const e = data [state]
console.log(
`| ${state} | ${e.population} | ${disp(e['pop %'])} | `
+ sizes.map(s => `${e[s + ' #']} | ${disp(e[s + ' %'])} `).join(' | ') + ' |'
)
})
return data
}
// from https://api.census.gov/data/2019/pep/population?get=POP,NAME&for=state:* -- removing DC & PR
const pops = {Alabama: 4903185, Alaska: 731545, Arizona: 7278717, Arkansas: 3017804, California: 39512223, Colorado: 5758736, Connecticut: 3565287, Delaware: 973764, 'District of Columbia': 705749, Florida: 21477737, Georgia: 10617423, Hawaii: 1415872, Idaho: 1787065, Illinois: 12671821, Indiana: 6732219, Iowa: 3155070, Kansas: 2913314, Kentucky: 4467673, Louisiana: 4648794, Maine: 1344212, Maryland: 6045680, Massachusetts: 6892503, Michigan: 9986857, Minnesota: 5639632, Mississippi: 2976149, Missouri: 6137428, Montana: 1068778, Nebraska: 1934408, Nevada: 3080156, 'New Hampshire': 1359711, 'New Jersey': 8882190, 'New Mexico': 2096829, 'New York': 19453561, 'North Carolina': 10488084, 'North Dakota': 762062, Ohio: 11689100, Oklahoma: 3956971, Oregon: 4217737, Pennsylvania: 12801989, 'Rhode Island': 1059361, 'South Carolina': 5148714, 'South Dakota': 884659, Tennessee: 6829174, Texas: 28995881, Utah: 3205958, Vermont: 623989, Virginia: 8535519, Washington: 7614893, 'West Virginia': 1792147, Wisconsin: 5822434, Wyoming: 578759}
const dcPop = 705749 // same source, simply needs different handling.
report(pops, dcPop, 435, 1000, 5000)
electors (435, pops) // Current EC of 538
//=> {Alabama: 9, Alaska: 3, Arizona: 13, Arkansas: 6, California: 60, ..., Wyoming: 3}
electors (896, pops) // Total EC of 1000
//=> {Alabama: 16, Alaska: 4, Arizona: 23, Arkansas: 11, California: 116, ..., Wyoming: 4}
electors (1000, pops) // Total House of 1000
//=> {Alabama: 18, Alaska: 4, Arizona: 25, Arkansas: 12, California: 129, ..., Wyoming: 4}
// This is cleaner, but could run into recursion limits
// Note that this does not handle the removal of the original 50 seats assigned to each state.
// An update is in https://stackoverflow.com/a/70560879/1243641
const apportion = (
total,
pops,
seats = Object.fromEntries (Object.entries(pops).map(([s, _]) => [s, 1])),
state = nextSeat (seats, pops)
) =>
total <= 0
? seats
: apportion (total - 1, pops, {...seats, [state]: seats[state] + 1})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment