don't random number that are being random before - java

I know how to random number using java Random class.
This will random a number between 0-13 13 times;
public static void main(String[] args) {
int ctr = 13;
int randomNum = 0;
while(ctr != 0) {
Random r = new Random();
randomNum = r.nextInt(13);
ctr--;
System.out.println(ctr +": " + randomNum);
}
}
Question
-I would like to random a number between 0-13 for 13 times
-If the first random number is e.g(5),then my second random number will random any number from 0-13 again EXCLUDING 5;
If the second random number is e.g(4),then my third random number will random any number from 0-13 again EXCLUDING 5 and 4;
etc..
is there a way to do it?

Do this:
Create a List of size 13
Fill it with numbers 0-12
Shuffle the List using the JDK Collections utility method
Use the numbers in the shuffled order (by just iterating over the List)
In code:
List<Integer> nums = new ArrayList<Integer>();
for (int i = 0; i < 13; i++)
nums.add(i);
Collections.shuffle(nums);
for (int randomNum : nums)
System.out.println(randomNum); // use the random numbers

I'd fill a list, shuffle it, and then iterate it, guaranteeing a different number each time:
public static void main(String[] args) {
int ctr = 13;
List<Integer> list = new ArrayList<>(ctr);
for (int i = 0; i < ctr; ++i) {
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < ctr; ++i) {
System.out.println(ctr + ": " + list.get(i));
}
}

Question -I would like to random a number between 0-13 for 13 times
I would start with a List and Collections.shuffle(List) and a Random with something like -
Random rand = new Random();
List<Integer> al = new ArrayList<>();
for (int i = 0; i < 14; i++) {
al.add(i);
}
Collections.shuffle(al, rand);
System.out.println(al);
Or, if using Java 8+, an IntStream.range(int, int) to generate the List. And you could use a forEachOrdered to display (and in either version, you cold use the Collections.shuffle with an implicit random) like
List<Integer> al = IntStream.range(0, 13).boxed().collect(Collectors.toList());
Collections.shuffle(al);
al.stream().forEachOrdered(System.out::println);

The answers recommending shuffle show the right way, as it is elegant and fast.
Just for the sake of completeness: you can also slightly alter your code. Add any random number found to an array. Then check the next random number if it is already in the array. If yes, drop the number and get a new one. Do this until the array is filled with 13 numbers.
Like this:
List<Integer> numbers = new ArrayList<Integer>();
Random r = new Random();
while (numbers.size() < 14) {
randomNum = r.nextInt(13);
if (!numbers.contains(randomNum)) {
numbers.add(randomNum);
}
}

you can use Set to avoid having duplicate
Code:
Set<Integer> set1 = new LinkedHashSet<>();
int ctr = 13;
int randomNum = 0;
while (ctr == 13) {
Random r = new Random();
randomNum = r.nextInt(13);
set1.add(randomNum);
System.out.print(randomNum + " ");
if (set1.size() >= 13) {
ctr = 12;
}
}
System.out.println("");
set1.forEach(i -> System.out.print(" " + i));
output:
4 11 11 11 5 1 9 12 5 7 5 2 9 10 1 7 10 3 11 8 9 3 12 9 2 6 7 10 12 3 11 1 10 3 6 2 0
4 11 5 1 9 12 7 2 10 3 8 6 0

ArrayList<Integer> nums = new ArrayList<Integer>();
Random generator = new Random();
for (int i = 0; i < 14; i++) {
nums.add(i);
}
for (int i = 0; i < 14; i++) {
int size = nums.size();
int chosen = generator.nextInt(size);
System.out.println(nums.get(chosen) + " ");
nums.remove(chosen);
}

Related

Finding distinct numbers in queue using java

I want to find distinct numbers in a queue but I can't use anything but a queue such as an array or etc.
Here is my code:
Queue distinct = new Queue(10);
Queue distincttemp1 = new Queue(10);
int count=0;
Random rnd = new Random();
boolean flag=true;
for (int i = 0; i < 10; i++) {
int x = rnd.nextInt(9);
System.out.print(x + " ");
distinct.enqueue(x);
}
System.out.println("");
I couldn't find a solution finding how many numbers are repeated except adding every each number to a queue. It should be simple with a few loops. Can you help me find an algorithm?
Input and output should be like this:
Queue: 4 8 5 8 4 3 2 8
Output: 5
You can use Queue and keep track of distinct numbers using HashSet because sets do not allow duplicate values.
Queue<Integer> distinct = new LinkedList<>();
Set<Integer> set = new HashSet();
Random random = new Random();
int number;
for(int i=0; i<10; i++){
number = random.nextInt(9);
System.out.print(number+" ");
distinct.add(number);
set.add(number);
}
System.out.println("Distinct "+set.size());
According to your example, your numbers are between 0 and 8. That means that a single Integer variable is more than enough to mark an occurrence of any of your numbers (we need only 9 bits for that).
Explanation
Keep track of distinct values
If a value x is generated, then an xth bit in the binary representation of the "marker" variable is set to 1.
int marker = 0;
...
int x = random.nextInt(9);
System.out.print(x + " ");
marker |= (1 << x);
...
Number of distinct values
Then, once the loop is complete, number of set bits in the marker corresponds to the number of different values generated in the loop.
...
System.out.println(Integer.bitCount(marker));
...
Full Code
Random random = new Random();
int marker = 0;
for (int i = 0; i < 10; i++) {
int x = random.nextInt(9);
System.out.print(x + " ");
marker |= (1 << x);
queue.add(x);
}
System.out.println("\n" + Integer.bitCount(marker));
4 7 1 4 0 1 4 0 7 8
5

Generating random Numbers , but it must be Generated with Unique numbers without replications

int[] drawNumbers = new int[10];//Array With 10 Random Numbers USED for DRAWN NUMBERS
String x = "Drawn Numbers: ";
List<Ticket> ticketWon ;
do{
//GENERATING 10 Random Numbers
for (int i = 0; i <= drawNumbers.length -1 ; i++) {
Random r = new Random();
drawNumbers[i] = r.nextInt(99) + 1;
x += drawNumbers[i] + " ";
}
}
I'm trying to generate 10 random numbers that must be random generated and Unique. My problem is that with Random r = new Random() there are times that replicated numbers are shown. How can i generate 10 random numbers from range 1 to 99 without replications?
Problem is for a Lottery System
I would like to use Collection.Shuffle but I'm not that sure how it should be implemented.
Here is an alternative way to achieve your desired result. We populate a list with values 1 to 99. Then we shuffle the list and grab the first 10 values:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<100; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
for (int i=0; i<10; i++) {
System.out.println(list.get(i));
}
}
You won't have to import/directly deal with Random, which is a plus. However, as pointed out by #Voicu (in the comments), shuffle does indeed utilize random:
public static void shuffle(List<?> list) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
}
private static Random r;
You can broadly think of this problem as having a deck of cards numbered from 1 to 99, and you want to pick 10 of those cards. The solution would be to, programmatically, create that deck and then randomly select from that deck and remove from the deck.
We can model the deck as a List of Integers and populate that List with entries from 1 to 99 with something like this:
List<Integer> deck = new ArrayList<Integer>();
for( int i=1; i<=99; i++ ){
deck.add( i );
}
We then need to pick a random card between the 0th card (lists are numbered starting at 0) and the number of elements in the list:
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
And repeat that 10 times, doing something with the "card" (say, putting it into an array, or another list, or whatever:
int drawNumbers = new int[10];
for( int co=0; co<10; co++ ){
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
drawNumbers[co] = card;
}
Use Set<Integer>.
Set<Integer> set = new HashSet<Integer>();
int[] drawNumbers = new int[10];
Random r = new Random();
for(int i=0; i<10; i++)
{
drawNumbers[i] = r.nextInt(99) + 1;
while(set.contains(drawNumbers[i]))
drawNumbers[i] = r.nextInt(99) + 1;
set.add(drawNumbers[i]);
}
I'd generate random numbers and save them to a Set until I get 10 numbers. Then create a list from it, shuffle it, and then take numbers from it.
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
Set<Integer> randoms = new HashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
// Now shuffle them:
List<Integer> shuffledRandom = new ArrayList<>(randoms);
Collections.shuffle(shuffledRandom);
EDIT:
As #MarkPeters noted in the comments, using a LinkedHashSet would eliminate the need to shuffle:
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
LinkedHashSet<Integer> randoms = new LinkedHashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
It would be easier to use a list so you could check if it already contains the number and re-generate if it does.
List<Integer> drawNumbers = new ArrayList<Integer>();
Random r = new Random();
int newNumber = -1;
do
{
newNumber = r.nextInt(99) + 1;
} while(drawNumbers.contains(newNumber); //Make sure the number is not already in the list.
Then put this in a loop to repeat 10 times.

Bug in random numbers in Android

TreeSet myNumbers = new TreeSet();
Random randGen = new Random();
for (int i = 1; i <= 16; i++) {
// number generation here
int randNum = randGen.nextInt(16 - 1) + 1;
for (;;) {
if (myNumbers.add(randNum))
break;
else
randNum = randGen.nextInt();
}
Toast.makeText(getApplicationContext(), "" + randNum, 100).show();
}
I want to generate random numbers between 1 and 16 and the same number should not be repeated.
The code above gives me output like:
2, 5, 7, 9, 1, 4, 10.4109446, -448831, 98824724, 11, 13, ...
I do not know why it gives me random numbers not in the 1-16 range, please help me out.
You're only generating one number in the range 1-15. You're then generating subsequent numbers with just nextInt:
if (myNumbers.add(randNum))
break;
else
randNum = randGen.nextInt();
That should be:
if (myNumbers.add(randNum))
break;
else
randNum = randGen.nextInt(16) + 1;
... and fix the initial call to nextInt to remove the "-1". (You don't need the 16 - 1, as explained in Josh's answer.)
To generate a random number in a range, it is like:
int min = ...
int max = ...
int randNumber = min + new Random().nextInt(max - min + 1);
So in your example where you want to generate a random number from [1, 16], it would look like:
int randNumber = 1 + new Random().nextInt(16 - 1 + 1);
Or if you choose to simplify:
int randNumber = 1 + new Random().nextInt(16);
Also, you should really be using a while loop instead of an infinite for loop:
final TreeSet<Integer> myNumbers = new TreeSet<>();
final Random rand = new Random();
for(int i = 0; i < 16; i++){
int n = 1 + rand.nextInt(16);
while(!myNumbers.add(n))
n = 1 + rand.nextInt(16);
}
It's not a big issue, if you are working in the range 1-16, but your code results in rejection of some randomly drawn numbers, if they have already been picked before.
In your solution, the expected value of nextInt() calls is proportional to n log(n), where n is the number of total elements you want to shuffle (16 in your case) – and the actual values can be much higher for a single run. You might consider using a more efficient implementation.
A solution which always uses only n calls:
ArrayList<Integer> originalNumbers = new ArrayList<Integer>();
Random randGen = new Random();
int max = 16;
for (int i = 1; i <= max; i++) {
// initializing ordered list so it becomes 1, 2, ..., max
originalNumbers.add(i);
}
for (int i = max; i >= 1; i--) {
// picking a random number from the ordered list, and swapping it
// with the last unpicked element which is placed closer to the
// end of list, where the already picked numbers are stored
int randNum = randGen.nextInt(i);
Collections.swap(originalNumbers, i - 1, randNum);
Toast.makeText(getApplicationContext(), "" + originalNumbers[i - 1], 100).show();
}

How to generate 100 random 3 digit numbers in java?

I need to generate 100 random 3 digit numbers. I have figured out how to generate 1 3 digit number. How do I generate 100? Here's what I have so far...
import java.util.Random;
public class TheNumbers {
public static void main(String[] args) {
System.out.println("The following is a list of 100 random" +
" 3 digit numbers.");
Random rand= new Random();
int pick = rand.nextInt(900) + 100;
System.out.println(pick);
}
}
The basic concept is to use a for-next loop, in which you can repeat your calculation the required number of times...
You should take a look at The for Statement for more details
Random rnd = new Random(System.currentTimeMillis());
for (int index = 0; index < 100; index++) {
System.out.println(rnd.nextInt(900) + 100);
}
Now, this won't preclude generating duplicates. You could use a Set to ensure the uniqueness of the values...
Set<Integer> numbers = new HashSet<>(100);
while (numbers.size() < 100) {
numbers.add(rnd.nextInt(900) + 100);
}
for (Integer num : numbers) {
System.out.println(num);
}
If you adapt the following piece of code to your problem
for(int i= 100 ; i < 1000 ; i++) {
System.out.println("This line is printed 900 times.");
}
, it will do what you want.
Try for loop
for(int i=0;i<100;i++)
{
int pick = rand.nextInt(900) + 100;
System.out.println(pick);
}
Using the answer to the question Generating random numbers in a range with Java:
import java.util.Random;
public class TheNumbers {
public static void main(String[] args) {
System.out.println("The following is a list of 100 random 3 digit nums.");
Random rand = new Random();
for(int i = 1; i <= 100; i++) {
int randomNum = rand.nextInt((999 - 100) + 1) + 100;
System.out.println(randomNum);
}
}
This solution is an alternative if the 3-digit numbers include numbers that start with 0 (if for example you are generating PIN codes), such as 000, 011, 003 etc.
Set<String> codes = new HashSet<>(100);
Random rand = new Random();
while (codes.size() < 100)
{
StringBuilder code = new StringBuilder();
code.append(rand.nextInt(10));
code.append(rand.nextInt(10));
code.append(rand.nextInt(10));
codes.add(code.toString());
}
for (String code : codes)
{
System.out.println(code);
}

Generating random numbers with identical pairs between 1 to 8?

Like my question, i need to generate random numbers that have identical pairs between a range. i have tried to generate random numbers and stored in an array but the numbers are repeating more than twice. i have 16 random numbers to be generated in the range. Any idea how to make it generate only identical pairs random number?
The following will do the job I think :
import java.util.*;
class Randoms {
public static void main(String[] args) {
List<Integer> randoms = new ArrayList<Integer>();
Random randomizer = new Random();
for(int i = 0; i < 8; ) {
int r = randomizer.nextInt(8) + 1;
if(!randoms.contains(r)) {
randoms.add(r);
++i;
}
}
List<Integer> clonedList = new ArrayList<Integer>();
clonedList.addAll(randoms);
Collections.shuffle(clonedList);
int[][] cards = new int[8][];
for(int i = 0; i < 8; ++i) {
cards[i] = new int[]{ randoms.get(i), clonedList.get(i) };
}
for(int i = 0; i < 8; ++i) {
System.out.println(cards[i][0] + " " + cards[i][1]);
}
}
}
One sample run of the above gives :
1 2
8 6
4 3
3 7
2 8
6 1
5 5
7 4
Hope that helps.
Generally, if you put the numbers you wish to generate in an array (in your case, an array of length 16 with two each of 1, 2, ..., 8), then randomly permute the array, you will get what you want. You can randomly permute the array using code here.
I believe this clearly shows you how to approach the problem:
public static List<Integer> shuffled8() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 1; i <= 8; i++) {
list.add(i);
}
Collections.shuffle(list);
return list;
}
public static void main(String[] args) {
List<Integer> first = shuffled8();
List<Integer> second= shuffled8();
for (int i = 0; i < 8; i++) {
System.out.println(first.get(i) + " " + second.get(i));
}
}
shuffled8 simply returns a list of numbers 1 to 8 shuffled. Since you need two of such lists, you invoke it twice, and store it in first and second. You then pair first.get(i) with second.get(i) to get the properties that you want.
To generalize this, if you need triplets, then you just add List<Integer> third = shuffled8();, and then first.get(i), second.get(i), third.get(i) is a triplet that has the properties that you want.
I have made this way :
Random random = new Random();
List<Integer> listaCartoes = new ArrayList<Integer>();
for(int i=0; i<8;)
{
int r = random.nextInt(8) + 1;
if(!listaCartoes.contains(r))
{
listaCartoes.add(r);
listaCartoes.add(r);
++i;
}
}
Collections.shuffle(listaCartoes);
Hope it helps ^_^

Categories

Resources