Getting a range off user input for random generation - java

So I am trying to get my code to get a random number generation based off what the user inputs. and my current statement doesnt generate the proper range.
secretNum = low + (int)(Math.random()* max);
Where low is the lowest part of the range, and high is the highest. For example. if low was 5 and high was 10, would this generate a range from 1-50? (5*10).

I'd use a Random object for this.
You create it like this:
Random r = new Random();
And then from there, it is very easy to use. For a random int from 0 (inclusive) to 50 (exclusive), just do:
int randomNumber = r.nextInt(50);
I think it makes all of this much easier for you. If the user inputs 10 and 140, then you do something like this:
int lowest = 10;
int highest = 140;
int randomMax = 140-10;
int randomNumber = r.nextInt(randomMax) + 10;
It's probably the easiest way to do this.

You save your user input in the variable in:
String in = sc.nextLine();
Then you create a instance of java.util.Random with the seed being a hash of the input:
Random r = new Random(in.hashCode());
int randomNumber = r.nextInt();
If you want to generate a random number between with a maximum and a minimum see this Question
Or this one but then you need to convert c++ into java:
C++:
output = min + (rand() % (int)(max - min + 1))
Java:
output = min + (r.nextInt() % (max - min + 1))
You can also use r.nextInt(max) if you only need a maximum.
Note:
For cryptographically secure random numbers use an instance of SecureRandom

Related

Is Math.random() safe to use?

I have a method which is generating random integers. I don't want integers to be repeated, so I created this code -
int prevInt = 0;
private int randomInt() {
int random = (int) (Math.random() * 3);
//generate random numbers between 0 to 3 inclusive
if(random == prevInt)
return randomInt();
//if previous random number is equal to currently generated
//random number, then call this method again for a different
//random number
prevInt = random;
return random;
//else return the generated random number
}
Is the above code safe to use? At worst case scenario, can it be possible that all random integers generated by Math.random() * 3 are same?
private final Random random = new Random();
private int randomInt(final int prev, final int max) {
final int next = random.nextInt(max - 1);
if(next >= prev){
return next + 1;
}else{
return next;
}
}
This will return an int between 0 and max without the need to repeat.
public static double random()
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
There are two principal means of generating random (really pseudo-random) numbers:
the Random class generates random integers, doubles, longs and so on,
in various ranges.
the static method Math.random generates doubles between 0 (inclusive)
and 1 (exclusive).
To generate random integers:
do not use Math.random (it produces doubles, not integers)
use the Random class to generate random integers between 0 and N.
To generate a series of random numbers as a unit, you need to use a single Random object - do not create a new Random object for each new random number.
Other alternatives are:
SecureRandom, a cryptographically strong subclass of Random
ThreadLocalRandom, intended for multi-threaded cases
please have a look at this post.
SO Reference 1,Reference 2
From the javadoc, Math.random() return a pseudo random and (approximately) uniform distributed number within the range.
So when you don't strict accuracy you may use it. Otherwise search for better solution.
try this trivial code and see for yourself
for (int ran = 0; ran < 10; ran++) {
int random = (int) (Math.random() * 3);
System.out.println(random);
}
Output in my case
2 2 0 2 1 0 0 0 2 1
First, I must point that your question title is not that clear. Safe can mean various thing. In this case I think you mean safety of algorithm of your code, not security nor only Math.random().
Unfortunately, your code is not algorithmically safe. Even if Math.random is safe, Your code has always positive possibility on running at any time: roughly speaking it means there are no guarantee that your code ends in finite time.
Assume you are taking random number among 4 numbers. If you are drawing random number excluding right before number, you're actually not drawing from 4 numbers: it's 3. I suggest another method:
int prevInt = -1;
private int randomInt() {
if (prevInt == -1) {
int random = (int) (Math.random() * 4);
//generate random numbers between 0 to 3 inclusive
} else if
int random = (int) (Math.random() * 3);
random = (random >= prevint) ? (random + 1) % 4 : random;
}
prevInt = random;
return random;
}
private void resetRandom() {
prevInt = -1;
//use when you want to reset information that you have 'before' result.
}
This algorithm ends within finite time. Concern about whether Math.Random() itself is dangerous or whatever will be explained by other nice guys.
Yes, it is safe but we never know what is going to happen, so we can simply multiply Math.random two times to maintain a good safety
int random = (int) (Math.random() * Math.random() * 3);

Random number generator with range and higher probability for bigger numbers in java

I want to make a method in java where I can input the maximum and minimum numbers and it will give me a random number, but with a higher chance of a bigger number than a smaller one. How would I do this?
There is lots of ways to do this depending on what you mean by higher. You can skew your distribution with a function.
int num = (int) (func(Math.random()) * (max - min)) + min;
Your func could be Math.sqrt or Math.pow(x, n) where n < 1 to favour higher numbers.
I would like it to be 10% more likely to have an answer over ten.
If this is your requirement, you actually have two distributions.
private static final Random rand = new Random();
public static int randBetween(int min, int max) {
return rand.nextInt(max - min + 1) + min;
}
int next = rand.nextInt(100) < 10 ? // a 10% chance
randBetween(10, max) : // random of at least 10
randBetween(min, max); // otherwise any number.

How to make purely random generation of numbers in certain interval

I have an generation method that generates numbers between 1 and 8. But the problem is that this method often generates the numbers 1-7 and almost never number 8. My question is that how to generate random numbers in certain interval but that all numbers appear approximately same times ?
EDIT:
my number generator
public int generateNumber() {
Random r = new Random();
return r.nextInt(8 - 1) + 1;
}
The random generator generates an "uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)" Please refer to the documentation:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
You can do:
random.nextInt(max - min + 1) + min
And it should be fine.
Alternatively,
Random randomGenerator = new Random();
for (int idx = 1; idx <= NUMBER_OF_INTEGERS_YOU_WANT; idx++){
int randomInt = randomGenerator.nextInt(8)+1;
CODE_HERE
}
"almost never number 8": If that generator ever generates 8 there is something wrong.
The nextInt gives a number between 0 and 6 (borders inclusive) and adding one gives the interval [1,7].
To get numbers in [1,8] you can use
r.nextInt(8) + 1
You need something like
return r.nextInt(8) + 1;
Which will return values from 1 to 8. So it starts with 0 and generated number max uptil n-1 i.e. 7 as per this.
In your case, you have r.nextInt(8 - 1) which evaluates to r.nextInt(7) so it would generate numbers from 0 -6 and on top of that you are adding 1 to number from above api, so your range is 1-7 and not 1-8.

Generate a random number larger or smaller than the previous random number

I am trying to generate a random number larger than and smaller than the previous random number, but cannot figure out how.
I have this so far:
number = (int)( max * Math.random() ) + min;
guess = (int)( max * Math.random() ) + min;
if (guess<number)
{
guess = (int)( max * Math.random() ) + min;
System.out.println(guess);
}
else if (guess>number)
{
guess = (int)( max * Math.random() ) + min;
System.out.println(guess);
}
UPDATE: How do I make sure it doesn't generate a random number that it already has generated? The computer gets 10 tries to guess the number that was generated, but I want to make it logical in the way that it wouldn't generate one that it already knows is wrong.
What about ordering a list of random numbers...
public static void method2() throws Exception {
Random rng = new SecureRandom();
Set<Integer> numbers = new HashSet<>();
while (numbers.size() < 3) {
// number only added if not already present in Set, set values are unique
numbers.add(rng.nextInt(MAX));
}
List<Integer> numberList = new ArrayList<>(numbers);
Collections.sort(numberList);
// lower random at index 0, mid at index 1
// you can guess where the other one is hiding
System.out.println(numberList);
}
I put them in a set first to make sure that there are no duplicates. Of course, if MAX has value 1 this may take a while.
One advantage of this approach is that the numbers should be pretty well distributed over 0 to MAX. If you use ranges directly then you have to deal with upper and lower bounds.
Of course this approach can easily be extended to work over ranges as well, as long as the maximum amount of values is (significantly) higher than the amount of numbers in the list (in this case just 3).
If the computer player receives information that its guess is either too low or too high (or correct), you need to keep track of the range of possible values that the correct value could be. Initially, this is the entire range, min..max. Once you guess a value that is incorrect, you move either min or max:
if (guess<number)
{
min = guess + 1; // Don't guess any more number <= guess
}
else if (guess>number)
{
max = guess - 1; // Don't guess any more number >= guess
}
else
{
// I WIN!!
}
Now you you always have the correct range for valid guesses between min and max.
Now, your logic to generate random numbers within the range seems to be a bit off. This answer to the question linked in #Solver's answer has the correct logic:
guess = (int)( (max - min) * Math.random() + 1) + min;
You can specify the minimum andere maximum values when getting a random nummer as shown here: How do I generate random integers within a specific range in Java?
This will always return numbers like this: less <= number <= more
number = (max * Math.random()) + min;
less = (number * Math.random()) + min;
more = ((max - number) * Math.random()) + number;
edit:
Misinterpreted the question.

Random numbers in Java when working with Android

I need to make a random number between 1 and 20, and based on that number (using "If - Then" statements), I need to set the image of an ImageView.
I know that in Objective-C, it goes like this:
int aNumber = arc4Random() % 20;
if (aNumber == 1) {
[theImageView setImage:theImage];
}
How can I do this in Java? I have seen it done this way, but I do not see how I can set the range of numbers (1-20, 2-7, ect).
int aNumber = (int) Math.random()
Docs are your friends
Random rand = new Random();
int n = rand.nextInt(20); // Gives n such that 0 <= n < 20
Documentation:
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
Thus, from this example, we'll have a number between 0 and 19
Math.random() returns an double from [0,1[.
Random.nextInt(int) returns an int from [0, int[.
You can try:
int aNumber = (int) (20 * Math.random()) + 1;
or
Random rand = new Random();
int n = rand.nextInt(20) + 1;
You can use Math.random() to generate a double between 0 and 1 non-inclusive. Android Javadoc here.

Categories

Resources