Distribute Range of Numbers between each threads - java

Config File
ThreadSize = 10
StartRange = 1
EndRange = 1000
I have a config file above in which I have number of threads I want to use and the client instance is able to use ID range from 1 to 1000 and suppose the client threads is set at 10, so each thread would have range of 100 id's(basically by dividing end range with thread size) that it can use without stepping on other threads. so What I want is that each thread should use 100 id's from that range without stepping on other threads- for example
Thread1 will use 1 to 100 (id's)
// generate a random number between 1 to 100 and keep on printing values until it has generated all the random values between 1 to 100
Thread2 will use 101 to 200 (id's)
// generate a random number between 101 to 200 and keep on printing values until it has generated all the random values between 101 to 200
Thread3 will use 201 to 300 (id's)
// generate a random number between 201 to 300 and keep on printing values until it has generated all the random values between 201 to 300
-----
----
Thread10 will use 901 to 1000
// generate a random number between 901 to 1000 and keep on printing values until it has generated all the random values between 901 to 1000
I know how to write a multithreading program, but not sure how should I divide the range between various threads.
public static void main(String[] args) {
for (int i = 1; i <= threadSize; i++) {
new Thread(new ThreadTask(i)).start();
}
}
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public synchronized void run() {
}
}

Each thread gets N = (EndRange - StartRange + 1) / ThreadSize numbers.
Thread number i gets range (StartRange + i*N) - (StartRange + i*N + N - 1).
In your example N = (1000 - 1 + 1) / 10 = 100.
Thread i = 0 would get range (1 + 0*100) - (1 + 0*100 + 100 - 1) = 1 - 100
Thread i = 1 would get range (1 + 1*100) - (1 + 1*100 + 100 - 1) = 101 - 200
...

public class MyThread extends Thread {
public static final int TOTAL_THREADS = 10;
public static final int START_RANGE = 1;
public static final int END_RANGE = 1000;
public static final int N = (END_RANGE - START_RANGE + 1) / TOTAL_THREADS;
int threadNo;
static volatile int counter = 1;
public final static Object obj = new Object();
public MyThread(int threadNo) {
this.threadNo = threadNo;
}
#Override
public void run() {
synchronized (obj) {
while (counter <= 1000) {
if (counter >= (START_RANGE + threadNo * N) && counter <= (START_RANGE + threadNo * N + N - 1)) {
System.out.println((this.threadNo + 1) + " prints " + counter++);
obj.notifyAll();
} else {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String args[]) {
for (int i = 0; i < TOTAL_THREADS; i++) {
System.out.println("Call thread : " + (i + 1));
MyThread th = new MyThread(i);
th.start();
}
}
}

Related

How do I make a program that counts the occurrence of each individual digit between 1 and 100?

I'm making a program that counts how many times each digit (0-9) occurs in each number between 1 to 100. At the end it will say something like:
The digit 0 showed up ____ times between 1-100
The digit 1 showed up ____ times between 1-100
and so forth.
This is what I have:
public class CountEachDigit {
public static void main(String[] args) {
int counter =0;
int[] digit = new int[10];
for (int i=1;i<=100;i++) {
for (int j=0;j<=9;j++){
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(0)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(1)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(2)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
}
}
for (int j =0;j<=9;j++){
System.out.println("The number "+j+" appears "+digit[j]+" times between 1 - 100.");
}
}
}
I tried changing the charAt each digit to a String to count the occurrence using the try and catch. No dice so far.
You do not need a string operations. You have to use x % 10 to get the last digit, and then x \= 10, to remove this last digit.
public class CountEachDigit {
public static void main(String... args) {
final int lo = 1;
final int hi = 100;
int[] digits = countDigits(lo, hi);
for (int i = 0; i < 10; i++)
System.out.format("The number %d appears %d times between %d - %d.\n", i, digits[i], lo, hi);
}
private static int[] countDigits(int lo, int hi) {
int[] digits = new int[10];
for (int i = lo; i <= hi; i++) {
int val = i;
do {
digits[val % 10]++;
} while ((val /= 10) > 0);
}
return digits;
}
}
Demo:
The number 0 appears 11 times between 1 - 100.
The number 1 appears 21 times between 1 - 100.
The number 2 appears 20 times between 1 - 100.
The number 3 appears 20 times between 1 - 100.
The number 4 appears 20 times between 1 - 100.
The number 5 appears 20 times between 1 - 100.
The number 6 appears 20 times between 1 - 100.
The number 7 appears 20 times between 1 - 100.
The number 8 appears 20 times between 1 - 100.
The number 9 appears 20 times between 1 - 100.
Have an array with int[10] to count the occurrences for each digit.
Then have a function that traverses a string and for each digit it finds increases the correct field in the array.
Then have a loop over numbers from 1 to 100 which converts that number to string and feeds it into the function.
Finally print the array values.
In code this may look like
public class Test {
static int[] occurrences = new int[10];
static void checkOccurrences(String s) {
for (char c: s.toCharArray()) {
if (Character.isDigit(c)) {
occurrences[ c - '0' ]++;
}
}
}
public static void main(String[] args) {
for (int i=1; i<=100; i++) {
String s = String.valueOf(i);
System.out.println("checking "+s);
checkOccurrences(s);
}
System.out.println(Arrays.toString(occurrences));
}
}
and it prints
checking 1
checking 2
checking 3
...
checking 99
checking 100
[11, 21, 20, 20, 20, 20, 20, 20, 20, 20]
In case you or future readers want to see a stream approach, which I doubt, here's what I did just for fun: Stream over the range [1 - 100], convert and map to String, split each String at each charachter such that, for example "42" becomes a stream of "4" and "2", collect to map using digit as key and count of occurrence as value and finally print.
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
// ...
public static void main(String[] args) {
IntStream.rangeClosed(1, 100)
.mapToObj(String::valueOf)
.flatMap(s -> Arrays.stream(s.split("")))
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.forEach((k,v) -> System.out.printf("The digit %s showed up %d times between 1-100%n", k, v));
}
Instead of converting a number to string and then loop over its digits, you can also take the remainder by 10, i.e., the last digit, and then divide the number by 10 to "shift" it to the right.
For example, 45 % 10 == 5, and 45 / 10 == 4.
After you exit the while loop, your number is a single-digit number, so you have to count again that digit.
public class CountEachDigit {
public static void main(String[] args) {
int[] digits_count = new int[10];
int min = 1;
int max = 100;
for (int i = min; i <= max; ++i) {
int number = i;
while (number > 9) {
int last_digit = number % 10;
digits_count[last_digit] += 1;
number /= 10;
}
digits_count[number] += 1;
}
for (int i = 0; i < 10; i++) {
int count = digits_count[i];
System.out.println("Digit " + i + " appears " + count + " times in range [" + min + ", " + max + "]");
}
}
}
Using strings:
for (int i = 1; i <= 100; i++) {
String num = String.valueOf(i);
for(int j=0;j<num.length();j++){
//substracting 0 to get the integer value
counts[num.charAt(j)-'0']++;
}
}
for (int i = 0; i < 10; i++) {
System.out.println("The digit " + i + " showed up " + counts[i] + " times between 1-100.");
}
You can do it using by streaming and collecting in a map.
allocate a map to hold the counts
stream the values from 1 to 100 inclusive
within mapMulti
get the last digit by using the remainder % operator
accept the digit and place on the stream
expose the next digit by dividing by 10
Now collect the digits in the map, creating a frequency count as they occur. Each digit will the the key and the value will be the count.
Map<Integer, Integer> counts = IntStream.rangeClosed(1, 100)
.mapMulti((val, consumer) -> {
while (val > 0) {
consumer.accept(val % 10);
val /= 10;
}
}).boxed()
.collect(Collectors.toMap(i -> i, i -> 1, Integer::sum));
counts.forEach((digit, count) -> System.out
.println(digit + " occurs " + count + " times."));
prints
0 occurs 11 times.
1 occurs 21 times.
2 occurs 20 times.
3 occurs 20 times.
4 occurs 20 times.
5 occurs 20 times.
6 occurs 20 times.
7 occurs 20 times.
8 occurs 20 times.
9 occurs 20 times.

I'm trying to write a code in java where I'm supposed to use a function than can show even or odd digits in a specific number

i have 2 phone numbers
String telUDM = "5143436111",
telJean = "4501897654";
what im expecting my function to print
i have 7 odd digits in telUDM
i have 5 even digits in telJean
what i tried in my function is this function i took from someone's answer but i didnt work
final int EVEN = 0;
final int ODD = 1;
static int count(int n, int remainder)
{
int count = 0;
while (n > 0)
{
int rem = n % 10;
if (rem % 2 == remainder)
count++;
n = n / 10;
}
return count;
}
public static void main(String[] args) {
System.out.println("Even Count: " + count(12233, EVEN));
System.out.println("Odd Count: " + count(12233, ODD));
}
im expecting to write in my main :
function name(telUDM , "even");
function name(telJean , "odd");
and to get this as result
i have 7 odd digits in telUDM
i have 5 even digits in telJean
Here we go with your code:
public class Test {
static final int EVEN = 0; // this fields must be static if you are calling them in static function
static final int ODD = 1;
static int count(long n, int remainder) { // change the parameter type to long that has bigger range
int count = 0;
while (n > 0) {
long rem = n % 10;
if (rem % 2 == remainder)
count++;
n = n / 10;
}
return count;
}
public static void main(String[] args) {
long telUDM = 5143436111L; // cannot be integer, value is higher than max int (> ~2 100 000 000)
long telJean = 4501897654L;
System.out.println("Even Count: " + count(telJean, EVEN));
System.out.println("Odd Count: " + count(telUDM, ODD));
}
}
Actually it should work but phone number is too big for integer range. Here you should use string insteed (phone numbers may be much more longer). In the case when you are using string you have to iterate over all elements and parse the digit value (you can see example). But lets talk more about your code.
You cannot use non static variables in static context (static methods)
Syntax like function .... is non valid java syntax and it will not work here, you should learn something bout java basics. Anyway you cannot provide String values to methods that expect numerics like: int/long.
This should work that as you expect:
public class Test {
public static void main(String[] args) {
String telUDM = "5143436111";
String telJean = "4501897654";
System.out.println("I have " + countOdd(telUDM) + " odd digits in telUDM");
System.out.println("I have " + countEven(telJean) + " even digits in telJean");
}
private static long countEven(String string) {
return string.chars().map(Character::getNumericValue).filter(Test::isEven).count();
}
private static long countOdd(String string) {
return string.chars().map(Character::getNumericValue).filter(Test::isOdd).count();
}
private static boolean isEven(int number) {
return number % 2 == 0;
}
private static boolean isOdd(int number) {
return number % 2 == 1;
}
}
The output of this code is:
I have 7 odd digits in telUDM
I have 5 even digits in telJean

Java - thread priorities (example from Thinking in Java)

I read now chapter about concurrency from Thinking in Java and I try to reproduce example from this book in my computer and I got very different results.
I do example from subchapter Priorities:
public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d;
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
#Override
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
#Override
public void run() {
Thread.currentThread().setPriority(priority);
while (true) {
for (int i = 1; i < 100000; i++) {
d += (Math.PI + Math.E) / (double) i;
if (i % 1000 == 0) {
Thread.yield();
}
System.out.println(this);
if (--countDown == 0) return;
}
}
}
public static void main(String[] args) {
final ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executorService.execute(new SimplePriorities(Thread.MIN_PRIORITY));
}
executorService.execute(new SimplePriorities(Thread.MAX_PRIORITY));
executorService.shutdown();
}
}
and in result I got:
Thread[pool-1-thread-1,1,main]: 5
Thread[pool-1-thread-4,1,main]: 5
Thread[pool-1-thread-4,1,main]: 4
Thread[pool-1-thread-4,1,main]: 3
Thread[pool-1-thread-4,1,main]: 2
Thread[pool-1-thread-4,1,main]: 1
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-6,10,main]: 4
Thread[pool-1-thread-6,10,main]: 3
Thread[pool-1-thread-6,10,main]: 2
Thread[pool-1-thread-6,10,main]: 1
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-5,1,main]: 5
Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-1,1,main]: 4
Thread[pool-1-thread-2,1,main]: 4
Thread[pool-1-thread-5,1,main]: 4
Thread[pool-1-thread-3,1,main]: 4
Thread[pool-1-thread-5,1,main]: 3
Thread[pool-1-thread-2,1,main]: 3
Thread[pool-1-thread-1,1,main]: 3
Thread[pool-1-thread-2,1,main]: 2
Thread[pool-1-thread-5,1,main]: 2
Thread[pool-1-thread-3,1,main]: 3
Thread[pool-1-thread-5,1,main]: 1
Thread[pool-1-thread-2,1,main]: 1
Thread[pool-1-thread-1,1,main]: 2
Thread[pool-1-thread-3,1,main]: 2
Thread[pool-1-thread-1,1,main]: 1
Thread[pool-1-thread-3,1,main]: 1
The author wrote that the last result has the highest priority, but when I run this code in my system I get different priorities and on average often low priorities than high, like above.
I use Ubuntu 16.04.

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.

Generating a random number between multiple ranges

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.

Categories

Resources