How do I print a number that is not 'x'. But within the given range.
int x = (int) (Math.random() *3);// I have generated a random number
System.out.println(x);// This will print the random number
There is some confusion understanding this problem so i will explain it with the help of an example.
Suppose 'x' is equal to 2
Now i want to print a number that is not equal to 'x' for example 1, which is within the range stated above.
I would do:
int possibilities = 7;
int x = ThreadLocalRandom.current().nextInt(possibilities);
int y = ThreadLocalRandom.current().nextInt(possibilities - 1);
if (y >= x)
y++; // adding 1 to y here means that y can't equal x
This way y is equally likely to be any of the integers in the range 0 to possibilities - 1 except x.
ThreadLocalRandom.current().nextInt(possibilities); is just an alternative way of generating a random number in a range. ThreadLocalRandom.current() just gives an instance of the Random class, and nextInt is a method for producing random numbers in a range (I prefer this to the Math.random approach).
However, you may find it easier to understand this solution, which is more similar to your original question.
int possibilities = 7;
int x = (int) (Math.random() * possibilities);
int y = (int) (Math.random() * (possibilities - 1));
if (y >= x)
y++;
Try the Random class
Random r = new Random();
int max = 10;
int min = 1;
int x = r.nextInt((max - min) + 1) + min;// I have generated a random number
System.out.println(x);// This will print the random number
I assume you want to print a random number within gives range in java you replace your line
int x = (int) (Math.random() *3);
with this code
Random rand;
int x = rand.nextInt((max - min) + 1) + min;
Given your code:
int x = (int) (Math.random() *3);
int y = (int) (Math.random() *3);
if(y != x){
System.out.println(x);
}
Related
I'm currently going through the book Computer Science: An Interdisciplinary Approach, which contains a code snippet for shuffling an array (in this example, the array contains a deck of cards). The code is as follows:
int n = deck.length;
for (int i = 0; i < n; i++)
{
int r = i + (int) (Math.random() * (n-i));
String temp = deck[i];
deck[i] = deck[r];
deck[r] = temp;
}
My question is, why is the simpler (int) (Math.random() * n) not preferred? Is it less random than i + (int) (Math.random() * (n-i))?
Any help appreciated!
They give you different values.
(int) (Math.random() * n) gives you a value in the range 0 <= r < n (between 0 [inclusive] and n [exclusive]).
i + (int) (Math.random() * (n-i)) gives you a value in the range i<= r < n (between i [inclusive] and n [exclusive]).
So for example, if i is 10, your "simplified" version could give you 5. The version in the code cannot.
The idea is to take a random value that hasn't been chosen yet. If you'd allow your scheme then some elements may never get shuffled and the chance that some elements stay in place is therefore too high.
Math.Random() can return a double value between 0.0 and 1.0.
https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random()
So if you just do (int) (Math.random() * n) then the value of r can be higher then n-1 while will lead to ArrayIndexoutofbound exception.
http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html
Right now, it makes number above 50 positive and numbers below 50 negative. How should I change the code to make it so that any number can be either positive or negative?
public class P1G
{
static void main()
{
int[] a = new int[10];
for(int index = 0; index < 10; index ++)
{
double r = Math.random();
int p = (int) (((100 - 0) + 1) * r + 0); // (-) or (+)
if ( p < 50 )
{
int n = (int) (((100 - 0) + 1) * r + 0);
n = n * -1;
System.out.println(n);
}
else
{
int n = (int) (((100 - 0) + 1) * r + 0);
n = n;
System.out.println(n);
}
}
}
}
Unless I'm missing something you want
int n = (int) (Math.random() * 101) - 50;
System.out.println(n);
Explanation
Get a random int in the range 0 to 100 and subtract 50, that gives the range -50 to positive 50. Per the Math.random() Javadoc -
Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.
Instead of randoming over [0,101], you can random over [-50, 50] by doing the following:
int p = (int) (100 * r - 50);
Can you just use this?
new Random().nextInt(50)-100
Oh, sorry,, make a big careless mistake.
new Random().nextInt(100) - 50
I understand that in Java I can generate a random number with the following code:
Random rand=new Random()
int x=rand.nextInt(1);
I am interested generating either the number zero or one. But I want that number one has 90% higher probability of of being generated than zero.
How can I achieve that?
thanks
EDIT:
Thanks everyone. It's working.
Generate a random number from 0 to 9. If the number is 0, you return zero. If the number is 1-9, you return one.
Heres a pretty compact way to express it
Random rand=new Random();
int x = ((rand.nextInt(10) == 0)) ? 0 : 1;
This would do it:
int result;
if (Math.random() < 0.9) {
result = 1;
}
else {
result = 0;
}
Or more concise:
int result = (Math.random() < 0.9) ? 1 : 0;
read nextInt(int) manual which says:
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence. The general contract of nextInt is that one int value in the specified range is pseudorandomly generated and returned. All n possible int values are produced with (approximately) equal probability. The method nextInt(int n) is implemented by class Random as if by:
change your code to
Random rand=new Random();
int x=rand.nextInt(10);
return (x == 0) ? 0 : 1;
then run it again
You can write it like this.
int x = (int) (Math.random() / 0.9); // 90% chance of 0
or
int x = (int) (Math.random() + 0.9); // 90% chance of 1
I use this method to get a random location outside the screen to spawn all the zombies on.
public void initZombie(){
for(int i = 0; i < 100; i++){
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
}
}
The problem that I am having with this is that the two ints that gets the random location only run once so therefor every single zombie spawns at the exact same place inside of each other. How would I be able to get the ints to run multiple times so that the zombies spawn at different locations? I have tried to put them inside of the run() method instead and then they run two times so that the first zombie spawns in one location and then the 99 other zombies spawn at another location inside of each other.
You are casting Math.random() to an integer which floors the value. Since Math.random() generates a double that is 0 <= x < 1, it will always be rounded to 0. That is why you are getting the exact same spawn position.
You need to add parenthesis to your cast:
int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
If I were you, I'd use the Random object, and I'd call the nextInt function
Random rnd = new Random();
for(...)
{
int randInt = rnd.nextInt(300) //300 is the maximum
}
You don't index your spawn array. Actually I don't think you even need one. Try this
public void initZombie(int maxZombies){
Random r=new Random();
for(int i = 0; i < maxZombies; i++){
zombie.add(new Zombie(r.nextInt(MAX_X), r.nextInt(MAX_Y));
}
}
If you later need to recall the spawn position of a zombie, you can save it as a private int in the zombie instance.
Also the original code will give you negative coordinates because you multiply with a negative constant. And even if it did work you'd end up with more zombies than you'd want because the new Zombie() code runs in an inner loop.
There are a couple things causing problems with the code. As Supericy said, you're accidentally casting all of your random numbers too soon, truncating their values, and as SJuan76 mentioned in a comment, your for loop isn't quite set up right. (It works, but it can be much cleaner.)
First, the casting issue: When you cast a double to an int, the decimal portion is rounded down.
int num = (int) 0.999; //num == 0
Math.random() always returns a double between 0 and 1, so when cast to an int, it's always truncated to zero as well.
So that means your line
int randomXSpawn = (int) Math.random() * -300 + -50;
is evaluated like this:
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomXSpawn = (int) 0.xxxx * -300 + -50;
int randomXSpawn = 0 * -300 + -50;
int randomXSpawn = -50;
To fix this, simply add parenthesis to force the multiplication and addition to happen before the casting, like Supericy said:
int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
Second, the for loops: This is what you have now. It works correctly, but it could be written more clearly.
for(int i = 0; i < 100; i++) {
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
}
What happens during a single iteration of the outer for loop?
//int i = 0;
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
First, you generate two random numbers:
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
Then, you store those numbers so you can get to them later:
int[][] spawn = {{randomXSpawn,randomYSpawn}};
Finally, you enter into the final for loop:
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
What happens in there? We know that spawn is a two-dimensional array. Since you just declared it above, we also know that it has dimensions [1][2]. This means that the for loop will iterate once: when j = 0, because when j = 1 on the next iteration, j < spawn.length will no longer be true.
Because of how you declared spawn, we know that spawn[0][0] == randomXSpawn and spawn[0][1] == randomYSpawn, so the line in the middle of the inner for loop effectively does this:
zombie.add(new Zombie(randomXSpawn,randomYSpawn));
This suggests a way to make your code more clear: You can remove the spawn array and the inner for loop in order to call the Zombie constructer with randomXSpawn and randomYSpawn directly.
This is what the change would look like:
for(int i = 0; i < 100; i++) {
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
zombie.add(new Zombie(randomXSpawn,randomYSpawn));
}
Putting both changes together, we get this:
for(int i = 0; i < 100; i++) {
int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
zombie.add(new Zombie(randomXSpawn,randomYSpawn));
}
If you don't like my suggested restructuring of the for loops, you don't have to change that. I think the way you have them now works correctly. It's just my opinion that it's difficult to read, and if you disagree, that is allowed =). The first change about using parenthesis to control casting is what is causing the problem you mentioned in your question, though, and needs to be taken care of.
I am looking for a way to generate a random integer from 0-x, where x is defined at runtime by the human user. However, half of those numbers must be greater than zero and less than or equal to 5 (0,5] and the other half must be in the set of [6,x].
I know that the following code will generate a number from 0-x. The main problem is ensuring that half of them will be in the set of (0,5]
Math.random() * x;
I'm not looking for someone to do this for me, just looking for some hints. Thank you!
You could first flip a coin and based on that generate upper or lower number:
final Random rnd = new Random();
while (true)
System.out.println(rnd.nextBoolean()? rnd.nextInt(6) : 6 + rnd.nextInt(x-5));
Or, using the unwieldy Math.random() (bound to have trouble at the edges of the range):
while (true)
System.out.println(Math.floor(
math.random() < 0.5 ? (Math.random() * 6) : (6 + (x-5) * Math.random())
));
Consider this as a hint only :)
I'd do this:
double halfX= x / 2.0;
double random = Math.random() * x;
if( random< halfX ) {
random = random*5.0/(halfX);
} else {
random = (random/halfX - 1) * (x-5.0) + 5.0 ;
}
I think it is good now. This is less understandable and readable, but has only one call to random for each invocation. Apart from the fact MarkoTopolnic pointed out: the user needed an integer... I'd have to calculate what rounding would do to the distribution.
This is absolutely not easy... My head aches, so the best I can come up with:
double halfX= x / 2.0 + 1.0;
double random = Math.random() * (x+2.0);
int randomInt;
if( random< halfX ) {
randomInt = (int) (random*6.0/(halfX)); //truncating, means equal distribution from 0-5
} else {
randomInt = (int) ((random/halfX - 1.0) * (x-5.0) + 6.0) ; //notice x-5.0, this range before truncation is actually from 6.0 to x+1.0, after truncating it gets to [6;x], as this is integer
}
The second part I'm not sure though... A few hours of sleep would get it right... I hope the intentions and logic is clear though...
In case anyone is curious, here's the solution I came up with based on Marko's solution.
I had the following class defined for another part of this program.
public class BooleanSource
{
private double probability;
BooleanSource(double p) throws IllegalArgumentException
{
if(p < 0.0)
throw new IllegalArgumentException("Probability too small");
if(p > 1.0)
throw new IllegalArgumentException("Probability too large");
probability = p;
}
public boolean occurs()
{
return (Math.random() < probability);
}
}
With that, I did the following
private static void setNumItems(Customer c, int maxItems)
{
BooleanSource numProb = new BooleanSource(0.5);
int numItems;
if(numProb.occurs())
{
double num = (Math.random()*4)+1;
numItems = (int) Math.round(num);
}
else
{
double num = 5 + (maxItems-5)*Math.random();
numItems = (int) Math.round(num);
}
c.setNumItems(numItems);
}