Java lotto simulation - java

I am writing a program simulating a lotto draw of six numbers between 1 and 45, a sample output is 3 7 12 27 43 28. But what I am trying to do is count the number of times adjacent numbers appear, for example 1 4 5 29 26 41 is a positive answer because 5 comes after 4.
What is the best way of doing that?
I have tried examples such as :
int adjacent=0;
for(int i =0; i<6; i++)
{
int t = test[i]+1;
test[i]=(int)(45*Math.random())+1;
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
This does not work.
What am I doing wrong?

I think you just have an order of operations problem
int adjacent=0;
for(int i =0; i<6; i++)
{
//test[i] hasn't been set yet
int t = test[i]+1;
test[i]=(int)(45*Math.random())+1;
//this comparison doesn't make a whole lot of sense
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
Change it around to something like this:
int adjacent=0;
for(int i =0; i<6; i++)
{
test[i]=(int)(45*Math.random())+1;
int t = -1;
//Make sure this comparison only happens after the second iteration
//to avoid index out of bounds
if ( i != 0 )
{
//Set t to the last number + 1 instead of trying to predict the future
t = test[i-1] + 1;
}
//Now this comparison makes a little more sense
//The first iteration will compare to -1 which will always be false
if(test[i]==t)
adjacent++;
System.out.print(test[i]+" ");
}
This can be further simplified to just this:
int adjacent=0;
for(int i =0; i<6; i++)
{
test[i]=(int)(45*Math.random())+1;
if(i != 0 && test[i]==(test[i-1]+1))
adjacent++;
System.out.print(test[i]+" ");
}

After you generate your 6 numbers and put them into an array. Use Arrays.sort(). You can then compare adjacent array entries.
You should also avoid using Random to generate you 6 numbers, because it can generate duplicates. This may or may not accurately simulate your lotto draw. Quoi's answer has a good suggestion for this.

I think you should shuffle it and take any five. Collections#Shuffle would help you, It permutes the specified list using a default source of randomness. All permutations occur with approximately equal likelihood.
List<Integer> list = ArrayList<Integer>();
list.add(1);
list.add(2);
Collections.shuffle(list);
Random rnd = new Random();
Integer[] result = new Integer[5];
result[0] = list.get(rnd.getNextInt(45));
result[1] = list.get(rnd.getNextInt(45));
result[2] = list.get(rnd.getNextInt(45));
result[3] = list.get(rnd.getNextInt(45));
result[4] = list.get(rnd.getNextInt(45));
It always gives you random values, then you should sort it to arrange it in order, say ascending.
Arrays.sort(result);
now you can write a loop to find out adjacent number.
int adjacent = 0;
for(int i=1; i<result.length;i++){
int prev = result[i-1];
int now = result[i];
if(prev+1 == now)
adjacent++;
}

You need to separate the generation of unique (hence the HashSet below to insure identity) random selections, sorting them, and then determining adjacency:
import java.util.HashSet;
import java.util.Arrays;
public class Lotto
{
public Lotto()
{
}
/**
* #param args
*/
public static void main(String[] args)
{
Lotto lotto = new Lotto();
lotto.randomizeSelections(5);
}
private void randomizeSelections(int numOfArrays)
{
for(int i = 0; i < numOfArrays; i++)
{
int[] selArry = new int[6];
//to insure that each random selection is unique
HashSet<Integer> idntySet = new HashSet<Integer>();
for(int j = 0; j < 6;)
{
int rndm = (int)(45 * Math.random()) + 1;
//add selection to the array only if it has not been randomized before
if(!idntySet.contains(rndm))
{
selArry[j] = rndm;
j++;
}
}
//sort the array for determing adjacency
Arrays.sort(selArry);
for(int j = 0; j < 6; j++)
{
int sel = selArry[j];
boolean isAdjcnt = (j > 0 && (sel == selArry[j - 1] + 1)) ? true : false;
System.out.println(i + "." + j + ".random = " + sel);
if(isAdjcnt) System.out.println("\tAdjacent");
}
}
}
}

Related

Drawing six random numbers without repetition on table /java

Hello I have with repetitions in drawing randoms. I tried to do this on tables but every time I have problem with comparing generated random number with numbers in table. Be carefull there because this code now is endless loop what is throwing ArrayIndexOutOfBoundsException. Do you have any ideas? To show you what I want to get is similar to polish TV show Lotto where they are drawing 6 random numbers written on balls without repetition.
I have seen topic where it was done on lists but it's possible on tables like that?
public static void main(String[] args) {
Lotto lot = new Lotto();
int[] table = new int[6];
Random random = new Random();
for(int i = 0; i < 6; i++) {
int numbers = random.nextInt(48) + 1;
for(int k = 0; k < 6; k++) {
if (table[k] != numbers) {
try {
table[i] = numbers;
} catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
} else {
i--;
}
}
}
Arrays.sort(table);
for (int m = 0; m < 6; m++) {
System.out.println(table[m]);
}
}
I suggest following approach:
// Get list of all number
List<Integer> all = new ArrayList<>();
for (int i = 1; i <= 48; i++) {
all.add(i);
}
//Shuffle it
Collections.shuffle(all);
//Take first 6
List<Integer> result = all.subList(0, 6);
There are two popular techniques, choose only items that are available or choose any possible and check if it has been chose. This answer chooses from possible numbers, check if the number has been chosen already. If it has not been chosen, it is added to the array. If it has been chosen, then the process is repeated.
for(int i = 0; i < 6; i++) {
boolean selected = false;
while(!selected){
selected = true;
int numbers = random.nextInt(48) + 1;
for(int k = 0; k <= i; k++) {
if (table[k] == numbers) {
selected = false;
break;
}
}
if(selected){
table[i] = numbers;
}
}
}
The usage for the techniques depends on how many samples you need compared to the population you are choosing from.
If you need to choose any six numbers between 1 and 1000000, then this technique will work better because the odds of repeating are small, but shuffling a million element list takes more calculations.
The other technique is more appropriate say if your possible numbers are small, for example if you had to pick 6 numbers between 1 and 7, then you would pick a lot of duplicates. So shuffling a list will be better.
In your range, 6 out of 49, the choose and repeat will be faster because most often you'll find a new number.
I would do it like this:
TreeSet<Integer> t = new TreeSet<>();
while (t.size()<6) {
t.add((int)(Math.random()*48+1));
}
TreeSet guarantees that only unique items will be put into target collection.
Try and model the real world and get your application to do what happens in real life. You have 48 balls, numbered 1 to 48. Let's make a collection of them:
List<Integer> ballsInTheMachine = new ArrayList<>(48);
for (int i = 1; i <= 48; i++)
ballsInTheMachine.add(i);
Using Java 8 Streams, you can also create the same list in a way that is supposedly more succinct:
List<Integer> ballsInTheMachine = IntStream.rangeClosed(1, 48)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Next, you pick 6 balls at random out of the 48:
Random rng = new Random();
List<Integer> ballsPicked = new ArrayList<>(6);
for (int i = 1; i <= 6; i++) {
int index = rng.nextInt(ballsInTheMachine.size());
Integer pickedBall = ballsInTheMachine.remove(index);
ballsPicked.add(pickedBall);
}
And now you have your 6 randomly chosen balls in the list ballsPicked.

Java: Print out each number in an array without printing its an repeats of that number?

Im trying to print out an array but only print out the distinct numbers in that array.
For example: if the array has {5,5,3,6,3,5,2,1}
then it would print {5,3,6,2,1}
each time i do it either i only print the non repeating numbers, in this example {6,2,1} or i print them all. then i didnt it the way the assignment suggested
the assignment wants me to check the array before i place a value into it to see if its there first. If not then add it but if so dont.
now i just keep getting out of bounds error or it just prints everything.
any ideas on what i should do
import java.util.Scanner;
public class DistinctNums {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int value;
int count = 0;
int[] distinct = new int[6];
System.out.println("Enter Six Random Numbers: ");
for (int i = 0; i < 6; i++)
{
value = input.nextInt(); //places users input into a variable
for (int j = 0; i < distinct.length; j++) {
if (value != distinct[j]) //check to see if its in the array by making sure its not equal to anything in the array
{
distinct[count] = value; // if its not equal then place it in array
count++; // increase counter for the array
}
}
}
// Displays the number of distinct numbers and the
// distinct numbers separated by exactly one space
System.out.println("The number of distinct numbers is " + count);
System.out.print("The distinct numbers are");
for (int i = 0; i < distinct.length; i++)
{
System.out.println(distinct[i] + " ");
}
System.out.println("\n");
}
}
Always remember - if you want a single copy of elements then you need to use set.
Set is a collection of distinct objects.
In Java, you have something called HashSet. And if you want the order to be maintained then use LinkedHashSet.
int [] intputArray = {5,5,3,6,3,5,2,1};
LinkedHashSet<Integer> set = new LinkedHashSet<Integer>();
//add all the elements into set
for(int number:intputArray) {
set.add(number);
}
for(int element:set) {
System.out.print(element+" ");
}
You can make this using help array with lenght of 10 if the order is not important.
int [] intputArray = {5,5,3,6,3,5,2,1};
int [] helpArray = new int[10];
for(int i = 0; i < intputArray.length ; i++){
helpArray[intputArray[i]]++;
}
for(int i = 0; i < helpArray.length ; i++){
if(helpArray[i] > 0){
System.out.print(i + " ");
}
}

Generate random numbers without duplicates using arrays only

I want to fill an array of size X with random integers from 0 to X with no duplicates. The catch is I must only use arrays to store the collections of int, no ArrayLists. How do I go about implementing this?
I don't understand why I can't seem to get this. But this is my most recent bit of code that fills the list but allows for duplicates.
System.out.print("Zero up to but excluding ");
int limit = scanner.nextInt();
// create index the size of the limit
int [] index = new int[limit];
for(int fill=0;fill<limit;fill+=1){
index[fill] = (limit);
}
int randomNumber = 0;
Random rand = new Random();
int [] randoms = new int[limit];
boolean flag = true;
// CODE TO NOT PRINT DOUBLES
for (int z=0;z<limit;z+=1){
randomNumber = rand.nextInt(limit);
int i=0;
while (i<limit){
if (index[i] == randomNumber){
flag = true;
}
else {
flag = false;
break;
}
i+=1;
}
if (flag == false){
randoms[z] = randomNumber;
index[z] = randomNumber;
}
}
System.out.println("Randoms: "+java.util.Arrays.toString(randoms));
Here's one way to do it:
Create an array of length N
Fill it from 0 to N-1
Run a for loop and swap randomly 2 indices
Code:
// Step 1
int N = 10;
int[] array = new int[N];
// Step 2
for(int i=0; i < N; i++)
array[i] = i;
// Step 3
for(int i=0; i < N; i++) {
int randIndex = (int) (Math.random() * N);
int tmp = array[i];
array[i] = array[randIndex];
array[randIndex] = tmp;
}
Why not rephrase the problem to shuffling an array of integers. First fill the array monotonically with the numbers 0 to X. Then use the Random() function to select one of the X numbers to exchange with the number in position 0. Repeat as many times as you may like. Done.
Here is your bug:
while (i<limit){
if (index[i] == randomNumber){
flag = true;
}
else {flag = false;break;} <--- rest of the array is skipped
i+=1;
}
after you generated a new number, you start to check for equality , however once you find that randomNumber!=index[i] (else statement) you break out of the while. look this: actual array is 3,4,5,1 your new number is 5, you compare it to 3 just to find out that they different so flag is set to false and break out happens.
Consider using another array filled with elements in order from 0 to X. Then, with this array, shuffle the elements around. How do you go about this? Use a loop to traverse through every single element of the array, and for each iteration, choose a random number from 0 to array.length - 1 and switch the elements at the index you're currently on and the random index. This is how it would look like,
In your main, you would have an array initialized by doing this,
int[] arr = new int[10];//10 can be interchangeable with any other number
for(int i = 0; i < arr.length; i++){
arr[i] = i;
}
shuffleArray(arr);
And the shuffle method would look like this,
public int[] shuffleArray(int[] arr){
Random rand = new Random();
for(int i = 0; i < arr.length; i++){
int r = rand.nextInt(arr.length);//generate a random number from 0 to X
int k = arr[i];
arr[i] = arr[r];
arr[r] = k;
}
}

Weighted random numbers in 2D Array - Processing

I would like to fill a 3x3 2D array with values 1,2,3.
I need each number to appear for a given times.
For example:
1 to appear 2 times
2 to appear 4 times
3 to appear 3 times
What I need is to store this numbers to array in a random position.
For Example:
1,2,2
3,2,2
1,3,3
I already did this in a simple way using only 2 different numbers controlled by a counter. So I loop through the 2D array and applying random values of number 1 and number 2.
I'm checking if the value is 1 and add it in the counter and the same with number 2. if one of the counter exceeds the number I have set as the maximum appear times then it continues and applies the other value.
Is there any better approach to fill the 3 numbers in random array position?
See code below:
int [][] array = new int [3][3];
int counter1 =0;
int counter2 =0;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
array[i][j] = (int)random(1, 3); //1,2
if (arrray[i][j]==1) {
counter1++;
} else if (array[i][j] ==2) {
counter2++;
}
//if it is more than 5 times in the array put only the other value
if (counter1>5) {
array[i][j] = 2;
}
//if it is more than 4 times in the array put only the other value
else if (counter2>4) {
array[i][j] = 1;
}
}
}
I finally did this according to this discussion:
How can I generate a random number within a range but exclude some?, with 1D array for tesing, but it does not always works.
Please see attached code:
int []values = new int[28];
int counter1=0;
int counter2=0;
int counter3=0;
for (int i=0; i<values.length; i++) {
if (counter1==14) {
ex = append(ex, 5);
}
if (counter2==4) {
ex =append(ex, 6);
}
if (counter3==10) {
ex =append(ex, 7);
}
values[i] = getRandomWithExclusion(5, 8, ex);
if (values[i]==5) {
counter1++;
} else if (values[i] ==6) {
counter2++;
} else if (values[i] ==7) {
counter3++;
}
}
int getRandomWithExclusion(int start, int end, int []exclude) {
int rand = 0;
do {
rand = (int) random(start, end);
}
while (Arrays.binarySearch (exclude, rand) >= 0);
return rand;
}
I would like to fill the 1D array with values of 5,6 or 7. Each one a specific number. Number 5 can be added 14 times. Number 6 can be added 4 times. Number 7 can be added 10 times.
The above code works most of the times, however somethimes it does not. Please let me know if you have any ideas
This is the Octave/Matlab code for your problem.
n=3;
N=n*n;
count = [1 2; 2 4; 3 3];
if sum(count(:,2)) ~= N
error('invalid input');
end
m = zeros(n, n);
for i = 1:size(count,1)
for j = 1:count(i,2)
r = randi(N);
while m(r) ~= 0
r = randi(N);
end
m(r) = count(i,1);
end
end
disp(m);
Please note that when you address a 2D array using only one index, Matlab/Octave would use Column-major order.
There are a ton of ways to do this. Since you're using processing, one way is to create an IntList from all of the numbers you want to add to your array, shuffle it, and then add them to your array. Something like this:
IntList list = new IntList();
for(int i = 1; i <= 3; i++){ //add numbers 1 through 3
for(int j = 0; j < 3; j++){ add each 3 times
list.append(i);
}
}
list.shuffle();
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
array[i][j] = list.remove(0);
}
}
You could also go the other way: create an ArrayList of locations in your array, shuffle them, and then add your ints to those locations.

Generating Random Permutation Uniformly in Java

Anyone know of a fast/the fastest way to generate a random permutation of a list of integers in Java. For example if I want a random permutation of length five an answer would be 1 5 4 2 3, where each of the 5! possibilities is equally likely.
My thoughts on how to tackle this are to run a method which generates random real numbers in an array of desired length and then sorts them returning the index i.e. 0.712 0.314 0.42 0.69 0.1 would return a permutation of 5 2 3 4 1. I think this is possible to run in O(n^2) and at the moment my code is running in approximately O(n^3) and is a large proportion of the running time of my program at the moment. Theoretically this seems OK but I'm not sure about it in practice.
Have you tried the following?
Collections.shuffle(list)
This iterates through each element, swapping that element with a random remaining element. This has a O(n) time complexity.
If the purpose is just to generate a random permutation, I don't really understand the need for sorting. The following code runs in linear time as far as I can tell
public static int[] getRandomPermutation (int length){
// initialize array and fill it with {0,1,2...}
int[] array = new int[length];
for(int i = 0; i < array.length; i++)
array[i] = i;
for(int i = 0; i < length; i++){
// randomly chosen position in array whose element
// will be swapped with the element in position i
// note that when i = 0, any position can chosen (0 thru length-1)
// when i = 1, only positions 1 through length -1
// NOTE: r is an instance of java.util.Random
int ran = i + r.nextInt (length-i);
// perform swap
int temp = array[i];
array[i] = array[ran];
array[ran] = temp;
}
return array;
}
And here is some code to test it:
public static void testGetRandomPermutation () {
int length =4; // length of arrays to construct
// This code tests the DISTRIBUTIONAL PROPERTIES
ArrayList<Integer> counts = new ArrayList <Integer> (); // filled with Integer
ArrayList<int[]> arrays = new ArrayList <int[]> (); // filled with int[]
int T = 1000000; // number of trials
for (int t = 0; t < T; t++) {
int[] perm = getRandomPermutation(length);
// System.out.println (getString (perm));
boolean matchFound = false;
for(int j = 0; j < arrays.size(); j++) {
if(equals(perm,arrays.get(j))) {
//System.out.println ("match found!");
matchFound = true;
// increment value of count in corresponding position of count list
counts.set(j, Integer.valueOf(counts.get(j).intValue()+1));
break;
}
}
if (!matchFound) {
arrays.add(perm);
counts.add(Integer.valueOf(1));
}
}
for(int i = 0; i < arrays.size(); i++){
System.out.println (getString (arrays.get (i)));
System.out.println ("frequency: " + counts.get (i).intValue ());
}
// Now let's test the speed
T = 500000; // trials per array length n
// n will the the length of the arrays
double[] times = new double[97];
for(int n = 3; n < 100; n++){
long beginTime = System.currentTimeMillis();
for(int t = 0; t < T; t++){
int[] perm = getRandomPermutation(n);
}
long endTime = System.currentTimeMillis();
times[n-3] = (double)(endTime-beginTime);
System.out.println("time to make "+T+" random permutations of length "+n+" : "+ (endTime-beginTime));
}
// Plotter.plot(new double[][]{times});
}
There is an O(n) Shuffle method that is easy to implement.
Just generate random number between 0 and n! - 1 and use
the algorithm I provided elsewhere (to generate permutation by its rank).

Categories