I have been set a task to create a Android app in which the user chooses four numbers (1-6), I then compare it against four randomly generated numbers and then tell them how many of there numbers were correct.
My problem is that whenever I generate any numbers the first three shown are always the same, except from the last number.
Random a1 = new Random();
random1 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random1.add(a1.nextInt(5)+ 1);
}
Random a2 = new Random();
random2 = new ArrayList<Integer>();
for (int index = 0; index < 6; index++)
{
random2.add(a2.nextInt(5)+ 1);
}
This is the code I use for the random number generation, each number uses the exact same code, which makes it even more confusing, if they were all the same I could understand that because it's the same code it generates the same number or something along those lines but the last one is always different, any help would always be appreciated.
Try not create two Random instances but reuse single instance instead. May be two Randoms with close seeds produces close output.
Check if below code works for you. Code taken from http://www.javapractices.com/topic/TopicAction.do?Id=62. Modified according to your requirements.
public final class RandomRange {
public static final void main(String... aArgs) {
int START = 1;
int END = 6;
Random random = new Random();
List<Integer> first = new ArrayList<Integer>();
List<Integer> second = new ArrayList<Integer>();
for (int idx = 1; idx <= END; ++idx) {
first.add(showRandomInteger(START, END, random));
second.add(showRandomInteger(START, END, random));
}
System.out.println(first);
System.out.println(second);
first.retainAll(second);//Find common
System.out.println(first);
}
private static int showRandomInteger(int aStart, int aEnd, Random aRandom) {
if (aStart > aEnd) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
// get the range, casting to long to avoid overflow problems
long range = (long) aEnd - (long) aStart + 1;
// compute a fraction of the range, 0 <= frac < range
long fraction = (long) (range * aRandom.nextDouble());
int randomNumber = (int) (fraction + aStart);
return randomNumber;
}
}
Related
I'm trying to make a small program that allows you to generate a certain amount of numbers within a range, but it does not work as expected.
For example, if I ask the program to generate 3 random numbers between 5 and 10 it gives me 5 random numbers between 0 and 5.
private void jFillActionPerformed(java.awt.event.ActionEvent evt) {
int intInput1;
int intInput2;
int intInput3;
int i;
int RandomNumber;
intInput1 = Integer.parseInt(txtInput1.getText());
intInput2 = Integer.parseInt(txtInput2.getText());
intInput3 = Integer.parseInt(txtInput3.getText());
int ListSize = (intInput3) + 1;
Random rnd = new Random();
for (i = 0; i <= ListSize; i++)
{
RandomNumber = rnd.nextInt((intInput2 - intInput1) + 1);
fill.addElement(RandomNumber);
lstNumbers.setModel(fill);
}
Simply always add 5 (or more specifically - intInput1 in your case as it seems it's lower range value) to generated numbers so it will be in the range you need (0+5=5, 5+5=10 so it will be in range 5,10)
Here an IntStream you can later than use limit to set the amount of numbers you want.
public static IntStream numbersBetween(int from, int to){
return new Random().ints().map(e -> Math.abs(e % ((to+1) - from)) + from);
}
so far in the program the values were searched randomly, but I want to modify the program to search for random numbers in a given range. Generally speaking, My point is that the draw should be from the given range (from-to), and not up to 1000 random numbers as in the above code, so my question is:
How can I pass the value from and to random: rand.nextInt (?) so that the numbers are randomly drawn in a given range. so I generally need to get a printout from the program like in the question: expected output
// Create array to be searched
final int[] arrayToSearch = new int[20];
Random rnd = new Random();
for (int i = 0; i < arrayToSearch.length; i++)
arrayToSearch[i] = rnd.nextInt(1000);
System.out.println(Arrays.toString(arrayToSearch));
final int PARTITIONS = 4;
Thread[] threads = new Thread[PARTITIONS];
final int[] partitionMin = new int[PARTITIONS];
final int[] partitionMax = new int[PARTITIONS];
for (int i = 0; i < PARTITIONS; i++) {
final int partition = i;
threads[i] = new Thread(new Runnable() {
#Override
public void run() {
// Find min/max values in sub-array
int from = arrayToSearch.length * partition / PARTITIONS;
int to = arrayToSearch.length * (partition + 1) / PARTITIONS;
int min = Integer.MAX_VALUE,
max = Integer.MIN_VALUE;
for (int j = from; j < to; j++) {
min = Math.min(min, arrayToSearch[j]);
max = Math.max(max, arrayToSearch[j]);
}
partitionMin[partition] = min;
partitionMax[partition] = max;
});
so far:
partition 0: from=0, to=5, min=23, max=662 //the draw in the range 0-5, draw is outside the specified range
expected output:
partition 1: from=0, to=5, min=1, max=3 // the draw takes place within the given range 0 to 5
partition 2: from=20, to=30, min=22, max=29 //the draw takes place within the given range 20 to 30
How can I pass the value from and to random: rand.nextInt (?) so that the numbers are randomly drawn in a given range
Try it like this. This will generate values between from and to inclusive.
int from = -100;
int to = 100;
int draw = ThreadLocalRandom.current().nextInt(from, to);
You can actually generate your own Supplier to just get random numbers in a specified range.
The BiFunction returns a Supplier. And the Supplier can be called to get the a random number in the range.
BiFunction<Integer, Integer, IntSupplier> rndGen = (f,
t) -> () -> ThreadLocalRandom.current().nextInt(f, t+1);
IntSupplier rnd = rndGen.apply(from,to);
So each time rnd.getAsInt() is invoked, you will get a number in the desired range.
Note: There are of course methods that do this pretty much automatically. But I presumed you wanted to work out the logic of finding min and max yourself so I did not include those.
Class Random has method ints (long streamSize, int randomNumberOrigin, int randomNumberBound) to generate IntStream of random numbers in the given range, and then the summary statistics may be collected for such stream:
static void printMinMax(int size, int from, int to) {
IntSummaryStatistics stats = new Random()
.ints(size, from, to)
.summaryStatistics();
System.out.printf("min = %d, max = %d%n", stats.getMin(), stats.getMax());
}
Test:
printMinMax(20, 20, 200); // min = 30, max = 198
Create a random number of your choosing however you want.
If it's under your From value, add your From value to it.
If it's over your To value mod it by your To value.
I have to generate 5 digit random number , without having any zeros in it. I have tried with below code, sometimes it works and sometimes it doesn't. Is there any better way to do this?
public Integer generateLastFiveSequenceNumbers()
{
Random ranndomNumber = new Random();
Random replaceNumber = new Random();
Integer fiveDigitRanndomNumber = 11111 + ranndomNumber.nextInt(99999);
Integer replaceZeroNumber = 1 + replaceNumber.nextInt(9);
String tempValidation = fiveDigitRanndomNumber.toString();
char[] ch = tempValidation.toCharArray();
for(int i = 0 ; i < ch.length-1 ;i++)
{
if(ch[i]=='0')
{
ch[i] = '1';
}
}
String newValue = new String(ch);
Integer finalNumber = Integer.parseInt(newValue);
return finalNumber;
}
While your intended method of replacing zero digits with additional random numbers is reasonably sound in theory, you are not using the replacement digits anywhere. Your final verification loops over all but the last index, which is the error that causes zeros to appear sometimes. Replacing all zeros with just ones defeats much of the randomness since ones are now twice as likely to appear as any other digit.
A simpler solution might be to concatenate five random digits that are guaranteed to be in the valid range to begin with. Since your return value is a number, you don't need to deal with strings at all:
public Integer generateLastFiveSequenceNumbers()
{
Random ranndomNumber = new Random();
int result = 0;
for(int i = 0; i < 5; i++) {
result = result * 10 + (randomNumber.nextInt(9) + 1);
}
return result;
}
Your idea above with an int stream:
public static int generateLastFiveSequenceNumbers( ) {
Random r = new Random();
return r.ints(11111, 99999+1)
.filter(i->!String.valueOf(i).contains("0"))
.limit(1).findFirst().getAsInt();
}
Combination of the above answers:
Integer rand = Integer.valueOf(
IntStream.rangeClosed(1,5) // repeat 5 times.
.map(x -> { return new Random().nextInt(9) + 1;} // Random between 1 and 9.
.boxed() // Convert to a stream of Integer objects.
.map(String::valueOf) // Convert from Integer to String.
.collect(Collectors.joining())); // Concat them all together.
System.out.println(rand);
public static void generateRandom(int howMany) {
int c = 0;
int multiplicator = 1;
Integer number = 0;
while (c < howMany) {
number += multiplicator * getRandom();
multiplicator = multiplicator * 10;
c++;
}
System.out.println(number);
}
public static Integer getRandom() {
Random rand = new Random();
return rand.nextInt(9)+1;
}
This solution uses a BiFunction (java 8 only).
BiFunction<Integer,Integer,Integer> customRandom = (min,max) -> {
int val = 0;
Random r = new Random();
do {
val = min + r.nextInt(max);
} while (String.valueOf(val).contains("0")); // skip randoms containing '0'
return val;
}
Usage:
System.out.println(customRandom.apply(10000,99999));
My question concerns the Java RNG; use the following code:
for (int s = 0; s < 600; s++) {
Random r = new Random(s);
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}
This will result in 600 random numbers being generated. I know this is a bit odd, but I require a new random number generator each time in my actual project. The seed I receive is sequential. The first random double that is generated is extremely close for any of the seeds, is this because of the linear congruential formula that is used as initialization?
The second double generated actually looks like it is actually properly random, is this safe to assume so? Is it OK practice to first generate an unused random number, and after that moment start to use it for the actual reason it was created?
Thank you in advance
EDIT:
Let me clarify:
int possibleRoutes = 7;
void handlePacket(Packet p) {
int chosenRoute = p.hash % possibleRoutes;
// ...Other code...
}
vs.
int possibleRoutes = 7;
void handlePacket(Packet p) {
Random r = new Random(p.hash);
int chosenRoute = r.nextInt() % possibleRoutes;
// ...Other code...
}
}
vs.
int possibleRoutes = 7;
void handlePacket(Packet p) {
Random r = new Random(p.hash);
r.nextInt();
int chosenRoute = r.nextInt() % possibleRoutes;
// ...Other code...
}
A guarantee is that each packet must take the same route. The packet hash is inherently sequential at the moment. There are too many possible hashes to keep any type of state to speed this up.
why do you give a special number as a seed? just leave it empty, so the Random constructor will choose a seed for you.
for (int s = 0; s < 600; s++) {
Random r = new Random();
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}
see Role of seed in random number generation
Call the default constructor which uses the nanoTime as a seed. This way you won't need to generate a new seed to create your object each iteration.
//loop through number of numbers needed
for(int i = 0; i < 100; i +)
//Calls default constructor
Random r = new Random();
System.out.println(r.nextDouble()*.5);
An alternative is to use a master random to seed all the subsiduary randoms in the loop:
Random masterRand = new Random();
for (int s = 0; s < 600; s++) {
Random r = new Random(masterRand.nextLong());
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}
Hi I am having some problems with using random numbers inside of loops.
private void SetMines()
{
Random randRowGen = new Random();
Random randColGen = new Random();
int mineCount = 0;
int numMines = (ROWS * COLUMNS)* (int)0.156;
while(mineCount <= numMines)
{
int randRow = randRowGen.nextInt(ROWS)+1;
int randCol = randColGen.nextInt(COLUMNS)+1;
grid[randRow][randCol] = new Character('*');
mineCount++;
}
}
Here is my method it is going through an array size 25 * 25 and picking random spots and putting "mines" there. The only problem is it only selects one location to put a "mine" in and it needs to put 97 mines in random spots.
Any help will be appreciated thanks!!
Your numMines calculation will always return 0, because when you cast a double that is less than 1 to an int, it will be set to 0, which means that the statement in your while loop will only be run a single time, hence only a single mine being placed.
The problem isn't Random, it's int numMines = (ROWS * COLUMNS)* (int)0.156;. Have you checked what that value is? It's 0, because (int) 0.156 equals 0.
Perhaps you want int numMines = (int) ((double) 0.156 * ROWS * COLUMNS);. The problem with integer maths is that you can lose a LOT of precision.
Make your computer suffer and make it drop all those mines.
Remember. The definition of "computation" is "to force a machine do a boring job that nobody else would like to do" :-)
public static void main(String[] args) {
int rows = 25;
int cols = 25;
boolean[][] mines = new boolean[rows][cols];
while(mineCount(mines) < 97){
dropMine(mines);
}
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
System.out.print("[");
if (mines[i][j]){
System.out.print("*");
}else{
System.out.print(" ");
}
System.out.print("] ");
}
System.out.println();
}
}
private static void dropMine(boolean[][] mines) {
int x = (int)(Math.random()*25);
int y = (int)(Math.random()*25);
mines[x][y] = true;
}
private static int mineCount(boolean[][] mines) {
int count = 0;
for(int i=0;i<25;i++){
for(int j=0;j<25;j++){
if (mines[i][j]){
count++;
}
}
}
return count;
}