1

I need help for an exercice in school.

I need to create an array with 6 random integers from the following array : montab[] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100} and with the following rules :

  1. numbers 25,50,75,100 can only occur once each in the array
  2. numbers 1 to 10 can only occur twice each in the array

I tried the first rule for now but in rare cases I still get the number more than once.

Here is my code :

public class Exo7bis {
public static void main (String[] args){
    Random random = new Random();
    int montab[] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100};
    int[] ar1 = new int[6];
    int j = 0, compteur25 = 0, compteur50 = 0, compteur75 = 0, compteur100 = 0;
        for (int i = 0; i < ar1.length; i++) {
            ar1[i] = (montab[new Random().nextInt(montab.length)]);
            if (ar1[i] == 25) {
                compteur25++;
                if (compteur25 > 1) {
                    while (ar1[i] == 25)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 50) {
                compteur50++;
                if (compteur50 > 1) {
                    while (ar1[i] == 50)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 75) {
                compteur75++;
                if (compteur75 > 1) {
                    while (ar1[i] == 75)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
            if (ar1[i] == 100) {
                compteur100++;
                if (compteur100 > 1) {
                    while (ar1[i] == 100)
                        ar1[i] = (montab[new Random().nextInt(montab.length)]);
                }
            }
        }

        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] +" ⎢ " + "\t");
        }
    }
}

I know that my tests are not totally right, I identified the problem but I can't find the proper solution.

If someone could help me or advise me, that would be cool.

Thanks in advance!

Jeremy

Adnan Isajbegovic
  • 2,227
  • 17
  • 27
Jeremy
  • 167
  • 11

4 Answers4

0

There is actually a simple solution, though it doesn't guarantee truly random numbers.

What we'll do is create an array with the numbers 1 - 10 listed twice, and 25 - 100 listed once. Every time a number is chosen, we replace it with a 0.

Thus, it is impossible to choose more than a single 25 or more than two 8's.

In code,

public class Exo7bis {

    public static void main (String[] args){

        Random random = new Random();

        int[] intPool = {1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,25,50,75,100};
        int[] chosen = {0,0,0,0,0,0};

        int counter = 0;

        // while the list is not full
        while (chosen[5] == 0) {

            // generate a number from 0 - 23 (representing the numbers in intPool)
            int temp = random.randInt(24);

            // if that element in intPool = 0, it means that it's already chosen
            // and can't be chosen again.
            if (intPool[temp] != 0) {
                chosen[counter] = intPool[temp];
                intPool[temp] = 0;

                counter++;
            }
        }
    }
}
Alex Zhang
  • 123
  • 1
  • 10
0

There are many ways to achieve this but since you are just using arrays I will advise you making a function that counts how many time 1-10 is repeated. For the first the condition you could just replace the element with 0 so it will not repeat next time. I think it's easy to explain in code so have a look at what you could change in your code:

public static void main(String[] args) {
        Random random = new Random();
        int montab[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100 };
        int[] ar1 = new int[6];
        int j = 0, count = 0;
        while (j < ar1.length) {
            count = 0;
            int index = random.nextInt(montab.length);
            int num = montab[index];
            if (num >= 25) { //adds any number greater or equal to 25
                ar1[j] = num;
                j++;
                montab[index] = 0; // replace the origianl array with 0.
            } else if (num != 0) {
                if(!isRepeated(ar1,num)){ //checks if the array has more than two of the number.
                ar1[j] = num;
                j++;
                }
            }
        }
        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] + " ⎢ " + "\t");
        }
    }

    public static boolean isRepeated(int[] arr, int num) { //method that verifies if the array has a number repeated twice or not.
        int count = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num)
                count++;
        }
        return count==2 ? true : false;
    }

I haven't tested it but I'm pretty sure it will work!!

thetraveller
  • 445
  • 3
  • 10
  • Hi, Thank you for your response. I hadn't thought about putting 0 once numbers more than 25 were used. I have 2 small questions, the first one is about the variable count in the main code. Is that one necessary or can we juste delete it. It seems useless as we dont use it later in the main code. My second question is about your method, as I'm new to java and to coding in general i d'ont totally understand it. What i have trouble with is your last line : return count==2 ? true : false; Could you please detail that line for me please? Thank you! – Jeremy Nov 24 '16 at 12:16
  • @Jeremy No, the count variable is not necessary there, I put there because I wasn't sure if you want `25,75,100` only once or each of it once. You can remove it'snot needed there,and the last statement in the method checks the condition if the count ==2 then it returns true else returns false. It is called ternary operator `result = testCondition ? value1 : value2` – thetraveller Nov 24 '16 at 17:21
0

Here's my approach. I try modify the original list/array so that the original numbers shrink in size if they're used as according to the rules.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Exo7bis {
    private static final List<Integer> montab = new ArrayList<Integer>(Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100 }));
    private static final List<Integer> allowOnce = new ArrayList<Integer>(Arrays.asList(new Integer[] { 25, 50, 75, 100 }));
    private static final List<Integer> allowTwice = new ArrayList<Integer>(Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
    public static void main(String[] args) {
        int[] ar1 = new int[6];
        for (int i = 0; i < ar1.length; ++i) {
            int index = new Random().nextInt(montab.size());
            int value = montab.get(index);
            ar1[i] = value;
            if (isOneOff(value)) {
                montab.remove(index);
            } else if (isTwoOff(value))
                montab.remove(index);
        }
        System.out.println(Arrays.toString(ar1));
    }
    public static boolean isOneOff(final int n) {
        for (int i = 0; i < allowOnce.size(); ++i)
            if (allowOnce.get(i) == n)
                return true;
        return false;
    }
    public static boolean isTwoOff(final int n) {
        boolean one = false, two = false;
        for (int i = 0; i < allowTwice.size(); ++i) {
            int j = 0;
            for ( ; j < montab.size(); ++j) {
                if (montab.get(j) == n) {
                    one = true;
                    break;
                }
            }
            ++j;
            for ( ; j < montab.size(); ++j) {
                if (montab.get(j) == n) {
                    two = true;
                    break;
                }
            }
        }
        return (one && two);
    }
}
Nick Bell
  • 516
  • 3
  • 16
0

Here's a solution that involves only arrays and gives the randomness you want. The idea is to store occurences of the picked values in another int[] array and compare those to your limits. [FULL CODE AT THE BOTTOM]

Explanation

The line

if ((randomNum < 25 && newOccurence == 2) || randomNum >= 25)

checks for your maximum occurences.

Then, you recreate the original array (montab) without the value that has reached its limit.

int[] tempTab = new int[montab.length - 1];
int skips = 0;
for (int j = 0; j < tempTab.length; j++) {
    if (montab[j] == randomNum) {
        skips++;
    }
    tempTab[j] = montab[j + skips];
}
montab = tempTab;

This approach obviously works iff there are no repeating values in the original array. The performance might not be the best because of the recreation of the array, but at least you avoid the randomness of maybe hitting the same values over and over again.

Tested code

import java.util.Random;

public class Exo7bis {

    public static void main (String[] args){

        int[] montab = {1,2,3,4,5,6,7,8,9,10,25,50,75,100};
        int[] ar1 = new int[6];
        int[] occurences = new int[montab.length];

        for (int i = 0; i < ar1.length; i++) {

            int randomIndex = new Random().nextInt(montab.length);
            int randomNum = montab[randomIndex];
            int newOccurence = (occurences[randomIndex] = occurences[randomIndex] + 1);

            /*  UNCOMMENT THIS FOR VISUAL STEPS
            for (int a : montab) { System.out.print(a + " | "); }
            System.out.println("");
            */

            if ((randomNum < 25 && newOccurence == 2) || randomNum >= 25) 
            { 
                int[] tempTab = new int[montab.length - 1];
                int skips = 0;
                for (int j = 0; j < tempTab.length; j++) {
                    if (montab[j] == randomNum) {
                        skips++;
                    }

                    tempTab[j] = montab[j + skips];
                }
                montab = tempTab;
            }
            ar1[i] = randomNum;
        }

        for (int i = 0; i < ar1.length; i++) {
            System.out.print(ar1[i] +" |" + "\t");
        }
    }
}
Mat
  • 1,440
  • 1
  • 18
  • 38