简体   繁体   中英

Generating random numbers in a range (0-4) with the constraint that each number can only be generated a certain amount of times?

I need to generate random numbers as an output for a function called randomize. I am trying to generate numbers in the range 0 to 4. However,

  • Once 0 is generated 2 times, stop generating 0, blankCount counts 0 generations
  • Once 1 is generates 4 times, stop generating 1, birdCount counts 1 generations
  • Once 2 is generated 1 time, stop generating 2, specialCount counts 2 generations
  • Once 3 is generated 2 times, stop generating 3, nullCount counts 3 generations
  • Once 4 is generated 1 time, stop generating 4, crashCount counts 4 generations

I am setting a place in an array to the output of this function. The function is at the end of the post. The problem is to get the function to stop calling itself. I get a Stack Overflow Error with this code.

The goal is to have Two 0s, Four 1s, One 2, Two 3s, and One 4

0,0,1,1,1,1,2,3,3,4

Can anyone help make this function work?

int blankCount = 0;
int birdCount = 0;
int specialCount = 0;
int nullCount = 0;
int crashCount = 0;

int randomize(){
  int num = 0;
  int randomNum = floor(random(0,5));
  
  if(randomNum == 0 && blankCount <= 1) {
    blankCount++;
    num = randomNum;
  }else if(randomNum == 0 && blankCount == 2){
    num = randomize();
  }else if(randomNum == 1 && birdCount <= 3){
    birdCount++;
    num = randomNum;
  }else if(randomNum == 1 && birdCount == 4){
    num = randomize();
  }else if(randomNum == 2 && specialCount <= 0){
    specialCount++;
    num = randomNum;
  }else if(randomNum == 2 && specialCount == 1){
    num = randomize();
  }else if(randomNum == 3 && nullCount <= 1){
    nullCount++;
    num = randomNum;
  }else if(randomNum == 3 && nullCount == 2){
    num = randomize();
  }else if(randomNum == 4 && crashCount <= 0){
    crashCount++;
    num = randomNum;
  }else if(randomNum == 4 && crashCount == 1){
    num = randomize();
  }else{
    print("H ");
  }
  return num;
}

First make a list containing every item that you can legally return.

Then, shuffle it.

Then, to generate a random number, just consume the next item from your shuffled list. Voila - now if you never want more than 4x a 1 , make sure only at most 4 1 values are in your original list.

I have no idea what your random(0, 5) does, but using that to generate random numbers sounds like it's broken by design (pigeon hole principle) - java has a Random class with a much nicer API that isn't broken, by all means use that.

class Randomizer {
    private static final List<Integer> INPUTS = List.of(0, 0, 1, 1, 1, 1, 2, 3, 3, 4);

    private final List<Integer> list;
    private int pos = 0;

    public Randomizer() {
        list = new ArrayList<Integer>(INPUTS);
        Collections.shuffle(list);
    }

    public int next() {
        return list.get(pos++);
    }
}

NB: The above will throw IndexOutOfBoundsException once you 'run out' of random numbers. If you want other behaviour, code that in. For example, if you want the algorithm to start over (re-return 0/0/1/1/1/1/2/3/3/4 in random order, re-fresh the order), then you could do, say:

public int next() {
    if (pos == list.size()) {
        Collections.shuffle(list); // reshuffle
        pos = 0;
    }
    return list.get(pos++);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM