Generating a random number between multiple ranges - java

I understand how to make a random number which is between two numbers:
1 + (int)(Math.random() * ((10 - 1) + 1))
or
min + (int)(Math.random() * ((max - min) + 1))
But how do I go about generating a random number which falls into multiple ranges?
For example: number can be between 1 to 10 or between 50 to 60

I'd go with something like this, to allow you to do it with as many ranges as you like:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class RandomInRanges
{
private final List<Integer> range = new ArrayList<>();
RandomInRanges(int min, int max)
{
this.addRange(min, max);
}
final void addRange(int min, int max)
{
for(int i = min; i <= max; i++)
{
this.range.add(i);
}
}
int getRandom()
{
return this.range.get(new Random().nextInt(this.range.size()));
}
public static void main(String[] args)
{
RandomInRanges rir = new RandomInRanges(1, 10);
rir.addRange(50, 60);
System.out.println(rir.getRandom());
}
}

First generate an integer between 1 and 20. Then if the value is above 10, map to the second interval.
Random random = new Random();
for (int i=0;i<100;i++) {
int r = 1 + random.nextInt(60-50+10-1);
if (r>10) r+=(50-10);
System.out.println(r);
}

First, you need to know how many numbers are in each range. (I'm assuming you are choosing integers from a discrete range, not real values from a continuous range.) In your example,
there are 10 integers in the first range, and 11 in the second. This means that 10/21 times, you should choose from the first range, and 11/21 times choose from the second. In pseudo-code
x = random(1,21)
if x in 1..10
return random(1,10)
else
return random(50,60)

if the list is known I think you can use something like this.
public class Test
{
public static void main(String[] args)
{
int a;
for(int i=0;i<10;i++)
{
a=(int) (Math.random()*((10-0)+(60-50)));
if(a<=10)
{
}
else if(a>(60-50))
{
a=a+50;
}
System.out.println(a);
}
}
}

How about the following approach: randomize picking a range an use that range to generage your random number, for that you'll have to put your ranges in some list or array
public class RandomRangeGenerator {
class Range {
public int min, max;
public Range(int min, int max) { this.min = min; this.max = max; }
}
#Test
public void generate() {
List<Range> ranges = new ArrayList<>();
ranges.add(new Range(1, 10));
ranges.add(new Range(50, 60));
List<Integer> randomNumbers = generateRandomNumbers(ranges, 10);
System.out.println(randomNumbers.toString());
for(Integer i : randomNumbers) {
Assert.assertTrue((i >= 1 && i <= 10) || (i >= 50 && i <= 60));
}
}
private List<Integer> generateRandomNumbers(List<Range> ranges, int numberOfNumbers) {
List<Integer> randomNumbers = new ArrayList<>(numberOfNumbers+1);
while(numberOfNumbers-- > 0) {
Range range = ranges.get(new Random().nextInt(ranges.size()));
randomNumbers.add(range.min + (int)(Math.random() * ((range.max - range.min) + 1)));
}
return randomNumbers;
}
}

To generate numbers between two ranges add up the total number of possibilities. 1 - 10 gives us 10 and 50 - 60 gives us another 11, so 21 total. Then, generate a random number between 1 - 21.
int rn = (int)(1 + (Math.random() * 21));
If the random number is between 1 and 10, that is easy, you have your number. If it is between 11 - 21, then you have to do some work. First, you can use modulus to get the index of the number between 50 - 60. Since you have 11 possible values in that range, then mod the random number by 11 and add 50.
if (rn > 10) {
rn %= 11;
rn += 50;
}
System.out.println(rn);
This will print values between 1 - 10 and 50 - 60 inclusive.

Related

Set a minimum and maximum int in a random number array (Java) [duplicate]

How do I generate a random int value in a specific range?
The following methods have bugs related to integer overflow:
randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum = minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.
In Java 1.7 or later, the standard way to do this is as follows:
import java.util.concurrent.ThreadLocalRandom;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
See the relevant JavaDoc. This approach has the advantage of not needing to explicitly initialize a java.util.Random instance, which can be a source of confusion and error if used inappropriately.
However, conversely there is no way to explicitly set the seed so it can be difficult to reproduce results in situations where that is useful such as testing or saving game states or similar. In those situations, the pre-Java 1.7 technique shown below can be used.
Before Java 1.7, the standard way to do this is as follows:
import java.util.Random;
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* #param min Minimum value
* #param max Maximum value. Must be greater than min.
* #return Integer between min and max, inclusive.
* #see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: This will (intentionally) not run as written so that folks
// copy-pasting have to think about how to initialize their
// Random instance. Initialization of the Random instance is outside
// the main scope of the question, but some decent options are to have
// a field that is initialized once and then re-used as needed or to
// use ThreadLocalRandom (if using at least Java 1.7).
//
// In particular, do NOT do 'Random rand = new Random()' here or you
// will get not very good / not very random results.
Random rand;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
See the relevant JavaDoc. In practice, the java.util.Random class is often preferable to java.lang.Math.random().
In particular, there is no need to reinvent the random integer generation wheel when there is a straightforward API within the standard library to accomplish the task.
Note that this approach is more biased and less efficient than a nextInt approach, https://stackoverflow.com/a/738651/360211
One standard pattern for accomplishing this is:
Min + (int)(Math.random() * ((Max - Min) + 1))
The Java Math library function Math.random() generates a double value in the range [0,1). Notice this range does not include the 1.
In order to get a specific range of values first, you need to multiply by the magnitude of the range of values you want covered.
Math.random() * ( Max - Min )
This returns a value in the range [0,Max-Min), where 'Max-Min' is not included.
For example, if you want [5,10), you need to cover five integer values so you use
Math.random() * 5
This would return a value in the range [0,5), where 5 is not included.
Now you need to shift this range up to the range that you are targeting. You do this by adding the Min value.
Min + (Math.random() * (Max - Min))
You now will get a value in the range [Min,Max). Following our example, that means [5,10):
5 + (Math.random() * (10 - 5))
But, this still doesn't include Max and you are getting a double value. In order to get the Max value included, you need to add 1 to your range parameter (Max - Min) and then truncate the decimal part by casting to an int. This is accomplished via:
Min + (int)(Math.random() * ((Max - Min) + 1))
And there you have it. A random integer value in the range [Min,Max], or per the example [5,10]:
5 + (int)(Math.random() * ((10 - 5) + 1))
Use:
Random ran = new Random();
int x = ran.nextInt(6) + 5;
The integer x is now the random number that has a possible outcome of 5-10.
Use:
minValue + rn.nextInt(maxValue - minValue + 1)
With java-8 they introduced the method ints(int randomNumberOrigin, int randomNumberBound) in the Random class.
For example if you want to generate five random integers (or a single one) in the range [0, 10], just do:
Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();
The first parameter indicates just the size of the IntStream generated (which is the overloaded method of the one that produces an unlimited IntStream).
If you need to do multiple separate calls, you can create an infinite primitive iterator from the stream:
public final class IntRandomNumberGenerator {
private PrimitiveIterator.OfInt randomIterator;
/**
* Initialize a new random number generator that generates
* random numbers in the range [min, max]
* #param min - the min value (inclusive)
* #param max - the max value (inclusive)
*/
public IntRandomNumberGenerator(int min, int max) {
randomIterator = new Random().ints(min, max + 1).iterator();
}
/**
* Returns a random number in the range (min, max)
* #return a random number in the range (min, max)
*/
public int nextInt() {
return randomIterator.nextInt();
}
}
You can also do it for double and long values.
You can edit your second code example to:
Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum = rn.nextInt(range) + minimum;
Just a small modification of your first solution would suffice.
Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);
See more here for implementation of Random
ThreadLocalRandom equivalent of class java.util.Random for multithreaded environment. Generating a random number is carried out locally in each of the threads. So we have a better performance by reducing the conflicts.
int rand = ThreadLocalRandom.current().nextInt(x,y);
x,y - intervals e.g. (1,10)
The Math.Random class in Java is 0-based. So, if you write something like this:
Random rand = new Random();
int x = rand.nextInt(10);
x will be between 0-9 inclusive.
So, given the following array of 25 items, the code to generate a random number between 0 (the base of the array) and array.length would be:
String[] i = new String[25];
Random rand = new Random();
int index = 0;
index = rand.nextInt( i.length );
Since i.length will return 25, the nextInt( i.length ) will return a number between the range of 0-24. The other option is going with Math.Random which works in the same way.
index = (int) Math.floor(Math.random() * i.length);
For a better understanding, check out forum post Random Intervals (archive.org).
It can be done by simply doing the statement:
Randomizer.generate(0, 10); // Minimum of zero and maximum of ten
Below is its source code.
File Randomizer.java
public class Randomizer {
public static int generate(int min, int max) {
return min + (int)(Math.random() * ((max - min) + 1));
}
}
It is just clean and simple.
Forgive me for being fastidious, but the solution suggested by the majority, i.e., min + rng.nextInt(max - min + 1)), seems perilous due to the fact that:
rng.nextInt(n) cannot reach Integer.MAX_VALUE.
(max - min) may cause overflow when min is negative.
A foolproof solution would return correct results for any min <= max within [Integer.MIN_VALUE, Integer.MAX_VALUE]. Consider the following naive implementation:
int nextIntInRange(int min, int max, Random rng) {
if (min > max) {
throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
}
int diff = max - min;
if (diff >= 0 && diff != Integer.MAX_VALUE) {
return (min + rng.nextInt(diff + 1));
}
int i;
do {
i = rng.nextInt();
} while (i < min || i > max);
return i;
}
Although inefficient, note that the probability of success in the while loop will always be 50% or higher.
I wonder if any of the random number generating methods provided by an Apache Commons Math library would fit the bill.
For example: RandomDataGenerator.nextInt or RandomDataGenerator.nextLong
I use this:
/**
* #param min - The minimum.
* #param max - The maximum.
* #return A random double between these numbers (inclusive the minimum and maximum).
*/
public static double getRandom(double min, double max) {
return (Math.random() * (max + 1 - min)) + min;
}
You can cast it to an Integer if you want.
As of Java 7, you should no longer use Random. For most uses, the
random number generator of choice is now
ThreadLocalRandom.For fork join pools and parallel
streams, use SplittableRandom.
Joshua Bloch. Effective Java. Third Edition.
Starting from Java 8
For fork join pools and parallel streams, use SplittableRandom that is usually faster, has a better statistical independence and uniformity properties in comparison with Random.
To generate a random int in the range [0, 1_000]:
int n = new SplittableRandom().nextInt(0, 1_001);
To generate a random int[100] array of values in the range [0, 1_000]:
int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();
To return a Stream of random values:
IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
rand.nextInt((max+1) - min) + min;
Let us take an example.
Suppose I wish to generate a number between 5-10:
int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);
Let us understand this...
Initialize max with highest value and min with the lowest value.
Now, we need to determine how many possible values can be obtained. For this example, it would be:
5, 6, 7, 8, 9, 10
So, count of this would be max - min + 1.
i.e. 10 - 5 + 1 = 6
The random number will generate a number between 0-5.
i.e. 0, 1, 2, 3, 4, 5
Adding the min value to the random number would produce:
5, 6, 7, 8, 9, 10
Hence we obtain the desired range.
Generate a random number for the difference of min and max by using the nextint(n) method and then add min number to the result:
Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
To generate a random number "in between two numbers", use the following code:
Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;
This gives you a random number in between 1 (inclusive) and 11 (exclusive), so initialize the upperBound value by adding 1. For example, if you want to generate random number between 1 to 10 then initialize the upperBound number with 11 instead of 10.
Just use the Random class:
Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
These methods might be convenient to use:
This method will return a random number between the provided minimum and maximum value:
public static int getRandomNumberBetween(int min, int max) {
Random foo = new Random();
int randomNumber = foo.nextInt(max - min) + min;
if (randomNumber == min) {
// Since the random number is between the min and max values, simply add 1
return min + 1;
} else {
return randomNumber;
}
}
and this method will return a random number from the provided minimum and maximum value (so the generated number could also be the minimum or maximum number):
public static int getRandomNumberFrom(int min, int max) {
Random foo = new Random();
int randomNumber = foo.nextInt((max + 1) - min) + min;
return randomNumber;
}
In case of rolling a dice it would be random number between 1 to 6 (not 0 to 6), so:
face = 1 + randomNumbers.nextInt(6);
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();
Or take a look to RandomUtils from Apache Commons.
You can achieve that concisely in Java 8:
Random random = new Random();
int max = 10;
int min = 5;
int totalNumber = 10;
IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);
Here's a helpful class to generate random ints in a range with any combination of inclusive/exclusive bounds:
import java.util.Random;
public class RandomRange extends Random {
public int nextIncInc(int min, int max) {
return nextInt(max - min + 1) + min;
}
public int nextExcInc(int min, int max) {
return nextInt(max - min) + 1 + min;
}
public int nextExcExc(int min, int max) {
return nextInt(max - min - 1) + 1 + min;
}
public int nextIncExc(int min, int max) {
return nextInt(max - min) + min;
}
}
Another option is just using Apache Commons:
import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;
public void method() {
RandomData randomData = new RandomDataImpl();
int number = randomData.nextInt(5, 10);
// ...
}
I found this example Generate random numbers :
This example generates random integers in a specific range.
import java.util.Random;
/** Generate random integers in a certain range. */
public final class RandomRange {
public static final void main(String... aArgs){
log("Generating random integers in the range 1..10.");
int START = 1;
int END = 10;
Random random = new Random();
for (int idx = 1; idx <= 10; ++idx){
showRandomInteger(START, END, random);
}
log("Done.");
}
private static void 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);
log("Generated : " + randomNumber);
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
An example run of this class :
Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.
public static Random RANDOM = new Random(System.nanoTime());
public static final float random(final float pMin, final float pMax) {
return pMin + RANDOM.nextFloat() * (pMax - pMin);
}
Here is a simple sample that shows how to generate random number from closed [min, max] range, while min <= max is true
You can reuse it as field in hole class, also having all Random.class methods in one place
Results example:
RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert
Sources:
import junit.framework.Assert;
import java.util.Random;
public class RandomUtils extends Random {
/**
* #param min generated value. Can't be > then max
* #param max generated value
* #return values in closed range [min, max].
*/
public int nextInt(int min, int max) {
Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
if (min == max) {
return max;
}
return nextInt(max - min + 1) + min;
}
}
It's better to use SecureRandom rather than just Random.
public static int generateRandomInteger(int min, int max) {
SecureRandom rand = new SecureRandom();
rand.setSeed(new Date().getTime());
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
rand.nextInt((max+1) - min) + min;
This is working fine.

Flipping a coin and stopping when it lands heads 4 times in a row

The assignment is to flip a coin until four heads in a row are seen and display all the results leading up to that. I keep getting the last error message I put in just in case it fell through. I have no idea what I messed up and was wondering if someone was able to help.
class Main {
public static void main(String[] args) {
int h = 2;
int t = 1;
int count = 0;
int result;
while (count<=4)
{
result = (int)Math.random()*2;
if (result == 2)
{
count++;
System.out.print("H ");
}
else if (result == 1)
{
count=0;
System.out.print("T ");
}
else
System.out.println("error");
}
}
}
(int)Math.random() * 2
is the same as
((int)Math.random()) * 2
Given that Math.random() returns a number at least zero but less than one, your expression is always going to be zero.
Put in parentheses:
(int) (Math.random() * 2)
But then, also look at the values of result in your conditionals: you will never generate 2.
You need to add 1 to have possible values of one or two:
result = (int) (Math.random() * 2 + 1);
You can use the Randomclass and boolean
Random random = new Random();
int count = 0;
while (count < 4) {
if (random.nextBoolean()) {
System.out.print("H");
count++;
} else {
count = 0;
System.out.print("T");
}
}
As the result of Math.random() is between 0 and 1 type casting it to int will remove the digits after decimal point and you'll always have zero as answer.
Below code will help you to generate a random number between min and max.
// define the range
int max = 2;
int min = 1;
int range = max - min + 1;
int rand = (int)(Math.random() * range) + min;
For an explanation of how this works you can put the min possible value of 0 and max possible of 0.99 and multiply both by any range, let's say 20 the answer will still be in between 1 to 20.8 which gets turned to 20 as it's not rounding off but directly type casting. Hence, this can give you a random number for any range.

How to generate a list of palindromes without a check

I'm working on a problem where I'm required to manipulate large lists of palindromes up to a certain number of digits. This should work with numbers up 15 digits. The most common method I've seen for this is iterating through each number and checking whether each is a palindrome and then adding that to a list. This is my implementation in java and it works fine.
public class Palindrome {
public ArrayList<Long> List = new ArrayList<Long>();
public double d;
public Palindrome(double digits) {
this.d = digits;
long dig = (int)(Math.pow(10,digits));
for (long i = 1; i <= dig; i++) {
long a = i;
long b = inverse(a);
if (a == b) {
List.add(a);
}
}
public long inverse(long x){
long inv = 0;
while (x > 0) {
inv = inv * 10 + x % 10;
x = x / 10;
}
return inv;
}
}
Only problem is it's pretty slow when I get to 10+ digit palindromes. I've been considering alternative ways to create this list and one consideration I've had is generating the list of palindromes rather than iterating through each number and checking if it's a palindrome.
I'm still working on paper but the pattern isn't as obvious as I thought I would find it to turn into pseudocode. I'm working it out that for n number of digits, going from i to n, if the number of digits is even, generate numbers from 1 up to [10^(i/2 + 1) - 1]. Then append the reverse of each number to itself. A little stuck on how to do it for the odd digits. That's where I am right now.
I will come back with my own response if I figure this out and implement the code but in the meantime, I would just like to know if anyone has done this before or has an alternative method I've overlooked that would be more efficient.
UPDATE
So I did manage to work out something thanks to all your suggestions. I decided to work with the numbers as strings but contrary to what I intended this has actually increased the runtime :/
public class Palindrome2 {
public ArrayList<Long> List = new ArrayList<Long>();
public double d;
public Palindrome2(double digits) {
this.d = digits;
for (long n = 1; n <= d; n++) {
if (n == 1) {
for (long i = 1; i < 10; i++) {
List.add(i);
}
}
if (n % 2 != 0 && n != 1) {
long max = (long) Math.pow(10, (n + 1) / 2);
long min = (long) Math.pow(10, Math.floor(n / 2));
for (long i = min; i < max; i++) {
String str = Long.toString(i);
str = str + removeFirst(reverse(str));
Long x = Long.parseLong(str);
List.add(x);
}
} else if (n % 2 == 0) {
long max = (long) (Math.pow(10, Math.floor((n + 1) / 2)) - 1);
long min = (long) Math.pow(10, (n / 2) - 1);
for (long i = min; i <= max; i++) {
String str = Long.toString(i);
str = str + reverse(str);
Long x = Long.parseLong(str);
List.add(x);
}
}
}
}
public String reverse(String x) {
String rev = new StringBuffer(x).reverse().toString();
return rev;
}
public String removeFirst(String x) {
return x.substring(1);
}
}
Once again, accurate but still slow :(
Introduction
You need to analyzing the regular pattern for an algorithm roughly before jump into developing, that will saving lot of time, for example:
each 1 digit is 1 palindrome, e.g: 1
each 2 digits has 1 palindrome, e.g: 11.
each 3 digits has 10 palindromes, e.g: 101,111,...,191.
each 4 digits has 10 palindromes, e.g: 1001, 1111, ..., 1991.
each 5 digits has 100 palindromes, e.g: 10001, 11011, ..., 19091, ..., 19991.
each 6 digits has 100 palindromes, e.g: 100001, 110011, ..., 190091, ..., 199991.
each 7 digits has 1000 palindromes, e.g: 1000001, ...,1900091,...,1090901, ..., 1999991.
each 8 digits has 1000 palindromes, e.g: 10000001, ...,19000091,...,10900901, ..., 19999991.
....
then you can write some arrangement algorithm to implement this .
Implementation
But I can tell you this implementation can optimizing as further, if you using a cache to saving palindromes generated from low digits palindromes(2), then any high digits palindromes(n>2) can reusing it.
Maybe it's not robust but it pass all my tests on github. I left the rest working & optimization to you, and I wish you can done by yourself.
private static List<Integer> palindromes(int digits) {
return palindromes(digits, 0);
}
private static List<Integer> palindromes(int digits, int shifts) {
List<Integer> result = new ArrayList<>();
int radix = (int) Math.pow(10, digits - 1);
int renaming = digits - 2;
boolean hasRenaming = renaming > 0;
for (int i = start(digits, shifts); i <= 9; i++) {
int high = i * radix;
int low = low(digits, i);
if (hasRenaming) {
for (Integer m : palindromes(renaming, shifts + 1)) {
int ret = high + m * 10 + low;
if (ret < 0) {
return result;
}
result.add(ret);
}
} else {
result.add(high + low);
}
}
return result;
}
private static int low(int digits, int high) {
return digits > 1 ? high : 0;
}
private static int start(int digits, int shifts) {
return digits > 1 && shifts == 0 ? 1 : 0;
}
Usage
then you can collect all palindrome numbers as below:
// v--- min:0, max: 2147447412, count: 121474
List<Integer> all = IntStream.rangeClosed(1, 10)
.mapToObj(PalindromeTest::palindromes)
.flatMap(List::stream)
.collect(Collectors.toList());
Time Cost:
191ms
Enable Caching
public class Palindromes {
private static final int[] startingNonZerosTable = {
0,// 0
0, 1,// 1 2
10, 10,//3 4
100, 100, //5 6
1000, 1000,//7 8
10000, 10000,// 9 10
100000, 100000,//11 12
1000000, 1000000,//13 14
10000000, 10000000,//15 16
100000000, 100000000,//17 18
1000000000, 1000000000//19 20
};
private static final int MAX_DIGIT = 9;
private static final int MIN_DIGIT = 0;
private static final int RADIX = MAX_DIGIT - MIN_DIGIT + 1;
private static final int LONG_MAX_DIGITS = 19;
private static volatile long[][] cache = new long[LONG_MAX_DIGITS + 1][];
// includes palindromes(0) ---^
static {
cache[0] = new long[0];
cache[1] = new long[]{0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L};
cache[2] = new long[]{0L, 11L, 22L, 33L, 44L, 55L, 66L, 77L, 88L, 99L};
}
public static LongStream since1(int end) {
return between(1, end);
}
public static LongStream between(int start, int end) {
return IntStream.rangeClosed(start, end)
.mapToObj(Palindromes::of)
.flatMapToLong(identity());
}
public static LongStream of(int digits) {
return Arrays.stream(palindromes0(digits))
.skip(startingNonZerosTable[digits]);
}
private final static long[] palindromes0(int digits) {
if (cache[digits] != null) {
return cache[digits];
}
long[] result = new long[sizeOf(digits)];
int size = 0;
long high = (long) Math.pow(RADIX, digits - 1);
for (int i = MIN_DIGIT; i <= MAX_DIGIT; i++) {
for (long mid : palindromes0(digits - 2)) {
long value = i * high + mid * RADIX + i;
if (value < 0) {//overflow
return cache[digits] = Arrays.copyOf(result, size);
}
result[size++] = value;
}
}
return cache[digits] = result;
}
private static int sizeOf(int digits) {
return MAX_DIGIT * (int) Math.pow(RADIX, (digits - 1) >>> 1)
+ startingNonZerosTable[digits];
}
// v--- java -Xms1024m -Xmx2048m test.algorithm.Palindromes
public static void main(String[] args) {
Duration duration = timing(() -> {
// palindromes[1..15] ---v
LongSummaryStatistics result = since1(15).summaryStatistics();
long max = result.getMax();
long count = result.getCount();
System.out.printf("Max: %d, Count: %d%n", max, count);
});
System.out.printf("Time Elapsed:%s%n", duration);
// ^--- time elapsed: 4s
}
private static Duration timing(Runnable task) {
long starts = System.currentTimeMillis();
task.run();
return Duration.ofMillis(System.currentTimeMillis() - starts);
}
}
Time Cost:
palindromes[1..15] time elapsed: 4s
Have you tried working with characters rather than numbers? You could generate the palindrome as a string of digits and then convert to a number at the end. Something like this pseudocode:
generatePalindrome(size)
half <- size DIV 2 // Integer division
result <- ""
result.append(randomDigitIn(1..9)) // No leading zeros.
while (result.length <= half)
result.append(randomDigitIn(0..9))
endwhile
if (size is odd)
result <- result + randomDigitIn(0..9) + result.reverse()
else
result <- result + result.reverse()
endif
return number.parse(result)
end generatePalindrome()
Basically you randomly generate half the palindrome, avoiding leading zeros, insert an extra digit in the middle for odd lengths, append the reversed first half and then parse the digit string into the number format you want.
For odd digit you can simply reuse the palindromes generated at the previous even step , split them in half and insert in the middle all the possible number from 0 to 9.
Let's say you need to generate the palindrom of 3 digit, simply get all the palindromes of 2 digit and add insert all the number from 0 to 9.
We have 22 than we can generate:
202
212
222
232
and so on
Hope my idea is clear:)
Try something like this:
public class Palindrome
{
public static ArrayList<Long> calculatePalindromes(int maxLength) {
ArrayList<Long> result = new ArrayList<>();
if (maxLength <= 0) {
return result;
}
long maxPart = (long)Math.pow(10, maxLength / 2);
for (long i = 0; i < 10; ++i) {
result.add(i);
}
for (long i = 1; i < maxPart; ++i) {
long curHalf = i;
long curNum = i;
int curLen = 0;
while (curHalf != 0) {
curNum *= 10;
curNum += curHalf % 10;
curHalf /= 10;
++curLen;
}
result.add(curNum);
// insert numbers from 0 to 9
if (curLen * 2 + 1 > maxLength) {
continue;
}
for (int j = 0; j < 10; ++j) {
curHalf = i;
curNum = i;
curNum *= 10;
curNum += j;
while (curHalf != 0) {
curNum *= 10;
curNum += curHalf % 10;
curHalf /= 10;
}
result.add(curNum);
}
}
return result;
}
}
The idea is to insert numbers from 0 to 9 after each X and add reversed(X) after it so we get X (1..9) reversed(X).
You can generate all palindromes in the needed range without check, but you will probably face with the memory insufficiency, as storing all these numbesr for 15-length upper number in the list - is a bad idea.
More specifically your code will looks like:
long dig = (long) Math.pow(10, digits / 2);
int pow = 10;
int npow = 100;
for (long i = 1; i <= dig; i++) {
System.out.println(i * pow + inverse(i));
System.out.println(i * pow / 10 + inverse(i / 10));
// list.add(i * pow + inverse(i));
// list.add(i * pow/10 + inverse(i / 10));
if (i % pow == 0) {
pow = npow;
npow *= 10;
}
}
I have deliberately commented list adding lines.
The idea is to push into list/output all numbers composed with given half as:
XXXY+YXXX
and
XXX+Y+XXX
i.e. generating both cases: odd and even palindromes.

Using (Math.random() * ((upperbound - lowerbound) + 1) + lowerbound) in JAVA generates a number out of the specified range [duplicate]

How do I generate a random int value in a specific range?
The following methods have bugs related to integer overflow:
randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum = minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.
In Java 1.7 or later, the standard way to do this is as follows:
import java.util.concurrent.ThreadLocalRandom;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
See the relevant JavaDoc. This approach has the advantage of not needing to explicitly initialize a java.util.Random instance, which can be a source of confusion and error if used inappropriately.
However, conversely there is no way to explicitly set the seed so it can be difficult to reproduce results in situations where that is useful such as testing or saving game states or similar. In those situations, the pre-Java 1.7 technique shown below can be used.
Before Java 1.7, the standard way to do this is as follows:
import java.util.Random;
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* #param min Minimum value
* #param max Maximum value. Must be greater than min.
* #return Integer between min and max, inclusive.
* #see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: This will (intentionally) not run as written so that folks
// copy-pasting have to think about how to initialize their
// Random instance. Initialization of the Random instance is outside
// the main scope of the question, but some decent options are to have
// a field that is initialized once and then re-used as needed or to
// use ThreadLocalRandom (if using at least Java 1.7).
//
// In particular, do NOT do 'Random rand = new Random()' here or you
// will get not very good / not very random results.
Random rand;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
See the relevant JavaDoc. In practice, the java.util.Random class is often preferable to java.lang.Math.random().
In particular, there is no need to reinvent the random integer generation wheel when there is a straightforward API within the standard library to accomplish the task.
Note that this approach is more biased and less efficient than a nextInt approach, https://stackoverflow.com/a/738651/360211
One standard pattern for accomplishing this is:
Min + (int)(Math.random() * ((Max - Min) + 1))
The Java Math library function Math.random() generates a double value in the range [0,1). Notice this range does not include the 1.
In order to get a specific range of values first, you need to multiply by the magnitude of the range of values you want covered.
Math.random() * ( Max - Min )
This returns a value in the range [0,Max-Min), where 'Max-Min' is not included.
For example, if you want [5,10), you need to cover five integer values so you use
Math.random() * 5
This would return a value in the range [0,5), where 5 is not included.
Now you need to shift this range up to the range that you are targeting. You do this by adding the Min value.
Min + (Math.random() * (Max - Min))
You now will get a value in the range [Min,Max). Following our example, that means [5,10):
5 + (Math.random() * (10 - 5))
But, this still doesn't include Max and you are getting a double value. In order to get the Max value included, you need to add 1 to your range parameter (Max - Min) and then truncate the decimal part by casting to an int. This is accomplished via:
Min + (int)(Math.random() * ((Max - Min) + 1))
And there you have it. A random integer value in the range [Min,Max], or per the example [5,10]:
5 + (int)(Math.random() * ((10 - 5) + 1))
Use:
Random ran = new Random();
int x = ran.nextInt(6) + 5;
The integer x is now the random number that has a possible outcome of 5-10.
Use:
minValue + rn.nextInt(maxValue - minValue + 1)
With java-8 they introduced the method ints(int randomNumberOrigin, int randomNumberBound) in the Random class.
For example if you want to generate five random integers (or a single one) in the range [0, 10], just do:
Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();
The first parameter indicates just the size of the IntStream generated (which is the overloaded method of the one that produces an unlimited IntStream).
If you need to do multiple separate calls, you can create an infinite primitive iterator from the stream:
public final class IntRandomNumberGenerator {
private PrimitiveIterator.OfInt randomIterator;
/**
* Initialize a new random number generator that generates
* random numbers in the range [min, max]
* #param min - the min value (inclusive)
* #param max - the max value (inclusive)
*/
public IntRandomNumberGenerator(int min, int max) {
randomIterator = new Random().ints(min, max + 1).iterator();
}
/**
* Returns a random number in the range (min, max)
* #return a random number in the range (min, max)
*/
public int nextInt() {
return randomIterator.nextInt();
}
}
You can also do it for double and long values.
You can edit your second code example to:
Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum = rn.nextInt(range) + minimum;
Just a small modification of your first solution would suffice.
Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);
See more here for implementation of Random
ThreadLocalRandom equivalent of class java.util.Random for multithreaded environment. Generating a random number is carried out locally in each of the threads. So we have a better performance by reducing the conflicts.
int rand = ThreadLocalRandom.current().nextInt(x,y);
x,y - intervals e.g. (1,10)
The Math.Random class in Java is 0-based. So, if you write something like this:
Random rand = new Random();
int x = rand.nextInt(10);
x will be between 0-9 inclusive.
So, given the following array of 25 items, the code to generate a random number between 0 (the base of the array) and array.length would be:
String[] i = new String[25];
Random rand = new Random();
int index = 0;
index = rand.nextInt( i.length );
Since i.length will return 25, the nextInt( i.length ) will return a number between the range of 0-24. The other option is going with Math.Random which works in the same way.
index = (int) Math.floor(Math.random() * i.length);
For a better understanding, check out forum post Random Intervals (archive.org).
It can be done by simply doing the statement:
Randomizer.generate(0, 10); // Minimum of zero and maximum of ten
Below is its source code.
File Randomizer.java
public class Randomizer {
public static int generate(int min, int max) {
return min + (int)(Math.random() * ((max - min) + 1));
}
}
It is just clean and simple.
Forgive me for being fastidious, but the solution suggested by the majority, i.e., min + rng.nextInt(max - min + 1)), seems perilous due to the fact that:
rng.nextInt(n) cannot reach Integer.MAX_VALUE.
(max - min) may cause overflow when min is negative.
A foolproof solution would return correct results for any min <= max within [Integer.MIN_VALUE, Integer.MAX_VALUE]. Consider the following naive implementation:
int nextIntInRange(int min, int max, Random rng) {
if (min > max) {
throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
}
int diff = max - min;
if (diff >= 0 && diff != Integer.MAX_VALUE) {
return (min + rng.nextInt(diff + 1));
}
int i;
do {
i = rng.nextInt();
} while (i < min || i > max);
return i;
}
Although inefficient, note that the probability of success in the while loop will always be 50% or higher.
I wonder if any of the random number generating methods provided by an Apache Commons Math library would fit the bill.
For example: RandomDataGenerator.nextInt or RandomDataGenerator.nextLong
I use this:
/**
* #param min - The minimum.
* #param max - The maximum.
* #return A random double between these numbers (inclusive the minimum and maximum).
*/
public static double getRandom(double min, double max) {
return (Math.random() * (max + 1 - min)) + min;
}
You can cast it to an Integer if you want.
As of Java 7, you should no longer use Random. For most uses, the
random number generator of choice is now
ThreadLocalRandom.For fork join pools and parallel
streams, use SplittableRandom.
Joshua Bloch. Effective Java. Third Edition.
Starting from Java 8
For fork join pools and parallel streams, use SplittableRandom that is usually faster, has a better statistical independence and uniformity properties in comparison with Random.
To generate a random int in the range [0, 1_000]:
int n = new SplittableRandom().nextInt(0, 1_001);
To generate a random int[100] array of values in the range [0, 1_000]:
int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();
To return a Stream of random values:
IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
rand.nextInt((max+1) - min) + min;
Let us take an example.
Suppose I wish to generate a number between 5-10:
int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);
Let us understand this...
Initialize max with highest value and min with the lowest value.
Now, we need to determine how many possible values can be obtained. For this example, it would be:
5, 6, 7, 8, 9, 10
So, count of this would be max - min + 1.
i.e. 10 - 5 + 1 = 6
The random number will generate a number between 0-5.
i.e. 0, 1, 2, 3, 4, 5
Adding the min value to the random number would produce:
5, 6, 7, 8, 9, 10
Hence we obtain the desired range.
Generate a random number for the difference of min and max by using the nextint(n) method and then add min number to the result:
Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
To generate a random number "in between two numbers", use the following code:
Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;
This gives you a random number in between 1 (inclusive) and 11 (exclusive), so initialize the upperBound value by adding 1. For example, if you want to generate random number between 1 to 10 then initialize the upperBound number with 11 instead of 10.
Just use the Random class:
Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
These methods might be convenient to use:
This method will return a random number between the provided minimum and maximum value:
public static int getRandomNumberBetween(int min, int max) {
Random foo = new Random();
int randomNumber = foo.nextInt(max - min) + min;
if (randomNumber == min) {
// Since the random number is between the min and max values, simply add 1
return min + 1;
} else {
return randomNumber;
}
}
and this method will return a random number from the provided minimum and maximum value (so the generated number could also be the minimum or maximum number):
public static int getRandomNumberFrom(int min, int max) {
Random foo = new Random();
int randomNumber = foo.nextInt((max + 1) - min) + min;
return randomNumber;
}
In case of rolling a dice it would be random number between 1 to 6 (not 0 to 6), so:
face = 1 + randomNumbers.nextInt(6);
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();
Or take a look to RandomUtils from Apache Commons.
You can achieve that concisely in Java 8:
Random random = new Random();
int max = 10;
int min = 5;
int totalNumber = 10;
IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);
Here's a helpful class to generate random ints in a range with any combination of inclusive/exclusive bounds:
import java.util.Random;
public class RandomRange extends Random {
public int nextIncInc(int min, int max) {
return nextInt(max - min + 1) + min;
}
public int nextExcInc(int min, int max) {
return nextInt(max - min) + 1 + min;
}
public int nextExcExc(int min, int max) {
return nextInt(max - min - 1) + 1 + min;
}
public int nextIncExc(int min, int max) {
return nextInt(max - min) + min;
}
}
Another option is just using Apache Commons:
import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;
public void method() {
RandomData randomData = new RandomDataImpl();
int number = randomData.nextInt(5, 10);
// ...
}
I found this example Generate random numbers :
This example generates random integers in a specific range.
import java.util.Random;
/** Generate random integers in a certain range. */
public final class RandomRange {
public static final void main(String... aArgs){
log("Generating random integers in the range 1..10.");
int START = 1;
int END = 10;
Random random = new Random();
for (int idx = 1; idx <= 10; ++idx){
showRandomInteger(START, END, random);
}
log("Done.");
}
private static void 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);
log("Generated : " + randomNumber);
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
An example run of this class :
Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.
public static Random RANDOM = new Random(System.nanoTime());
public static final float random(final float pMin, final float pMax) {
return pMin + RANDOM.nextFloat() * (pMax - pMin);
}
Here is a simple sample that shows how to generate random number from closed [min, max] range, while min <= max is true
You can reuse it as field in hole class, also having all Random.class methods in one place
Results example:
RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert
Sources:
import junit.framework.Assert;
import java.util.Random;
public class RandomUtils extends Random {
/**
* #param min generated value. Can't be > then max
* #param max generated value
* #return values in closed range [min, max].
*/
public int nextInt(int min, int max) {
Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
if (min == max) {
return max;
}
return nextInt(max - min + 1) + min;
}
}
It's better to use SecureRandom rather than just Random.
public static int generateRandomInteger(int min, int max) {
SecureRandom rand = new SecureRandom();
rand.setSeed(new Date().getTime());
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
rand.nextInt((max+1) - min) + min;
This is working fine.

Write a program to round a number to the next multiple of 10 given the following conditions?

Write a program to Round a number to the next multiple of 10 if its ones digit is 5 or more, otherwise round it the previous multiple of 10.So, 25 and 26 round to 30 where as 23 and 24 round to 20. 20 also rounds to 20. You have been given 4 ints as input. Round each of the input values and return their sum.
MyApproach
I created 2 functions in the first function I counted the sum of all 4 numbers.
In the second function I checked the UnitDigtit if>=5 &&<=9 Then proceed with set of statements given in the question.
else
I checked if Its a one digit or two or any digit number.If One digit I returned num=0 else I proceded with the sets of statements.
Sample Input #1
sumRounded(11,15,23,30)
Sample Output #1
80 (11 rounds to 10, 15 to 20, 23 to 20 and 30 to 30)
Sample Input #2
sumRounded(1,3,7,9)
Sample Output #2
20
public int sumRounded(int num1, int num2, int num3, int num4)
{
int a=checkRound(num1);
int b=checkRound(num2);
int c=checkRound(num3);
int d=checkRound(num4);
return a+b+c+d;
}
public int checkRound(int num)
{
int a=num%10;
if((a>=5) &&(a<=9))
{
if(a==5)
{
num=num+5;
}
else if(a==6)
{
num=num+6;
}
else if(a==7)
{
num=num+7;
}
else if(a==8)
{
num=num+8;
}
else if(a==9)
{
num=num+9;
}
return num;
}
else
{
if((num/10)!=0)
{
if(a==1)
{
num=num-1;
}
else if(a==2)
{
num=num-2;
}
else if(a==3)
{
num=num-3;
}
else if(a==4)
{
num=num-4;
}
return num;
}
else
{
return num=0;
}
}
}
Results:
Parameters Actual Output Expected Output
'289' '3' '25' '308' 644 630
Rounding
If the remainder is less than 5, subtract it from num. Otherwise, add ten minus the remainder to the num. Something like,
static int checkRound(int num) {
int rem = num % 10;
return rem < 5 ? num - rem : num + (10 - rem);
}
or use Math.round(float) like
static int checkRound(int num) {
return Math.round((float) num / 10) * 10;
}
Varargs
You could also implement sumRounded as a varargs method with a for-each loop
static int sumRounded(int... nums) {
int sum = 0;
for (int num : nums) {
sum += checkRound(num);
}
return sum;
}
Testing
Then you could test it like,
public static void main(String[] args) {
System.out.println(sumRounded(11, 15, 23, 30)); // == 80
System.out.println(sumRounded(1, 3, 7, 9)); // == 20
}
Simply use the reminder check inside checkRounded method
int number = 23;
int output=0;
if(number%10<5){
output=(number/10)*10;
}
else{
output=((number/10)+1)*10;
}
System.out.println(output);
You simply put following code in you chexkRound method
int a = num % 10;
if ((a >= 5) && (a <= 9)) {
num = 10 * (num / 10 + 1);
} else {
num = 10 * (num / 10);
}
return num;
If you want to fix you way do the following but Exbury's answer is a shorter way of doing it.
If you are rounding up you should add the 10 minus the number, not the number itself. So for example, 26 rounded up should be 26+(10-6) = 26+(4) = 30
Well the following code perfectly suits your need
//code starts
public static void main(String[] args) {
System.out.println("The answer is: " + getSum(2,5,19));
}
public static int getSum(int... nums) {
int sum = 0;
for (int n : nums) {
int lastDigit = n % 10;
if (lastDigit >= 5) {
sum = sum + n + (10 - (lastDigit));
} else {
sum = sum + 10 * (n / 10);
}
}
return sum;
}
//code ends

Categories

Resources