Running Loop showing results [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
How can I use a loop to flip a coin 20 times, each time displaying the result of the flip as a string on the page? After the loop completes, I want to return the array with the result of each flip.
What I have so far:
function display20Flips() {
const results = [];
var i;
var results = '';
for (i = 0; i < 20; i++) {
}
const coin = {
state: 0,
flip: function() {
this.state = Math.floor(Math.random() * 2);
},
toString: function() {
if (this.state === 0) {
return Heads;
} else {
return Tails
}
},
toHTML: function() {
const image = document.createElement('img');
image.src = `$this.toString()}.png`
image.alt = this.toString()
return image;
}
};
function display20Flips() {
const results = [];
// 4. One point: Use a loop to flip the coin 20 times, each time displaying the result of the flip as a string on the page. After your loop completes, return an array with the result of each flip.
for (let i = 0; i < 20; i++) {
if(i%2){
results[i] = 'heads';
} else{
results[i] = 'tails';
}
console.log(results[i])
}
}
display20Flips();
function display20Images() {
const results = [];
// 5. One point: Use a loop to flip the coin 20 times, and display the results of each flip as an image on the page. After your loop completes, return an array with result of each flip.
}

You might want to create a FlipCoin function which determinates the value, call this function in a loop, storing the function result value in a variable, which you can print to screen and add to a results array.
something like this
// Returns 1 or 0, i.e. 1 = Head, 0 = Tail
function flipCoin() {
var flipValue = Math.floor(Math.random() * 100);
return flipValue % 2;
}
function main() {
let results = [];
for (cnt = 0; cnt < 20; cnt++) {
let result = flipCoin();
results.push(result);
console.log(result == 0 ? "Tail" : "Head");
}
console.dir(results);
}
main();

I believe you want something like this:
function display20Flips() {
var results = [];
for (let i = 0; i < 20; i++) {
if(i%2){
results[i] = 'heads';
} else{
results[i] = 'tails';
}
console.log(results[i])
}
}
display20Flips(); // for displaying in snippet code

Use Array(20) to create an array of size 20
Array.map to iterate through each element, use Array.fill to fill the array with null values else it will not iterate through.
Math.random()*10 to generate a random number between 0-10.
If the value is even then returned Head else Tails
function display20Flips() {
return Array(20).fill().map(e => Math.random()*10 & 1 ? 'Head' : 'Tails')
}
console.log(display20Flips())

Im not an expert but here it is :D
<!DOCTYPE html>
<html>
<body>
<script>
var results = [];
function display20Flips() {
for (var i = 0; i <20; i++ ){
var x = Math.floor((Math.random() * 2));
if(x == 0){
results[i] = "heads";
}else{
results[i] = "tails";
}
}
console.log(results);
}
display20Flips();
</script>
</body>
</html>

Related

Javascript program is not recognizing an if statement [duplicate]

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 5 years ago.
The program is running an else statement when I'm expecting an if statement to run. When the program checks the gameObject's playerSelections property against the gameObject's colorSequence property I expect the program to log 'You got it. Way to go!' if the two arrays are equivalent. Instead I keep getting the console log statement 'Better luck next time!'. Does anyone have any ideas as to why this may be happening. `
const $headerText = $('.fly-in-text');
setTimeout(function() {
$headerText.removeClass('temp-hide');
}, 500);
let gameObject = {
colorIds: ['#blue', '#red', '#green', '#yellow'],
currentLevel: 1,
colorSequence: [],
playerSelections: [],
illuminate:function(color){
setTimeout(function(){
$(color).css('opacity', .5);
setTimeout(function() {
$(color).css('opacity', 1);
},500);
},500);
},
levelSequence: function(){
const iterationCount = this.currentLevel + 2;
for (let i = 0; i < iterationCount; i++) {
this.colorSequence.push(this.colorIds[Math.floor(Math.random() * 4)]);
}
this.startGame(this.colorSequence);
},
startGame: function(sequence) {
let i = 0;
const self = this;
var interval = setInterval(function(){
self.illuminate(sequence[i]);
i++;
if (i >= sequence.length){
clearInterval(interval);
}
}, 1000);
}
}
$circle.click(function() {
clearTimeout(interval);
$(this).toggleClass('rotate');
gameObject.levelSequence();
$('.colors').click(function(){
gameObject.playerSelections.push(`#${this.id}`);
console.log(gameObject.playerSelections);
checkForWin();
// for (let i = 0; i < gameObject.colorSequence.length; i++) {
// playerSelections[i] = (`$${this.id}`);
// console.log(playerSelections)
// }
})
})
function checkForWin(){
if (gameObject.playerSelections === gameObject.colorSequence){
console.log('Comparing')
if (gameObject.playerSelections === gameObject.colorSequence){
console.log('You got it. Way to go!');
gameObject.colorSequence = [];
gameObject.playerSelections = [];
gameObject.currentLevel += 1;
$('.colors').off('click');
return 'You got it. Way to go!';
} else {
gameObject.colorSequence = [];
gameObject.playerSelections = [];
$('.colors').off('click')
console.log('Better luck next time!');
}
}
}
Since playerSelections and colorSequence are arrays, your the condition gameObject.playerSelections === gameObject.colorSequence tests that the array references are equal, not the contents of the arrays.
You need to check that each element of the array is equal:
How to check identical array in most efficient way?

"Look and say sequence" in javascript

1
11
12
1121
122111
112213
122211
....
I was trying to solve this problem. It goes like this.
I need to check the former line and write: the number and how many time it was repeated.
ex. 1 -> 1(number)1(time)
var antsArr = [[1]];
var n = 10;
for (var row = 1; row < n; row++) {
var lastCheckedNumber = 0;
var count = 1;
antsArr[row] = [];
for (var col = 0; col < antsArr[row-1].length; col++) {
if (lastCheckedNumber == 0) {
lastCheckedNumber = 1;
antsArr[row].push(lastCheckedNumber);
} else {
if (antsArr[row-1][col] == lastCheckedNumber) {
count++;
} else {
lastCheckedNumber = antsArr[row-1][col];
}
}
}
antsArr[row].push(count);
antsArr[row].push(lastCheckedNumber);
}
for (var i = 0; i < antsArr.length; i++) {
console.log(antsArr[i]);
}
I have been on this since 2 days ago.
It it so hard to solve by myself. I know it is really basic code to you guys.
But still if someone who has a really warm heart help me out, I will be so happy! :>
Try this:
JSFiddle Sample
function lookAndSay(seq){
var prev = seq[0];
var freq = 0;
var output = [];
seq.forEach(function(s){
if (s==prev){
freq++;
}
else{
output.push(prev);
output.push(freq);
prev = s;
freq = 1;
}
});
output.push(prev);
output.push(freq);
console.log(output);
return output;
}
// Sample: try on the first 11 sequences
var seq = [1];
for (var n=0; n<11; n++){
seq = lookAndSay(seq);
}
Quick explanation
The input sequence is a simple array containing all numbers in the sequence. The function iterates through the element in the sequence, count the frequency of the current occurring number. When it encounters a new number, it pushes the previously occurring number along with the frequency to the output.
Keep the iteration goes until it reaches the end, make sure the last occurring number and the frequency are added to the output and that's it.
I am not sure if this is right,as i didnt know about this sequence before.Please check and let me know if it works.
var hh=0;
function ls(j,j1)
{
var l1=j.length;
var fer=j.split('');
var str='';
var counter=1;
for(var t=0;t<fer.length;t++)
{
if(fer[t]==fer[t+1])
{
counter++;
}
else
{
str=str+""+""+fer[t]+counter;
counter=1;
}
}
console.log(str);
while(hh<5) //REPLACE THE NUMBER HERE TO CHANGE NUMBER OF COUNTS!
{
hh++;
//console.log(hh);
ls(str);
}
}
ls("1");
You can check out the working solution for in this fiddle here
You can solve this by splitting your logic into different modules.
So primarily you have 2 tasks -
For a give sequence of numbers(say [1,1,2]), you need to find the frequency distribution - something like - [1,2,2,1] which is the main logic.
Keep generating new distribution lists until a given number(say n).
So split them into 2 different functions and test them independently.
For task 1, code would look something like this -
/*
This takes an input [1,1,2] and return is freq - [1,2,2,1]
*/
function find_num_freq(arr){
var freq_list = [];
var val = arr[0];
var freq = 1;
for(i=1; i<arr.length; i++){
var curr_val = arr[i];
if(curr_val === val){
freq += 1;
}else{
//Add the values to the freq_list
freq_list.push([val, freq]);
val = curr_val;
freq = 1;
}
}
freq_list.push([val, freq]);
return freq_list;
}
For task 2, it keeps calling the above function for each line of results.
It's code would look something like this -
function look_n_say(n){
//Starting number
var seed = 1;
var antsArr = [[seed]];
for(var i = 0; i < n; i++){
var content = antsArr[i];
var freq_list = find_num_freq(content);
//freq_list give an array of [[ele, freq],[ele,freq]...]
//Flatten so that it's of the form - [ele,freq,ele,freq]
var freq_list_flat = flatten_list(freq_list);
antsArr.push(freq_list_flat);
}
return antsArr;
}
/**
This is used for flattening a list.
Eg - [[1],[1,1],[1,2]] => [1,1,1,1,2]
basically removes only first level nesting
**/
function flatten_list(li){
var flat_li = [];
li.forEach(
function(val){
for(ind in val){
flat_li.push(val[ind]);
}
}
);
return flat_li;
}
The output of this for the first 10 n values -
OUTPUT
n = 1:
[[1],[1,1]]
n = 2:
[[1],[1,1],[1,2]]
n = 3:
[[1],[1,1],[1,2],[1,1,2,1]]
n = 4:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1]]
n = 5:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3]]
n = 6:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1]]
n = 7:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1]]
n = 8:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3]]
n = 9:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3],[1,1,2,2,1,1,3,1,1,3,2,1,1,1,3,1,1,2,3,1]]

How to get more than 1000 results Parse [duplicate]

This question already has answers here:
How to retrieve more than 1000 rows from Parse.com?
(11 answers)
Closed 7 years ago.
I have a cloud code which returns sometimes more than 1000 results , I am not getting how to chain query to get more than 1000 results in following code.
var User = Parse.Object.extend("Journal");
var mainQuery = new Parse.Query(User);
mainQuery.equalTo("user",username);
mainQuery.limit(1000);
mainQuery.find({
success: function(results) {
count = 0;
var avg = 0;
console.log("self:"+results.length);
for(j = 0; j < results.length ; j++)
{
var entry = results[j];
if(strcmp1(day,"All") != 0)
{
var dt = entry.get("created");
var weekDay = dt.getDay();
if(weekDay == day)
{
total += entry.get("Level");
count++;
}
}
else
{
total += entry.get("Level");
count++;
}
}
if(count > 1)
avg = total / count;
response.success(avg);
}
});
limit function is used for raising the default limit of 100 which is max 1000 per query result return cycle .
I am using this code presently. This can fetch more than 1000 results.
The values are sorted according to "objectId". You can sort according to "createdAt" by changing accordingly.
Final results are stored in result array
var result = [];
var processCallback = function(res) {
result = result.concat(res);
if (res.length == 1000) {
process(res[res.length-1].id);
return;
}
//To print all the ids
for(var i=0;i<result.length;i++){
console.log(result[i].id);
}
}
var process = function(skip) {
var query = new Parse.Query("ObjectName");
if (skip) {
query.greaterThan("objectId", skip);
}
query.limit(1000);
query.ascending("objectId");
query.find().then(function querySuccess(res) {
processCallback(res);
}, function queryFailed(error) {
});
}
process(false);

How can I group the elements of a set into disjoint subsets in javascript?

In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons? How can I generates all the possibilities via backtracking with javascript.
Example:
Gs = group([aldo,beat,carla,david,evi,flip,gary,hugo,ida],[2,2,5]);
console.log(Gs); // [[aldo,beat],[carla,david],[evi,flip,gary,hugo,ida]], ...
Note that I do not want permutations of the group members; i.e. [[aldo,beat],...] is the same solution as [[beat,aldo],...]. However, there's a difference between [[aldo,beat],[carla,david],...] and [[carla,david],[aldo,beat],...].
*No libraries please.
If you only need the number of ways a group of 9 people can be divided into 3 subgroups of 2, 3 and 4 people each then that's easy to compute mathematically using C (the function to calculate the number of combinations).
First you have 9 people out of which you need to select 2 people. Hence you do C(9, 2).
Next you have 7 people out of which you need to select 3 people. Hence you do C(7, 3).
Finally you have 4 people out of which you need to select 4 people. Hence you do C(4, 4). However C(n, n) is always 1.
Hence the number of ways to divide a group of 9 people into 3 subgroups of 2, 3 and 4 people is C(9, 2) * C(7, 3) * C(4, 4). This can be simplified to C(9, 2) * C(7, 3), which is 36 * 35 which is 1260.
We can write a function to compute this for us:
function ways(n) {
var l = arguments.length, w = 1;
for (var i = 1; i < l; i++) {
var m = arguments[i];
w *= combinations(n, m);
n -= m;
}
return w;
}
To make this function work we need to define the function combinations:
function combinations(n, k) {
return factorial(n) / factorial(n - k) / factorial(k);
}
Finally we need to define the function for factorial:
function factorial(n) {
var f = n;
while (--n) f *= n;
return f;
}
Then we compute the number of ways as follows:
alert(ways(9, 2, 3)); // 1260
You can see the demo here: http://jsfiddle.net/bHSuh/
Note that we didn't need to specify the last subgroup of 4 people because that is implied.
However I believe that you want to generate each possible way. This is the sort of thing that the amb operator is perfect for. So the first thing we'll do is write the amb operator in JavaScript:
function amb(options, callback) {
var length = options.length;
for (var i = 0; i < length; i++) {
try {
callback(options[i]); // try the next option
return; // no problem, quit
} catch (e) {
continue; // problem, next
}
}
throw new Error("amb tree exhausted"); // throw a tantrum
}
Next we'll write a function which picks a given set of items from a list of indices:
function pick(list, items) {
var length = list.length, selected = [], rest = [];
for (var i = 0; i < length; i++) {
if (items.indexOf(i) < 0) rest.push(list[i]);
else selected.push(list[i]);
}
return [selected, rest];
}
We also need a function which will generate a list of indices:
function getIndices(length) {
var indices = [];
for (var i = 0; i < length; i++)
indices.push(i);
return indices;
}
Finally we'll implement the group function recursively:
function group(options, divisions) {
var subgroup = [], groups = [], n = 0;
var indices = getIndices(options.length);
var division = divisions.shift(), remaining = divisions.length;
try {
amb(indices, select);
} catch (e) {
return groups;
}
function select(index) {
subgroup.push(index);
if (++n < division) {
try { amb(indices.slice(index + 1), select); }
catch (e) { /* we want to continue processing */ }
} else {
var subgroups = pick(options, subgroup);
if (remaining) {
var children = group(subgroups.pop(), divisions.slice());
var length = children.length;
for (var i = 0; i < length; i++)
groups.push(subgroups.concat(children[i]));
} else groups.push(subgroups);
}
n--;
subgroup.pop();
throw new Error;
}
}
Now you can use it as follows:
var groups = group([
"aldo", "beat", "carla",
"david", "evi", "flip",
"gary", "hugo", "ida"
], [2, 3]);
Notice again that you didn't need to specify the last subgroup of 4 people since it's implied.
Now let's see whether the output is as we expected it to be:
console.log(groups.length === ways(9, 2, 3)); // true
There you go. There are exactly 1260 ways that a group of 9 people can be divided into 3 subgroups of 2, 3 and 4 people each.
Now I know that my group function looks a little daunting but it's actually really simple. Try to read it and understand what's going on.
Imagine that you're the boss of 9 people. How would you divide them into 3 subgroups of 2, 3 and 4 people? That's exactly the way my group function works.
If you still can't understand the logic after a while then I'll update my answer and explain the group function in detail. Best of luck.
BTW I just realized that for this problem you don't really need amb. You may simply use forEach instead. The resulting code would be faster because of the absence of try-catch blocks:
function group(options, divisions) {
var subgroup = [], groups = [], n = 0;
var indices = getIndices(options.length);
var division = divisions.shift(), remaining = divisions.length;
indices.forEach(select);
return groups;
function select(index) {
subgroup.push(index);
if (++n < division) indices.slice(index + 1).forEach(select);
else {
var subgroups = pick(options, subgroup);
if (remaining) {
var children = group(subgroups.pop(), divisions.slice());
var length = children.length;
for (var i = 0; i < length; i++)
groups.push(subgroups.concat(children[i]));
} else groups.push(subgroups);
}
subgroup.pop();
n--;
}
}
Since we don't use amb anymore the execution time of the program has decreased tenfold. See the result for yourself: http://jsperf.com/amb-vs-foreach
Also I've finally created a demo fiddle of the above program: http://jsfiddle.net/Ug6Pb/
i am sure there are faster formulas, but i was never that great at math, and this seems to work if i understand the problem correctly:
function combo(r, ops){
function unq(r){return r.filter(function(a,b,c){return !this[a] && (this[a]=1);},{}); }
var combos={}, pairs=[];
r.forEach(function(a,b,c){
combos[a]=r.filter(function not(a){return a!=this && !combos[a]}, a);
});
Object.keys(combos).forEach(function(k){
combos[k].forEach(function(a){
pairs.push([k, a]+'');
});
});
return unq(unq(
pairs.map(function(a){
return unq(a.split(",")).sort();
})).map(function(a){
return a.length==ops && a;
}).filter(Boolean))
.sort();
}//end combo
var r="aldo,beat,carla,david,evi,flip,gary,hugo,ida".split(",");
// find groups of different lengths:
combo(r, 2) // 2 folks == 36 combos
combo( combo(r, 2), 3) // 3 folks == 84 combos
combo( combo( combo(r, 2), 3), 4) // 4 folks == 126 combos
i didn't bother to recursive-ize the function since you only need to go 4-in and a lispy invocation works, but if i had to go further, i'd want to write one additional outer wrapper to sandwich the calls...
the core implementation of the backtracking algorithm is simple (see function doBacktrack below). Usually the complexity is in the details of the specific backtracking problem
the following is my implementation of a backtracking algorithm for your problem. it is based on the backtracking algorithm description in Steven Skiena's Algorithm Design Manual (or what I remember of it).
I've not added pruning to the algorithm (because it's already taken me longer than I thought it would do :) ) but if you want to improve its performance just add a reasonable implementation for the function done() to prevent continuing with the processing of candidates that can be inferred to not be viable solutions
function backtrack() {
var people =
['aldo','beat','carla','david','evi','flip','gary','hugo','ida'];
var initial_state =
[[], [], []];
var groups =
[2, 3, 4];
var data =
{groups: groups, people: people, people_idx_for_name: {}};
people.forEach(function(e, i) {
data['people_idx_for_name'][e] = i;
});
var solutions = [];
doBacktrack(initial_state, solutions, data);
return solutions;
}
function doBacktrack(candidate, solutions, data) {
// console.log('processing: ' + candidate);
if (isSolution(candidate, data)) {
processSolution(candidate, solutions);
}
if (done(candidate, solutions, data)) {
return;
}
var new_candidates = calculateNewCandidates(candidate, data);
for (var i=0; i<new_candidates.length; i++) {
doBacktrack(new_candidates[i], solutions, data);
}
}
function calculateNewCandidates(candidate, data) {
var groups = data['groups'];
var i = 0;
while (i<groups.length && candidate[i].length == groups[i]) { i++; }
if (i < groups.length) {
//determine list of not yet selected people
var not_yet_selected = determineNotYetSelectedPeople(candidate, data, i);
var results = [];
for (var j=0; j<not_yet_selected.length; j++) {
var candidate_copy = candidate.slice(0);
for (var k=0; k<candidate_copy.length; k++) {
candidate_copy[k] = candidate_copy[k].slice(0);
}
candidate_copy[i].push(not_yet_selected[j])
results.push(candidate_copy);
}
return results;
} else {
return [];
}
}
function determineNotYetSelectedPeople(candidate, data, group) {
var people = data['people'];
var people_idx_for_name = data['people_idx_for_name'];
var selected_people = {};
var results = [];
var max = -Number.MAX_VALUE;
candidate.forEach(function(candidate_group, i) {
candidate_group.forEach(function(already_selected_person_name) {
var already_selected_person_idx = people_idx_for_name[already_selected_person_name];
if (max < already_selected_person_idx && i==group) { max = already_selected_person_idx; }
selected_people[already_selected_person_name] = true;
});
});
for (var i=0; i<people.length; i++) {
if (!selected_people[people[i]] && i > max) { results.push(people[i]); }
}
return results;
}
function isSolution(candidate, data) {
var groups = data['groups'];
for (var i=0; i<groups.length; i++) {
if (candidate[i].length != groups[i]) {return false;}
}
return true;
}
function processSolution(candidate, solutions) {
var solution = [];
candidate.forEach(function(e) {
var l = [];
solution.push(l);
e.forEach(function(f) {
l.push(f);
});
});
solutions.push(solution);
}
//use this to improve performance with prunning if possible
function done() {
return false;
}
var solutions = backtrack();
console.log(solutions);
console.log(solutions.length);

probability in javascript help?

Sorry, I'm new to JS and can't seem to figure this out: how would I do probability?
I have absolutely no idea, but I'd like to do something: out of 100% chance, maybe 0.7% chance to execute function e(); and 30% chance to execute function d(); and so on - they will add up to 100% exactly with a different function for each, but I haven't figured out exactly how to do this in any form.
What I found is mostly strange high school math tutorials "powered by" Javascriptkit or something.
For instance we define a number of functions
function a () { return 0; }
function b () { return 1; }
function c () { return 2; }
var probas = [ 20, 70, 10 ]; // 20%, 70% and 10%
var funcs = [ a, b, c ]; // the functions array
That generic function works for any number of functions, it executes it and return the result:
function randexec()
{
var ar = [];
var i,sum = 0;
// that following initialization loop could be done only once above that
// randexec() function, we let it here for clarity
for (i=0 ; i<probas.length-1 ; i++) // notice the '-1'
{
sum += (probas[i] / 100.0);
ar[i] = sum;
}
// Then we get a random number and finds where it sits inside the probabilities
// defined earlier
var r = Math.random(); // returns [0,1]
for (i=0 ; i<ar.length && r>=ar[i] ; i++) ;
// Finally execute the function and return its result
return (funcs[i])();
}
For instance, let's try with our 3 functions, 100000 tries:
var count = [ 0, 0, 0 ];
for (var i=0 ; i<100000 ; i++)
{
count[randexec()]++;
}
var s = '';
var f = [ "a", "b", "c" ];
for (var i=0 ; i<3 ; i++)
s += (s ? ', ':'') + f[i] + ' = ' + count[i];
alert(s);
The result on my Firefox
a = 20039, b = 70055, c = 9906
So a run about 20%, b ~ 70% and c ~ 10%.
Edit following comments.
If your browser has a cough with return (funcs[i])();, just replace the funcs array
var funcs = [ a, b, c ]; // the old functions array
with this new one (strings)
var funcs = [ "a", "b", "c" ]; // the new functions array
then replace the final line of the function randexec()
return (funcs[i])(); // old
with that new one
return eval(funcs[i]+'()');
Something like this should help:
var threshhold1 = 30.5;
var threshhold2 = 70.5;
var randomNumber = random() * 100;
if (randomNumber < threshhold1) {
func1()
}
else if (randomNumber < threshhold2) {
func2()
}
else {
func3()
}
This will execute func1() with 30.5% probability, func2() with 40%, and func3() with 29.5%.
You could probably do it more elegantly using a dictionary of threshholds to function pointers, and a loop that finds the first dictionary entry with a threshhold greater than randomNumber.
// generate cumulative distribution function from weights
function cdf(weights) {
// calculate total
var total = 0;
for(var i=0; i<weights.length; i++) {
total += weights[i];
}
// generate CDF, normalizing with total
var cumul = [];
cumul[0] = weights[0]/total;
for(var i=1; i<weights.length; i++) {
cumul[i] = cumul[i-1] + (weights[i]/total);
}
return cumul;
}
// pick the index using the random value
function selectInd(cumul,rand) {
for(var i=0; (i < cumul.length) && (rand > cumul[i]); ++i) {};
return i;
}
Code block to use the above
// setup (do this once)
var weights = [70,20,10];
var cumul = cdf(weights)
// get the index and pick the function
var ran = Math.random(); // 0 : 1
var func = funcs[selectInd(cumul,ran)];
// call the function
var someArgVal = 5;
var myResult = func(someArgVal);
// do it in one line
var myResult = (funcs[selectInd(cumul,Math.random())])(someArgVal);
Simplify calling code with a reusable object
function CumulDistributor(cumul,funcs) {
var funcArr = funcs;
var cumulArr = cumul;
function execRandomFunc(someArg) {
var func = funcArr[selectInd(cumulArr,Math.random())];
return func(someArg);
}
}
// example usage
var cdistor = new CumulDistributor(cumul,funcs);
var myResult = cdistor.execRandomFunc(someArgValue);
var decide = function(){
var num = parseInt(Math.random() * 10) + 1; // assigns num randomly (1-10)
num > 7 ? d() : e(); // if num > 7 call d(), else call e()
};
Look up how to get random numbers in JavaScript, and then depending on where that number falls, call each function.
Sounds like what you really want is the Javascript random() function.

Categories

Resources