const VOTES_TO_WIN = 270;
// State name, number of electoral votes, and Republican and
// Democrat nominee polling percent average taken from
// RealClearPolitics.com, rounded to nearest integer
const dataByState = {
'Washington' : { ElectoralVotes : 12, RChance: 50, DChance: 50 },
'Oregon': { ElectoralVotes: 7, RChance: 50, DChance: 50 },
'California': { ElectoralVotes: 55, RChance: 50, DChance: 50 },
'Idaho' : { ElectoralVotes: 4, RChance : 50, DChance: 50 },
'Nevada' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Montana' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'Wyoming' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'Colorado' : { ElectoralVotes: 9, RChance : 50, DChance: 50 },
'New Mexico' : { ElectoralVotes: 5, RChance : 50, DChance: 50 },
'Utah' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Arizona' : { ElectoralVotes: 11, RChance : 50, DChance: 50 },
'North Dakota' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'South Dakota' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'Nebraska' : { ElectoralVotes: 5, RChance : 50, DChance: 50 },
'Kansas' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Oklahoma' : { ElectoralVotes: 7, RChance : 50, DChance: 50 },
'Texas' : { ElectoralVotes: 38, RChance : 50, DChance: 50 },
'Minnesota' : { ElectoralVotes: 10, RChance : 50, DChance: 50 },
'Iowa' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Missouri' : { ElectoralVotes: 10, RChance : 50, DChance: 50 },
'Arkansas' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Lousiana' : { ElectoralVotes: 8, RChance : 50, DChance: 50 },
'Wisconsin' : { ElectoralVotes: 10, RChance : 50, DChance: 50 },
'Illinois' : { ElectoralVotes: 20, RChance : 50, DChance: 50 },
'Tennessee' : { ElectoralVotes: 11, RChance : 50, DChance: 50 },
'Mississippi' : { ElectoralVotes: 6, RChance : 50, DChance: 50 },
'Alabama' : { ElectoralVotes: 9, RChance : 50, DChance: 50 },
'Michigan' : { ElectoralVotes: 16, RChance : 50, DChance: 50 },
'Indiana' : { ElectoralVotes: 11, RChance : 50, DChance: 50 },
'Kentucky' : { ElectoralVotes: 8, RChance : 50, DChance: 50 },
'Ohio' : { ElectoralVotes: 18, RChance : 50, DChance: 50 },
'West Virginia' : { ElectoralVotes: 5, RChance : 50, DChance: 50 },
'Virginia' : { ElectoralVotes: 13, RChance : 50, DChance: 50 },
'North Carolina' : { ElectoralVotes: 15, RChance : 50, DChance: 50 },
'South Carolina' : { ElectoralVotes: 9, RChance : 50, DChance: 50 },
'Georgia' : { ElectoralVotes: 16, RChance : 50, DChance: 50 },
'Florida' : { ElectoralVotes: 29, RChance : 50, DChance: 50 },
'D.C.' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'Maryland' : { ElectoralVotes: 10, RChance : 50, DChance: 50 },
'Delaware' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'New Jersey' : { ElectoralVotes: 14, RChance : 50, DChance: 50 },
'Pennsylvania' : { ElectoralVotes: 20, RChance : 50, DChance: 50 },
'Connectuicut' : { ElectoralVotes: 7, RChance : 50, DChance: 50 },
'Rhode Island' : { ElectoralVotes: 4, RChance : 50, DChance: 50 },
'Massachusetts' : { ElectoralVotes: 11, RChance : 50, DChance: 50 },
'New York' : { ElectoralVotes: 29, RChance : 50, DChance: 50 },
'Vermont' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'New Hampshire' : { ElectoralVotes: 4, RChance : 50, DChance: 50 },
'Maine' : { ElectoralVotes: 4, RChance : 50, DChance: 50 },
'Alaska' : { ElectoralVotes: 3, RChance : 50, DChance: 50 },
'Hawaii' : { ElectoralVotes: 4, RChance : 50, DChance: 50 }
};
const states = Object.keys(dataByState);
// Helper for using the above map to get a chance of winning
// from a given poll difference
const calcWinChance = (diff) => {
const conv = pollConversion.find((x) =>
x.DiffRange[0] <= diff && x.DiffRange[1] >= diff
);
return conv && conv.ChanceWin;
}// Helper returns true or false depending on whether a given
// collection of states has enough combined electoral votes
// to win an election
const hasSufficientVotes = (states) => {
const votes = states.reduce((sum,state) =>
sum += dataByState[state].ElectoralVotes
, 0);
return votes >= VOTES_TO_WIN;
};
// Helper for getting the combination of states corresponding
// to the inputted bit pattern i
const getCombo = (i) => {
let combo = [];
for(var j = 0; j < states.length; ++j)
if((i >> j) & 1)
combo.push(states[j]);
return combo;
}
// To be filled out, combos will be a map of a bit pattern
// to the corresponding array of state names
let combos = {};
// Set time limit on
const now = new Date();
const timeout = now.setSeconds(now.getSeconds() + 1); // 1 seconds
// Run simulation
const rangetop = Math.pow(2,states.length) + 1;
while(new Date() < timeout)
{
const rand = Math.floor(Math.random() * rangetop);
if(!combos.hasOwnProperty(rand))
combos[rand] = getCombo(rand);
}
// Sum up the probabilites of the R candidate winning each
// combination of states that add up to a succifient number
// of electoral votes
let RSum = 0;
const keynums = Object.keys(combos);
console.log("num combos = " + keynums.length);//TEST
keynums.forEach((num) => {
const comboStates = combos[num];
// state combo not counted if it doesn't add up
// to enough electoral votes
if(!hasSufficientVotes(comboStates))
return;
// mutltipy together the probabilities of the R
// winning the state combo
let RProb = 1;
comboStates.forEach((state) => {
RProb *= dataByState[state].RChance / 100;
});
const otherStates = states.filter((state) => !comboStates.includes(state));
otherStates.forEach((state) => {
RProb *= dataByState[state].DChance / 100;
});
RSum += RProb;
});
const multiplier = Math.pow(2, states.length + 1) / keynums.length;
RSum *= multiplier;
alert("RSum = " + RSum);