amirsoltani
amirsoltani

Reputation: 91

If(something) re-do the for loop

This one is very simple and basic, but for some reason I cant get it right. So I'm making a for loop and inside the for loop generating random numbers, but I want to eliminate some numbers by redoing the for loop when those numbers come up. how should I do it and whats my mistake. Thank you in advance.

How I did it:

int[] array= new int[6];
for(int i=0;i<array.length;i++){
   Random rand = new Random();
   int  n = rand.nextInt(50) + 1;
   if(n==5 || n==9 || n==13){
      i--;
      return;
   }
   array[i]=n;
}

Upvotes: 2

Views: 106

Answers (5)

Indominus
Indominus

Reputation: 1258

Looks like you could use a while-loop:

int[] array= new int[6];
int i = 0;
while(i<array.length){
   Random rand = new Random();
   int  n = rand.nextInt(50) + 1;
   if(n!=5 && n!=9 && n!=13){
       array[i++] = n;  
   }
}

Upvotes: 1

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31299

The cleanest way is to make sure you don't generate the numbers you don't want - you can adjust your range depending on how many numbers you want to exclude.

This function will give you a random number for lowRange to highRange (both ends included), without any of the numbers specified in without:

public static int randomWithout(Random rand, int lowRange, int highRange, int... without) {
    int range = highRange - lowRange + 1 - without.length;
    int result = rand.nextInt(range) + lowRange;
    for (int i = 0; i < without.length; i++) {
        if (result >= without[i]) {
            result++;
        }
    }
    return result;
}

You can then use this function like this:

int[] array = new int[6];
Random rand = new Random();
for (int i = 0; i < array.length; ++i) {
    array[i] = randomWithout(rand, 1, 50, 5, 9, 13);
}

The big advantage is deterministic running time - using a while loop while you get a number that you don't want could theoretically run forever.

Upvotes: 0

Ian Mc
Ian Mc

Reputation: 5829

This is an interesting post. Just want to chime in and share what my first instinct is. Perhaps it is not conventional.

There is no reason to roll again if you hit upon 5, 9, 13. The approach can be deterministic

Algorithm:

  1. Choose a number R between 1-47 (the numbers 1-4, 6-8, 10-12, 14-50 are all equally probable)
  2. If R == 5 then R = 48
  3. else if R == 9 then R = 49
  4. else if R == 13 then R = 50

This can easily be made into a function where you pass a set of unwanted numbers.

Upvotes: 4

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21575

On thing you could do is generate a list of numbers from [1, .., 50] and remove the numbers you don't want from that list: [5, 9, 13]. Like so:

List<Integer> unwatedNums = Arrays.asList(5, 9, 13);
List<Integer> list = IntStream.rangeClosed(1, 50).boxed().collect(Collectors.toList());
list.removeAll(unwatedNums);

Now instead you can safely grab a random element from that list without having it to unnecessarily get a new random number in some cases:

int[] array= new int[6];
for(int i=0;i<array.length;i++){
    array[i]=list.get((new Random()).nextInt(list.size()));
}

Upvotes: 1

Antimony
Antimony

Reputation: 39481

I think the cleanest way would be to have an inner loop that loops until you get an acceptable number. That way the inner loop could be later factored into a function if necessary. I also moved the random number generator initialization out of the loop, since I assume that's what was intended.

Random rand = new Random();
for (int i = 0; i < array.length; ++i) {
  int n = rand.nextInt(50) + 1;
  while (n == 5 || n == 9 || n == 13) {
    n = rand.nextInt(50) + 1;
  }
  array[i] = n;
}

Upvotes: 3

Related Questions