I have a really specific problem and can’t think of an answer.
I have a function to generate a letter H or V.
I want to make that if the generator exceedes the limit for H to pick V and if the limit for V gets exceeded to pick H.
Example
Limit for H is 10 Limit for V is 10
function generateLetter(){ let result = randomLetter; // Just pseudocode it picks H or V if The limit for H is exceeded to pick }
the result would be the letter H 10 times and letter V 10 times.
This is my code
H5 = Limit for H number V5 = Limit for V number
function generateType(h5, v5){ let type = ["H", "V"]; let randomType = Math.round(Math.random()); let selectedType = type[randomType]; if(totalH < h5 && selectedType == "H"){ totalH += 1; } if(totalV < v5 && selectedType == "V"){ totalV += 1; } if(totalH >= h5 && totalV < v5){ selectedType = "V"; } if(totalV >= v5 && totalH < h5){ selectedType = "H"; } return selectedType; }
EDIT
I have a for loop that loops like 20 times
let text = []; for(let i = 0; i < 20; i++){ text1 = generateType(); text.push(text1); }
I want to make it so that there is exactly 10 H and 10 V or any number i choose
This is the entire Code
worker.js Using Web Workers
let letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q","r", "s", "t", "u", "v", "w", "x", "y", "z"]; let tags = []; let items = []; let index = 0; let textBack = ""; var hA = 0; var vA = 0; var minA; var maxA; let totalH = 0; let totalV = 0; function saveDATA(min, max, h, v){ minA = min; maxA = max; hA = Math.round(h / 50); vA = Math.round(v / 50); } function generateTags(totalTags){ let tag; for(let i = 0; i < totalTags; i++){ let r1 = Math.ceil(Math.random() * 15); let r2 = Math.ceil(Math.random() * 7); let r3 = Math.ceil(Math.random() * 5); let r4 = Math.ceil(Math.random() * 9); let r5 = Math.ceil(Math.random() * 17); // console.log(r1, r2, r3, r4, r5); tag = letters[r1] + letters[r2] + letters[r3] + letters[r4] + letters[r5]; if(tags.includes(tag)){ // Do nothing let random = Math.round(Math.random()); if(random == 1){ tags.push(tag); tags.concat(tag); } } else{ tags.push(tag); tags.concat(tag); tags.push(tag); tags.concat(tag); items.push(tag); } if(totalTags < 2){ return tag; } } } function generateType(h5, v5){ let type = ["H", "V"]; let randomType = Math.round(Math.random()); let selectedType = type[randomType]; if(totalH < h5 && selectedType == "H"){ totalH += 1; } if(totalV < v5 && selectedType == "V"){ totalV += 1; } if(totalH >= h5 && totalV < v5){ selectedType = "V"; } if(totalV >= v5 && totalH < h5){ selectedType = "H"; } return selectedType; } function getRandomInt(min, max) { let minB, maxB; minB = Math.ceil(Number(min)); maxB = Math.floor(Number(max)); return Math.floor(Math.random() * (maxB - minB + 1)) + minB; } function generateTagsInsideItem(){ let totalTags = getRandomInt(minA, maxA); return totalTags; } function generateTagsItem(h4, v4){ let totalTags = generateTagsInsideItem(); let tags = ""; for(let i = 0; i < totalTags; i++) { tags += " " + generateTags(1); } let text = generateType(h4, v4) + " " + totalTags + " " + tags; return text; } function generateDocumnet(id, items, horizontal, vertical) { hA = Math.round(Number(horizontal) / 50); vA = Math.round(Number(vertical) / 50); let totalItems = items; for(let i = 0; i < totalItems; i++){ textBack += "n" + generateTagsItem(hA, vA); } } self.addEventListener("message", function(e) { saveDATA(e.data.minimum, e.data.maximum, e.data.horizontal, e.data.vertical); generateDocumnet(e.data.id, e.data.count, e.data.horizontal, e.data.vertical); this.postMessage({id: e.data.id , result: textBack}); }, false);
Advertisement
Answer
Fill an array with 10 Hs, 10 Vs, then shuffle the array. Return consecutive elments from the array. Wrap everything in a closure, so that you do not pollute global state and can create differently parametrized “sequences”:
function shuffle(array) { for (let i = array.length - 1; i > 0; --i) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } function generate(hs, vs) { var a = new Array(hs + vs) .fill('H', 0, hs) .fill('V', hs, hs + vs); shuffle(a); var i = 0; return () => a[i++]; } let sequence = generate(4, 2); for (let i = 0; i < 8; ++i) { console.log(sequence()); } sequence = generate(2, 4); for (let i = 0; i < 8; ++i) { console.log(sequence()); }
If you always need the same number of H’s and V’s, you could simply keep a single array and shuffle it each time before iterating (shuffling is O(n) and requires only 20 steps for 20 elements). This would avoid having to “generate” a new sequence every time.
Or you could split the “generator” and the “iterator” part, making it easy for you to reuse arrays and iterate a given sequence multiple times:
function shuffle(array) { for (let i = array.length - 1; i > 0; --i) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } function generate(hs, vs) { var a = new Array(hs + vs) .fill('H', 0, hs) .fill('V', hs, hs + vs); shuffle(a); return a; } function iterate(a) { var i = 0; return () => a[i++]; } let array = generate(4, 2) let sequence = iterate(array); for (let i = 0; i < 8; ++i) { console.log(sequence()); } // iterate again from the beginning sequence = iterate(array); for (let i = 0; i < 8; ++i) { console.log(sequence()); }