Skip to content
Advertisement

Generate random letters “H” and “V” n times

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());
}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement