I have a method who randomize a number between 1 and 5.
This method needs to stop when all 5 numbers are sorted too (isn't doing it now)
My actual code is:
public ArrayList<String> generated = new ArrayList<String>(); on top
And the method itself is:
public int RandomizeQuestion () {
// Question numbers
final int min = 1;
final int max = 5;
Random r = new Random();
int qran = r.nextInt((max - min) + 1) + min;
if (Collections.singletonList(generated).contains(qran)) {
RandomizeQuestion();
} else {
generated.add(String.valueOf(qran));
}
return qran;
}
But that happens is all time the random number appears as new and this number is added repeatedly in generator array.
Collections.singletonList(generated) returns a List<ArrayList<String>> containing generated as its only element. Obviously that won't contain qran. Also, you're not checking if the list is the expected length before attempting to add a new item. Something like this should work:
if (generated.size() < max - min + 1) {
if (generated.contains(String.valueOf(qran))) {
RandomizeQuestion();
} else {
generated.add(String.valueOf(qran));
}
}
But here's a much simpler and more efficient way to shuffle a sequence of values:
// generate a list of values between min and max
generated = IntStream.rangeClosed(min, max)
.map(String::valueOf)
.collect(Collectors.toCollection(ArrayList::new));
// shuffle them
Collections.shuffle(generated);
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'm doing a coding challenge online where I'm supposed to write a class that takes in a positive parameter ("num") and returns its multiplicative persistence. This is the number of times you must multiply the digits in "num" until you reach a single digit.
For example, the multiplicative persistence of 39 = 3. This is because:
3 * 9 = 27
2 * 7 = 14
1 * 4 = 4
This is the whole program so far:
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class Persist {
public static void main(String[] args) {
persistence(39);
}
public static int persistence(long num) {
int persistenceValue = 0;
List<Long> digitList = new ArrayList<Long>();
long lastDigit;
//Resolves if num is single digit
if (num <= 9) {
return 0;
}
//Takes each digit of number and stores it to digitList (backwards)
while (num > 0) {
lastDigit = (num % 10);
digitList.add(lastDigit);
num = num / 10;
}
//Takes each digit in digitList and stores it in array in correct order
for (Long d : digitList) {
Long[] currentDigitArray = new Long[digitList.size()];
for (int i = 0; i < currentDigitArray.length; i++) {
currentDigitArray[currentDigitArray.length - i] = d;
}
persistenceValue = currentDigitArray.length;
while (persistenceValue > 1) {
List<Long> productList = multiplyDigits(currentDigitArray);
persistenceValue++;
}
}
return persistenceValue;
}
public static List multiplyDigits(Long[] currentDigitArray) {
//multiplies each digit
List<Long> productList = new ArrayList<Long>();
for (int i = 0; i < currentDigitArray.length; i++) {
Long product = currentDigitArray[i] * currentDigitArray[i + 1];
productList.add(product);
}
return productList;
}
}
I keep running into an array out of bounds exception for the for loop on line 52:
//Takes each digit in digitList and stores it in an array
for (Long d : digitList) {
Long[] currentDigitArray = new Long[digitList.size()];
for (int i = 0; i < currentDigitArray.length; i++) {
currentDigitArray[currentDigitArray.length - i] = d;
// ^ exception is thrown here ^
}
So obviously I looked this up on Google like a good stack overflow user. An array-index out of bounds exception is a Java exception thrown due to the fact that the program is trying to access an element at a position that is outside an array limit, hence the words "Out of bounds."
The problem is that I have no idea how big that array is going to be up front because it's all going to depend on how many digits are passed in by the user. I hard coded 39, but eventually I want the user to be able to put in as many as they want.
So how else would I takes each digit in digitList and store it in array?
This part has been resolved, but now I have a similar problem on line 78:
public static List multiplyDigits(Long[] currentDigitArray) {
//multiplies each digit
List<Long> productList = new ArrayList<Long>();
for (int i = 0; i < currentDigitArray.length; i++) {
Long product = currentDigitArray[i] * currentDigitArray[i + 1];
//^This line here
productList.add(product);
}
return productList;
}
I feel like this is a very similar problem, but don't quite know how to fix it.
This assignment
currentDigitArray[currentDigitArray.length - i] = d;
should be
currentDigitArray[currentDigitArray.length - 1 - i] = d;
to avoid the problem.
With this said, you can avoid arrays entirely by performing multiplication as you go. Recall that the order in which you do multiplication does not change the result. Therefore, you can start multiplication from the back of the number, and arrive at the same solution.
Arrays are zero-indexed, so currentDigitArray.length is always going to be out of bounds. In fact, because of the additive identity property, currentDigitArray.length - i is going to be currentDigitArray.length when i is 0. To fix this, just subtract an extra 1 in your index calculation:
currentDigitArray[currentDigitArray.length - i - 1] = d;
For your second problem, you iterate one element too many, and you need to stop one element earlier:
for (int i = 0; i < currentDigitArray.length - 1; i++) {
I want to use nextProbablePrime() method of BigInteger to get the prime that is lower than the given number instead of higher.
Is it possible to get it using just one nextProbablePrime call?
I don't know whether it's possible using the nextProbablePrime method (in one call). However, I just had a need for a previousProbablePrime method, and I came up with the following method that uses the isProbablePrime method in the BigInteger API:
public static BigInteger previousProbablePrime(BigInteger val) {
// To achieve the same degree of certainty as the nextProbablePrime
// method, use x = 100 --> 2^(-100) == (0.5)^100.
int certainty = 100;
do {
val = val.subtract(BigInteger.ONE);
} while (!val.isProbablePrime(certainty));
return val;
}
I set up the following test just to compare the speed (and accuracy) to the nextProbablePrime method:
private static void testPreviousProbablePrime() {
BigInteger min = BigInteger.ONE; // exclusive
BigInteger max = BigInteger.valueOf(1000000); // exclusive
BigInteger val;
// Create a list of prime numbers in the range given by min and max
// using previousProbablePrime method.
ArrayList<BigInteger> listPrev = new ArrayList<BigInteger>();
Stopwatch sw = new Stopwatch();
sw.start();
val = BigIntegerUtils.previousProbablePrime(max);
while (val.compareTo(min) > 0) {
listPrev.add(val);
val = BigIntegerUtils.previousProbablePrime(val);
}
sw.stop();
System.out.println("listPrev = " + listPrev.toString());
System.out.println("number of items in list = " + listPrev.size());
System.out.println("previousProbablePrime time = " + sw.getHrMinSecMsElapsed());
System.out.println();
// Create a list of prime numbers in the range given by min and max
// using nextProbablePrime method.
ArrayList<BigInteger> listNext = new ArrayList<BigInteger>();
sw.reset();
sw.start();
val = min.nextProbablePrime();
while (val.compareTo(max) < 0) {
listNext.add(val);
val = val.nextProbablePrime();
}
sw.stop();
System.out.println("listNext = " + listNext.toString());
System.out.println("number of items in list = " + listNext.size());
System.out.println("nextProbablePrime time = " + sw.getHrMinSecMsElapsed());
System.out.println();
// Compare the two lists.
boolean identical = true;
int lastIndex = listPrev.size() - 1;
for (int i = 0; i <= lastIndex; i++) {
int j = lastIndex - i;
if (listPrev.get(j).compareTo(listNext.get(i)) != 0) {
identical = false;
break;
}
}
System.out.println("Lists are identical? " + identical);
}
The Stopwatch class is just a basic custom class to track the execution time, so modify those parts to suit the class you might have for this.
I tested for the ranges from 1 to 10000, 100000, and 1000000. The previousProbablePrime method took longer to execute in all three tests. However, it appeared that the difference in execution time increased only modestly with each 10x increase in range size. For 10000, previousProbablePrime executed in just under a second, while nextProbablePrime came in at around 200 ms, for a difference of about 700 or 800 ms. For 1000000, the difference was only about 2 seconds, even though the execution times were 9 and 7 seconds, respectively. Conclusion, the difference in execution time increases slower than the range size.
In all tests, the two lists contained the identical set of prime numbers.
This level of efficiency was sufficient for my needs...might work for you too.
EDIT
Modified method implementation to be more efficient and potentially faster, though I have not tested.
public static BigInteger previousProbablePrime(BigInteger val) {
if (val.compareTo(BigInteger.TWO) < 0) {
throw new IllegalArgumentException("Value must be greater than 1.");
}
// Handle single unique case where even prime is returned.
if (val.equals(new BigInteger("3"))) {
return BigInteger.TWO;
}
// To achieve the same degree of certainty as the nextProbablePrime
// method, use x = 100 --> 2^(-100) == (0.5)^100.
int certainty = 100;
boolean isEven = val.mod(BigInteger.TWO).equals(BigInteger.ZERO);
val = isEven ? val.subtract(BigInteger.ONE) : val.subtract(BigInteger.TWO);
while (!val.isProbablePrime(certainty)) {
// At this point, only check odd numbers.
val = val.subtract(BigInteger.TWO);
}
return val;
}
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;
}
}