I have two integers, let them be
int a = 35:
int b = 70;
I want to pick one of them randomly at runtime and assign to another variable. I.e.
int c = a or b:
One of the ways that come into my mind is to create an array with these two integers and find a random integer between 0 and 1 and use it as the index of the array to get the number..
Or randomize boolean and use it in if-else.
My question is that is there a better and more efficient way to achieve this? I.e. pick a number from two previously defined integers?
Is there a specific reason you are asking for a more efficient solution? Unless this functionality sits in a very tight inner loop somewhere (e.g. in a ray tracer), you might be trying to prematurely optimize your code.
If you would like to avoid the array, and if you don't like the "bloat" of an if-statement, you can use the ternary choice operator to pick between the two:
int a = 35;
int b = 70;
int c = random.nextBoolean() ? a : b;
where random is an instance of java.util.Random. You can store this instance as a final static field in your class to reuse it.
If you don't require true randomness, but just want to switch between the two numbers in each invocation of the given block of code, you can get away with just storing a boolean and toggling it:
...
int c = toggle ? a : b;
toggle = !toggle;
Since I can't comment on other answers, I'd like to point out an issue with some of the other answers that suggest generating a random integer in a bigger range and making a decision based on whether the result is odd or even, or if it's lower or greater than the middle value. This is in effect the exact same thing as generating a random integer between 0 and 1, except overly complicated. The nextInt(n) method uses the modulo operator on a randomly generated integer between -2^31 and (2^31)-1, which is essentially what you will be doing in the end anyway, just with n = 2.
If you are using the standard library methods like Collections.shuffle(), you will again be overcomplicating things, because the standard library uses the random number generator of the standard library.
Note that all of the suggestions (so far) are less efficient than my simple nextBoolean() suggestion, because they require unnecessary method calls and arithmetic.
Another way to do this is, store the numbers into a list, shuffle, and take the first element.
ArrayList<Integer> numbers=new ArrayList<Integer>();
numbers.add(35);
numbers.add(70);
Collections.shuffle(numbers);
numbers.get(0);
In my opinion, main problem here is entropy for two numbers rather than making use of that entropy. Indexed array or boolean are essentially the same thing. What else you can do (and, hopefully, it will be more random) is to make Java give you a random number between limits say 0 to 100. Now, if the chosen random number is odd, you pick int c = a. Pick b otherwise. I could be wrong, but picking random between 0 to 100 seems more random as compared to picking random between two numbers.
You can simply use secure random generator(java.security.SecureRandom ).
try {
r = SecureRandom.getInstance("SHA1PRNG");
boolean b1 = r.nextBoolean();
if (b1) {
c = a;
} else {
c = b;
}
} catch (NoSuchAlgorithmException nsae) {
// Process the exception in some way or the other
}
Refer this link for more information
Randomize an integer between 1 and 10, if it's more than 5 then take the value of b other wise go with a. As far as I know there are no other ways to select from integers.
int a=1;
int b=2;
int get = new Random().nextBoolean()? a : b;
Related
I'm rather new to Java, and I'm trying to figure out a way to copy all primes inside of an array and copy those to another array.
To do so, I've implemented a separate isPrime() method to check whether the element is a prime, and another method that counts the number of primes in that array countPrimes(), such that I can determine the new array's size.
Here is where I'm kind of stuck:
public static int[] primesIn(int[] arr) {
int primeHolder = countPrimes(arr);
int[] copyArr = new int[primeHolder];
for (int i = 0; i < arr.length; i++) {
if (isPrime(arr[i]) == true) {
copyArr[>Needs to start from 0<] = arr[i];
}
}
return copyArr;
}
int[] arrayMan = {3,5,10,15,13};
At copyArr the position should be 0, followed by +1 everytime it finds a prime. If I were to give it i position, as in copyArr[i] = arr[i], then say the prime is at position 5, it would try to save the prime onto position 5of copyArr, which doesn't exist if there are only three primes in the original array, which would've given copyArr a length of only three.
Something tells me a different for loop, or maybe even an additional one would help, but I can't see how I should implement it. Help is greatly appreciated!
Have a second index variable int primeCount, and increment it whenever you find a prime. No need for a 2nd loop.
In modern days of abundant memory, things are usually not done like this. If you don't have some extra hard requirements, you could just use a resizable ArrayList<Integer>, and add() stuff in there. (and convert it back to int[] at the end if needed). This is also better in this case, because typically your countPrimes call will run much slower than ArrayList reallocations.
Read your words carefully:
At copyArr the position should be 0, followed by +1 everytime it
finds a prime.
That means that index in a new array does not depend on its position in the old array. Create a counter. And each time you place a prime number into a new array, increment it by 1. Thus you can always know where to put a new number.
Recently in AP Computer Science A, our class recently learned about arrays. Our teacher posed to us a riddle.
Say you have 20 numbers, 10 through 100 inclusive, right? (these numbers are gathered from another file using Scanners)
As each number is read, we must print the number if and only if it is not a duplicate of a number already read. Now, here's the catch. We must use the smallest array possible to solve the problem.
That's the real problem I'm having. All of my solutions require a pretty big array that has 20 slots in it.
I am required to use an array. What would be the smallest array that we could use to solve the problem efficiently?
If anyone could explain the method with pseudocode (or in words) that would be awesome.
In the worst case we have to use an array of length 19.
Why 19? Each unique number has to be remembered in order to sort out duplicates from the following numbers. Since you know that there are 20 numbers incoming, but not more, you don't have to store the last number. Either the 20th number already appeared (then don't do anything), or the 20th number is unique (then print it and exit – no need to save it).
By the way: I wouldn't call an array of length 20 big :)
If your numbers are integers: You have a range from 10 to 100. So you need 91 Bits to store which values have already been read. A Java Long has 64 Bits. So you will need an array of two Longs. Let every Bit (except for the superfluous ones) stand for a number from 10 to 100. Initialize both longs with 0. When a number is read, check if the corresponding bit mapped to the read value is set to 1. If yes, the read number is a duplicate, if no set the bit to 1.
This is the idea behind the BitSet class.
Agree with Socowi. If number of numbers is known and it is equal to N , it is always possible to use N-1 array to store duplicates. Once the last element from the input is received and it is already known that this is the last element, it is not really needed to store this last value in the duplicates array.
Another idea. If your numbers are small and really located in [10:100] diapason, you can use 1 Long number for storing at least 2 small Integers and extract them from Long number using binary AND to extract small integers values back. In this case it is possible to use N/2 array. But it will make searching in this array more complicated and does not save much memory, only number of items in the array will be decreased.
You technically don't need an array, since the input size is fixed, you can just declare 20 variables. But let's say it wasn't fixed.
As other answer says, worst case is indeed 19 slots in the array. But, assuming we are talking about integers here, there is a better case scenario where some numbers form a contiguous interval. In that case, you only have to remember the highest and lowest number, since anything in between is also a duplicate. You can use an array of intervals.
With the range of 10 to 100, the numbers can be spaced apart and you still need an array of 19 intervals, in the worst case. But let's say, that the best case occurs, and all numbers form a contiguous interval, then you only need 1 array slot.
The problem you'd still have to solve is to create an abstraction over an array, that expands itself by 1 when an element is added, so it will use the minimal size necessary. (Similar to ArrayList, but it doubles in size when capacity is reached).
Since an array cannot change size at run time You need a companion variable to count the numbers that are not duplicates and fill the array partially with only those numbers.
Here is a simple code that use companion variable currentsize and fill the array partially.
Alternative you can use arrayList which change size during run time
final int LENGTH = 20;
double[] numbers = new double[LENGTH];
int currentSize = 0;
Scanner in = new Scanner(System.in);
while (in.hasNextDouble()){
if (currentSize < numbers.length){
numbers[currentSize] = in.nextDouble();
currentSize++;
}
}
Edit
Now the currentSize contains those actual numbers that are not duplicates and you did not fill all 20 elements in case you had some duplicates. Of course you need some code to determine whither a numbers is duplicate or not.
My last answer misunderstood what you were needing, but I turned this thing up that does it an int array of 5 elements using bit shifting. Since we know the max number is 100 we can store (Quite messily) four numbers into each index.
Random rand = new Random();
int[] numbers = new int[5];
int curNum;
for (int i = 0; i < 20; i++) {
curNum = rand.nextInt(100);
System.out.println(curNum);
boolean print = true;
for (int x = 0; x < i; x++) {
byte numberToCheck = ((byte) (numbers[(x - (x % 4)) / 4] >>> ((x%4) * 8)));
if (numberToCheck == curNum) {
print = false;
}
}
if (print) {
System.out.println("No Match: " + curNum);
}
int index = ((i - (i % 4)) / 4);
numbers[index] = numbers[index] | (curNum << (((i % 4)) * 8));
}
I use rand to get my ints but you could easily change this to a scanner.
For a distributed application project I want to have two instances share the same/know (pseudo-)random numbers.
This can be achieved by using the same seed for the random number generator (RNG). But this only works if both applications use the RNG output in the same order. In my case this is hard or even impossible.
Another way of doing this is would be (psedocode):
rng.setSeed(42);
int[] rndArray;
for(...) {
rndArray[i] = rng.nextInt();
}
Now both applications would have the same array of random numbers and my problem would be solved.
BUT the array would have to be large, very large. This is where the lazy initialization part comes in: How can I write a class that where rndArray.get(i) is always the same random number (depending on the seed) without generating all values between 0 and i-1?
I am using JAVA or C++, but this problem should be solvable in most programming languages.
You can use a formula based on a random seed.
e.g.
public static int generate(long seed, int index) {
Random rand = new Random(seed + index * SOME_PRIME);
return rand.nextInt();
}
This will produce the same value for a given seed and index combination. Don't expect it to be very fast however. Another approach is to use a formula like.
public static int generate(long seed, int index) {
double num = seed * 1123529253211.0 + index * 10123457689.0;
long num2 = Double.doubleToRawLongBits(num);
return (int) ((num2 >> 42) ^ (num2 >> 21) ^ num2);
}
If it's large and sparse you can use a hash table (downside: the numbers you get depend on your access pattern).
Otherwise you could recycle the solution to a problem from the Programming Pearls (search for something like "programming pearls initialize array"), but it wastes memory iirc.
Last solution I can think of, you could use a random generator which can efficiently jump to a specified position - the one at http://mathforum.org/kb/message.jspa?messageID=1519417 is decently fast, but it generates 16 numbers at a time; anything better?
I have a portion of code which generates a random number, and then attempts to find out where the number falls, between zero and some probability, stored in an array as a percentage. I understand that this may sound much more confusing than it actually is, so here is my code, essentially, in Java:
Random rand = new Random();
double currentProbability = rand.nextDouble();
// these are the "percentages" I refer to above
// note that they will not necessarily be in least-to-greatest/greatest-to-least
// order
double[] probabilities = new double[]{0.49, 0.49, 0.02};
// the objects in the array below correspond to the probabilities at the same
// index in the "probabilities" array above
Object[] correspondingObjects = new Object[]{new Object(), new Object(), new Object()};
// here, I would find between which percentage the random number lies, and choose
// the corresponding object from the array of Objects
Therefore, my issue is mainly how to select in which index the random number lies, if the probability is given as a percentage. Perhaps I am over-complicating this, and I would ask that any user who believes that this is the case leave a comment below instead of down-voting this question.
Here is the code for finding index:
int index = 0;
while (true) {
currentProbability -= probabilities[index];
if (currentProbability <= 0) {
break;
}
index++;
}
D.E. Knuth describes a method that is beneficial if the number of cases to choose from is large. If you have to choose among n cases, you distribute them into n-1 buckets of equal sizes, such that there are no more than 2 cases in each bucket. It can be shown that this is always possible. To select a case is then a two step process that can be performed in constant time: first select a bucket, then decide which of the two cases in this bucket applies.
For example if the distribution for A, B, C is [0.49, 0.49, 0.02] we would come up with two buckets of size 0.5 each. The first contains 0.02 C and 0.48 A; the second 0.01 A and 0.49 B. In sum, you get the original probabilities.
If the generated random number r is below 0.5 we choose the first bucket, if r is below 0.02 the case C is selected, otherwise A. If r is above 0.5, the second bucket is selected and if (r-0.5) is below 0.01 we select case A otherwise case B.
It sounds like you want to do a weighted shuffle. depending on the size of your set, it may be easier to just load a List with objects multiple times then use the static shuffle(List) method in java.util.Collection and pop an object off the top of the List.
For instance,
for [.49,.49,.02] this would be normalized.
for [.10, .10, .80] this would normalize to [.1, .1, .8] so if this is [A, B, C] you would load 1 A, 1 B and 8 C objects into a list then use shuffle.
Obviously, if you have a very fine precision on your List and lots of objects then this solution would not be optimal.
Let's say that you have an arbitrarily large sized two-dimensional array with an even amount of items in it. Let's also assume for clarity that you can only choose between two things to put as a given item in the array. How would you go about putting a random choice at a given index in the array but once the array is filled you have an even split among the two choices?
If there are any answers with code, Java is preferred but other languages are fine as well.
You could basically think about it in the opposite way. Rather than deciding for a given index, which value to put in it, you could select n/2 elements from the array and place the first value in them. Then place the 2nd value in the other n/2.
A 2-D A[M,N] array can be mapped to a vector V[M*N] (you can use a row-major or a column-major order to do the mapping).
Start with a vector V[M*N]. Fill its first half with the first choice, and the second half of the array with the second choice object. Run a Fisher-Yates shuffle, and convert the shuffled array to a 2-D array. The array is now filled with elements that are evenly split among the two choices, and the choices at each particular index are random.
The below creates a List<T> the size of the area of the matrix, and fills it half with the first choice (spaces[0]) and half with the second (spaces[1]). Afterward, it applies a shuffle (namely Fisher-Yates, via Collections.shuffle) and begins to fill the matrix with these values.
static <T> void fill(final T[][] matrix, final T... space) {
final int w = matrix.length;
final int h = matrix[0].length;
final int area = w * h;
final List<T> sample = new ArrayList<T>(area);
final int half = area >> 1;
sample.addAll(Collections.nCopies(half, space[0]));
sample.addAll(Collections.nCopies(half, space[1]));
Collections.shuffle(sample);
final Iterator<T> cursor = sample.iterator();
for (int x = w - 1; x >= 0; --x) {
final T[] column = matrix[x];
for (int y = h - 1; y >= 0; --y) {
column[y] = cursor.next();
}
}
}
Pseudo-code:
int trues_remaining = size / 2;
int falses_remaining = size / 2;
while (trues_remaining + falses_remaining > 0)
{
if (trues_remaining > 0)
{
if (falses_remaining > 0)
array.push(getRandomBool());
else
array.push(true);
}
else
array.push(false);
}
Doesn't really scale to more than two values, though. How about:
assoc_array = { 1 = 4, 2 = 4, 3 = 4, 4 = 4 };
while (! assoc_array.isEmpty())
{
int index = rand(assoc_array.getNumberOfKeys());
int n = assoc_array.getKeyAtIndex(index);
array.push(n);
assoc_array[n]--;
if (assoc_array[n] <= 0) assoc_array.deleteKey(n);
}
EDIT: just noticed you asked for a two-dimensional array. Well it should be easy to adapt this approach to n-dimensional.
EDIT2: from your comment above, "school yard pick" is a great name for this.
It doesn't sound like your requirements for randomness are very strict, but I thought I'd contribute some more thoughts for anyone who may benefit from them.
You're basically asking for a pseudorandom binary sequence, and the most popular one I know of is the maximum length sequence. This uses a register of n bits along with a linear feedback shift register to define a periodic series of 1's and 0's that has a perfectly flat frequency spectrum. At least it is perfectly flat within certain bounds, determined by the sequence's period (2^n-1 bits).
What does that mean? Basically it means that the sequence is guaranteed to be maximally random across all shifts (and therefore frequencies) if its full length is used. When compared to an equal length sequence of numbers generated from a random number generator, it will contain MORE randomness per length than your typical randomly generated sequence.
It is for this reason that it is used to determine impulse functions in white noise analysis of systems, especially when experiment time is valuable and higher order cross effects are less important. Because the sequence is random relative to all shifts of itself, its auto-correlation is a perfect delta function (aside from qualifiers indicated above) so the stimulus does not contaminate the cross correlation between stimulus and response.
I don't really know what your application for this matrix is, but if it simply needs to "appear" random then this would do that very effectively. In terms of being balanced, 1's vs 0's, the sequence is guaranteed to have exactly one more 1 than 0. Therefore if you're trying to create a grid of 2^n, you would be guaranteed to get the correct result by tacking a 0 onto the end.
So an m-sequence is more random than anything you'll generate using a random number generator and it has a defined number of 0's and 1's. However, it doesn't allow for unqualified generation of 2d matrices of arbitrary size - only those where the total number of elements in the grid is a power of 2.