Find the N-monotonic number - java

I'm working on the assignment, which requires to find the N-th monotonic number (a number which digits form increasing or decreasing sequence).
Find the N-th monotonic number starting from zero 0 (i.e. index N start from zero and zero is the first monotonic number).
A number considered to be monotonic if it has all the digits either in
increasing or decreasing order.
Note: all numbers which consist of only one or two digits are considered to be monotonic.
Example:
Monotonic numbers: 1234, 4321, 13579
Non-monotonic numbers: 1432, 89461
You're not allowed to use an Array or a String.
I understand how to iterate over the digits of a number, but I'm not getting how to combine this with a check if the number is monotonic.
This is the code I have so far:
static int functionForCountNumbers(){
int n = ReadNumber();
int min;
int count = 0;
while (n > 0){
min = n % 10;
n /= 10;
count += 1;
}
return count;
}

This problem can be split into two parts, which you can address separately:
Generating candidate numbers.
Checking if the number is a monotonic number.
To accomplish the first part, declare the counter variable representing the index of a monotonic number as you did, and the variable holding a value of a candidate number.
Then in the loop you need to check each candidate number, and if it's a monotonic number, increment the count.
Since according to problem description, all numbers containing one or two digits are considered to be monotonic we can treat all n<100 separately, and start checking numbers starting from 123 which is the fist monotonic three-digit number.
Note: for simplicity, I will stick with the definition of a monotonic number as either strictly increasing or decreasing. I advise you consult with your professor, because the requirement of considering all two-digit numbers, including the numbers containing repeated digits like 33 and 99 might imply that a monotonic number can contain equal digits. So, even if my definition is not precise, it would give you the understanding of the algorithm.
That's how the first part might be implemented:
public static int functionForCountNumbers() {
int n = readNumber();
if (n < 0) throw new IllegalArgumentException("number shouldn't be negative");
// or allow the user to retry
// while (n < 0) {
// System.out.println("number shouldn't be negative");
// n = readNumber();
// }
if (n < 100) return n;
int count = 99;
int candidate = 123; // the first monotonic number, which should correspond to n = 100
while (count < n) {
if (isMonotonic(candidate)) count++;
candidate++;
}
return candidate;
}
To find out whether a candidate number is a monotonic or not you can compare the first subsequent pair of digits and store the result into a variable. Then continue comparing the rest digits in the loop, tracking the previous digit and result of the previous comparison.
If no inconsistencies were encountered while comparing adjacent digits, the number has been proved to be monotonic.
That's how this logic can look like:
public static boolean isMonotonic(int num) {
if (num < 100) return true;
int prev = num % 10;
num /= 10;
boolean isIncreasing = isIncreasing(num % 10, prev);
while (num > 0) {
if (isIncreasing != isIncreasing(num % 10, prev)) {
return false;
}
prev = num % 10;
num /= 10;
}
return true;
}
public static boolean isIncreasing(int left, int right) {
return left <= right;
}

Remember if the first pair of digits is in increasing or in decreasing order.
Remember the last digit.
For every new digit check if it form the same order with the last digit.
Assign current digit to last digit

Related

Counting integer digits

I'm trying to count the digits of an integer with java, it supposed to give 4 but instead I get 1 .
I don't know if I did something wrong, if someone could help.
Here's the code :
public static void main(String[] args) {
int n = 4781, i = 0;
while (n != 0) {
n %= 10;
n /= 10;
i++;
}
System.out.println(i);
}
The n %= 10 is unnecessary and in fact the source of the problem here. If you remove it, the code will work.
Usually when you do these kinds of "do something for each digit" you use % 10 to find the current digit a little bit like this:
int digit = n % 10;
System.out.println("The current digit is " + digit);
But in your case you don't actually care what the digits are, you only care how many there are, so there's no need to do % 10 at all.
And the way you did it you overwrote n (which is supposed to hold the current state of the number) with the current digit and then divided by 10. So no matter what the first digit is, this will never return a number bigger than 1.

How to find the 5th perfect number (which is 33550336)? The problem is taking forever to run

I am trying to write a Java method that checks whether a number is a perfect number or not.
A perfect number is a number that is equal to the sum of all its divisor (excluding itself).
For example, 6 is a perfect number because 1+2+3=6. Then, I have to write a Java program to use the method to display the first 5 perfect numbers.
I have no problem with this EXCEPT that it is taking forever to get the 5th perfect number which is 33550336.
I am aware that this is because of the for loop in my isPerfectNumber() method. However, I am very new to coding and I do not know how to come up with a better code.
public class Labreport2q1 {
public static void main(String[] args) {
//Display the 5 first perfect numbers
int counter = 0,
i = 0;
while (counter != 5) {
i++;
isPerfectNumber(i);
if (isPerfectNumber(i)) {
counter++;
System.out.println(i + " ");
}
}
}
public static boolean isPerfectNumber(int a) {
int divisor = 0;
int sum = 0;
for (int i = 1; i < a; i++) {
if (a % i == 0) {
divisor = i;
sum += divisor;
}
}
return sum == a;
}
}
This is the output that is missing the 5th perfect number
Let's check the properties of a perfect number. This Math Overflow question tells us two very interesting things:
A perfect number is never a perfect square.
A perfect number is of the form (2k-1)×(2k-1).
The 2nd point is very interesting because it reduces our search field to barely nothing. An int in Java is 32 bits. And here we see a direct correlation between powers and bit positions. Thanks to this, instead of making millions and millions of calls to isPerfectNumber, we will be making less than 32 to find the 5th perfect number.
So we can already change the search field, that's your main loop.
int count = 0;
for (int k = 1; count < 5; k++) {
// Compute candidates based on the formula.
int candidate = (1L << (k - 1)) * ((1L << k) - 1);
// Only test candidates, not all the numbers.
if (isPerfectNumber(candidate)) {
count++;
System.out.println(candidate);
}
}
This here is our big win. No other optimization will beat this: why test for 33 million numbers, when you can test less than 100?
But even though we have a tremendous improvement, your application as a whole can still be improved, namely your method isPerfectNumber(int).
Currently, you are still testing way too many numbers. A perfect number is the sum of all proper divisors. So if d divides n, n/d also divides n. And you can add both divisors at once. But the beauty is that you can stop at sqrt(n), because sqrt(n)*sqrt(n) = n, mathematically speaking. So instead of testing n divisors, you will only test sqrt(n) divisors.
Also, this means that you have to start thinking about corner cases. The corner cases are 1 and sqrt(n):
1 is a corner case because you if you divide n by 1, you get n but you don't add n to check if n is a perfect number. You only add 1. So we'll probably start our sum with 1 just to avoid too many ifs.
sqrt(n) is a corner case because we'd have to check whether sqrt(n) is an integer or not and it's tedious. BUT the Math Overflow question I referenced says that no perfect number is a perfect square, so that eases our loop condition.
Then, if at some point sum becomes greater than n, we can stop. The sum of proper divisors being greater than n indicates that n is abundant, and therefore not perfect. It's a small improvement, but a lot of candidates are actually abundant. So you'll probably save a few cycles if you keep it.
Finally, we have to take care of a slight issue: the number 1 as candidate. 1 is the first candidate, and will pass all our tests, so we have to make a special case for it. We'll add that test at the start of the method.
We can now write the method as follow:
static boolean isPerfectNumber(int n) {
// 1 would pass the rest because it has everything of a perfect number
// except that its only divisor is itself, and we need at least 2 divisors.
if (n < 2) return false;
// divisor 1 is such a corner case that it's very easy to handle:
// just start the sum with it already.
int sum = 1;
// We can stop the divisors at sqrt(n), but this is floored.
int sqrt = (int)Math.sqrt(n);
// A perfect number is never a square.
// It's useful to make this test here if we take the function
// without the context of the sparse candidates, because we
// might get some weird results if this method is simply
// copy-pasted and tested on all numbers.
// This condition can be removed in the final program because we
// know that no numbers of the form indicated above is a square.
if (sqrt * sqrt == n) {
return false;
}
// Since sqrt is floored, some values can still be interesting.
// For instance if you take n = 6, floor(sqrt(n)) = 2, and
// 2 is a proper divisor of 6, so we must keep it, we do it by
// using the <= operator.
// Also, sqrt * sqrt != n, so we can safely loop to sqrt
for (int div = 2; div <= sqrt; div++) {
if (n % div == 0) {
// Add both the divisor and n / divisor.
sum += div + n / div;
// Early fail if the number is abundant.
if (sum > n) return false;
}
}
return n == sum;
}
These are such optimizations that you can even find the 7th perfect number under a second, on the condition that you adapt the code for longs instead of ints. And you could still find the 8th within 30 seconds.
So here's that program (test it online). I removed the comments as the explanations are here above.
public class Main {
public static void main(String[] args) {
int count = 0;
for (int k = 1; count < 8; k++) {
long candidate = (1L << (k - 1)) * ((1L << k) - 1);
if (isPerfectNumber(candidate)) {
count++;
System.out.println(candidate);
}
}
}
static boolean isPerfectNumber(long n) {
if (n < 2) return false;
long sum = 1;
long sqrt = (long)Math.sqrt(n);
for (long div = 2; div <= sqrt; div++) {
if (n % div == 0) {
sum += div + n / div;
if (sum > n) return false;
}
}
return n == sum;
}
}
The result of the above program is the list of the first 8 perfect numbers:
6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
You can find further optimization, notably in the search if you check whether 2k-1 is prime or not as Eran says in their answer, but given that we have less than 100 candidates for longs, I don't find it useful to potentially gain a few milliseconds because computing primes can also be expensive in this program. If you want to check for bigger perfect primes, it makes sense, but here? No: it adds complexity and I tried to keep these optimization rather simple and straight to the point.
There are some heuristics to break early from the loops, but finding the 5th perfect number still took me several minutes (I tried similar heuristics to those suggested in the other answers).
However, you can rely on Euler's proof that all even perfect numbers (and it is still unknown if there are any odd perfect numbers) are of the form:
2i-1(2i-1)
where both i and 2i-1 must be prime.
Therefore, you can write the following loop to find the first 5 perfect numbers very quickly:
int counter = 0,
i = 0;
while (counter != 5) {
i++;
if (isPrime (i)) {
if (isPrime ((int) (Math.pow (2, i) - 1))) {
System.out.println ((int) (Math.pow (2, i -1) * (Math.pow (2, i) - 1)));
counter++;
}
}
}
Output:
6
28
496
8128
33550336
You can read more about it here.
If you switch from int to long, you can use this loop to find the first 7 perfect numbers very quickly:
6
28
496
8128
33550336
8589869056
137438691328
The isPrime method I'm using is:
public static boolean isPrime (int a)
{
if (a == 1)
return false;
else if (a < 3)
return true;
else {
for (int i = 2; i * i <= a; i++) {
if (a % i == 0)
return false;
}
}
return true;
}

Java- working with an integer

Write a static method called digitsInARow that takes an integer n as a parameter and that returns the highest number of digits that appear in a row in the base-10 representation of n. For many numbers the answer will be 1 because they don't have adjacent digits that match. But for a number like 3555585, the answer is 4 because there are four occurrences of the digit 5 that appear in a row. You are NOT allowed to use a String to solve this problem. You may assume that the value passed to the method is greater than or equal to 0.
public static int digitsInARow(int n) {
if (n / 10 == 0) {
return 1;
}
int count = 0;
int count1 = 0;
while (n > 0) {
int digit = n % 10;
int a = n / 10;
if (digit == a % 10) {
count++;
} else {
count1 = Math.max(count1, count);
count = 0;
}
n = n / 10;
}
return Math.max(count, count1);
}
I know the if statement is messed up. I am trying to figure out a way to compare consecutive digits WITHOUT using Integer class or String class. Any suggestions?
The problem with your code is that count keeps track of the current count, not of the highest count. You need to add a variable that tracks the highest count as well, and update it each time you process a digit, before resetting count back to zero.
Don't forget to update the highest count when you exit the loop, in case then-current count is greater than the previously found max.

How to improve: Given two integers, return the number of digits that they share [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I received this question during an interview, the question is
Given two integers, return the number of digits that they share.
For example 129 and 431 would return 1 - as they both share the digit 1, but no other digit. 95 and 780 would return 0, since none of the integers overlap.
My thoughts are just iterate through the digits, store them into a hashtable and check .containsKey.
My Java solution:
public int commonDigits(int x, int y) {
int count = 0;
HashTable<Integer, String> ht = new HashTable<Integer, String>();
while (x != 0) {
ht.put(x % 10, "x");
x /= 10;
}
while (y != 0) {
if ((ht.containsKey(y % 10)) {
count++;
}
y /= 10;
}
return count;
}
But this takes up O(n) space and O(n + m) time, anyways I can improve this?
Why not just use some simple bit fiddling? 
public int commonDigits(int x, int y) {
int dX = 0;
while (x != 0) {
dX |= 1 << (x % 10);
x /= 10;
}
int count = 0;
while (y != 0) {
int mask = 1 << (y % 10);
if ((dX & mask) != 0) {
count ++;
dX &= ~mask;
}
y /= 10;
}
return count;
}
This just sets a corresponding bit in dX for each digit in x. In the second loop, for each digit in x, the code checks whether it has an entry in dX. If so, it's counted and the bit is reset to avoid double-counting (note that this is missing in your code, consider 123 and 141). Obviously doesn't use any additional storage (dX and count could just be bytes if that matters).
Note that you don't need a HashTable in your solution -- you could just use a HasSet or a BitSet..
Your code translated to using a BitSet with the double-counting problem fixed:
public int commonDigits(int x, int y) {
int count = 0;
BitSet ht = new BitSet();
while (x != 0) {
ht.set(x % 10, true);
x /= 10;
}
while (y != 0) {
if ((ht.get(y % 10)) {
count++;
ht.set(y % 10, false);
}
y /= 10;
}
return count;
}
Both snippets work exactly the same way, the latter just has some more overhead for the BitSet (and embedded array) instance.
This article shows why a BitSet is better than a boolean array in the general case: http://chrononsystems.com/blog/hidden-evils-of-javas-byte-array-byte
Edit:
If counting the same digit multiple times is actually desired (was not clear from the examples in the question), use an int array to store the counts:
public int commonDigits(int x, int y) {
int count = 0;
int[] digits = new int[10];
while (x != 0) {
digits[x % 10]++;
x /= 10;
}
while (y != 0) {
if (digits[x % 10] > 0) {
count++;
digits[x % 10]--;
}
y /= 10;
}
return count;
}
This is your solution with the minimum storage (an array of 10 bytes instead of a hash table):
public int commonDigits(int x, int y) {
int count = 0;
byte[] digits=new byte[10];
while (x != 0) {
digits[x%10] ++;
x /= 10;
}
while (y != 0) {
if (digits[y % 10] > 0) {
count++;
digits[y % 10] --;
}
y /= 10;
}
return count;
}
The solution is optimum in running time O(n+m), where n is the number of digits in x and m is the number of digits in y. You cannot do less than enumerating the digits of x then the digits of y.
Since there are only 10 possible digits, why not just store an integer array? Indexed from 0-9, one for each digit. Loop through each digit and increment the corresponding array element. The space complexity of this depends on what you define to be "constant" - this will always take up 10 units of space (would be 10 bytes in C/C++, not sure how JVM does it)
By conservation of information, you have to loop through each digit of both numbers (they are independent so you can't just infer one from the other), so your time complexity will remain at O(m + n). Also I think by O(n) you really mean O(log n), as this is the number of digits in any representation of the number.
There is at maximum 10 digits that can be shared. This means you don't need a complicated data structure like Hashtable, an array or bitmask will suffice!
You would simply iterate over the first number, and every digit you hit is marked as "true" (in your bitmask or array). You can even short-circuit this and return early if you have found every digit once (which is easy and cheap with a bitmask). Then go over the second number. Every time you hit a digit that is also marked as true, increase the counter. If the bitmask contains every digit, short-circuit by returning the length of the number (its highest exponent), otherwise return the counter at the end.
This doesn't reduce O-complexity, but it reduces memory footprint and adds some short-circuits for large numbers.
For example, if the first number is 1234567890, then it will always share as many digits with the second number as the second number has decimal places.
A hash table is overkill, just use an array of ten flags (whether you pack them in a single integer with bitwise operations or keep independent variables is up to you).
Scan the first integer and raise the relevant flag for every digit.
Scan the second integer and reset the relevant flag for every digit.
Return the number of true resets (from 1 to 0).
Update: to deal with duplicates, the flags need to be replaced by counters.
If both numbers have M digits, they must all be looked at so that the time complexity is at certainly Ω(M).
The case of the space complexity is less clear. All solutions presented here are O(N), where N is the number of possible digits (10 in the decimal base). But O(1) space is possible: take every digit of the first number in turn, check if it is the first such digit in the first number (to avoid counting duplicates), then check if it exists in the second number. This is an O(M²)-time process, but O(1)-space only.
Update: to deal with duplicates, every time you process a digit, count the number of identical predecessors in the first number; when looking for a match in the second number, also match the number of predecessors.
So one may wonder if a O(M)-time, O(1)-space solution is possible.
My solution is O(M+N)-time, O(N)-space. The +N in the time complexity is only required for the initialization of all N flags. If you accept not to count the initialization, you can write the algorithm in such a way that it clears all the flags it has set (so that the algorithm can be played again) and this yields a O(M)-time, O(N)-space solution.
There is an easy O(M Log M)-time, O(M)-space solution, by sorting the two strings of digits and counting the identical digits in a merge-like step. Can be of use if M is very small compared to N.
Your solution doesn't account for duplicates.
# 11, 211 -> 2
You're right to use a hash, it's faster than an array. Gonna do this in python because it's faster to type...
# Returns an array containing the shared digits
def getShared(num1, num2):
shared = []
digits1 = getDigits(num1)
digits2 = getDigits(num2)
for digit in digits1:
if digit in digits2:
while digits2[digit] > 1 and digits1[digit] > 1:
digits2[digit] = digits2[digit] - 1
digits1[digit] = digits1[digit] - 1
shared += [digit]
del digits2[digit]
del digits1[digit]
return shared
# Given an integer, returns a dictionary with the keys as the digits,
# and the value as the number of times the digit appears
def getDigits(num)
dict = {}
while num > 0:
newDigit = num % 10
if newDigit not in dict:
dict[newDigit] = 1
else:
dict[newDigit] = dict[newDigit] + 1
return dict

Russian Doll Primes

This question was asked in an interview (about prime numbers)
Russian Doll Primes
They are more commonly known as Truncatable Primes.
I found this code on wiki
public static void main(String[] args){
final int MAX = 1000000;
//Sieve of Eratosthenes (using BitSet only for odd numbers)
BitSet primeList = new BitSet(MAX>>1);
primeList.set(0,primeList.size(),true);
int sqroot = (int) Math.sqrt(MAX);
primeList.clear(0);
for(int num = 3; num <= sqroot; num+=2)
{
if( primeList.get(num >> 1) )
{
int inc = num << 1;
for(int factor = num * num; factor < MAX; factor += inc)
{
//if( ((factor) & 1) == 1)
//{
primeList.clear(factor >> 1);
//}
}
}
}
//Find Largest Truncatable Prime. (so we start from 1000000 - 1
int rightTrunc = -1, leftTrunc = -1;
for(int prime = (MAX - 1) | 1; prime >= 3; prime -= 2)
{
if(primeList.get(prime>>1))
{
//Already found Right Truncatable Prime?
if(rightTrunc == -1)
{
int right = prime;
while(right > 0 && primeList.get(right >> 1)) right /= 10;
if(right == 0) rightTrunc = prime;
}
//Already found Left Truncatable Prime?
if(leftTrunc == -1 )
{
//Left Truncation
String left = Integer.toString(prime);
if(!left.contains("0"))
{
while( left.length() > 0 ){
int iLeft = Integer.parseInt(left);
if(!primeList.get( iLeft >> 1)) break;
left = left.substring(1);
}
if(left.length() == 0) leftTrunc = prime;
}
}
if(leftTrunc != -1 && rightTrunc != -1) //Found both? then Stop loop
{
break;
}
}
}
System.out.println("Left Truncatable : " + leftTrunc);
System.out.println("Right Truncatable : " + rightTrunc);
}
This gives the output:
Left Truncatable : 998443
Right Truncatable : 796339
But I am not able to solve this particular Russian doll prime number problem like if you have a prime number and you remove either left or right digit of this prime number then if that resulting number is prime number or not?
I am new to this so please pardon any mistake.
Let's start from the beginning:
According to the link you supplied with your question:
"Russian Doll Primes are
prime numbers whose right digit can be repeatedly removed, and are
still prime."
I will assume that you have a function boolean isPrime(int) to find out if a number is prime.
Googling, we will find from Wikipedia that the number of right-truncatable prime numbers up to 73,939,133 is 83, which makes brute-force a viable option; but a few optimization techniques can be employed here:
Since we right-truncate, we can safely eliminate even numbers (since any even number won't be prime, and so any number generated upon it will never be a russian doll prime).
Since any number that starts with 5 is divisible by 5, then based on the same rule I mentioned in the previous point, we can eliminate 5.
That leaves us with numbers that contain 1, 3, 7, and 9.
Now if we wanted to generate all possible combinations of these 4 numbers that do not exceed the maximum you mentioned (1,000,000), it would take only 4,096 iterations.
The downside of this technique is that we now have 4,096 numbers that contain possible non-prime numbers, or prime numbers that are formed from non-prime numbers and hence are not russian doll primes. We can eliminate these numbers by looping through them and checking; or better yet, we can examine russian doll primes more closely.
Upon examining the rule I quoted from your link above, we find that a russian doll primes are prime numbers whose right digit can be repeatedly removed, and are still prime (and hence are still russian doll prime, given the word repeatedly)!
That means we can work from the smallest single-digit russian doll primes, work our generation magic that we used above, and since any prime number that is formed from russian doll prime numbers is a russian doll prime number, we can eliminate non-primes early on, resulting in a clean list of russian doll prime numbers, while reducing the running time of such a program dramatically.
Take a look at the generation code below:
void russianDollPrimesGeneration(int x) {
x *= 10;
if (x * 10 >= 1000000) return;
int j;
for (int i=1; i<=9; i+=2) {
if (i == 5) continue;
j = x + i;
if (isPrime(j)) {
addToRussianDollPrimesList(j);
russianDollPrimesGeneration(j);
}
}
}
Provided that void addToRussianDollPrimesList(int x) is a function that adds x to a list that we previously preserved to store the russian doll prime numbers.
UPDATED NOTE
Note that you can put the call to void russianDollPrimesGeneration(int x) that we made inside the if condition inside the void addToRussianDollPrimesList(int x) function, because whenever we call the former function, we will always call the latter function with the same arguments. I'm separating them here to emphasize the recursive nature of the generation function.
Also note that you must run this function with the integer 0.
A final note is that there are a number of cases that the generation function void russianDollPrimesGeneration(int x) above won't count, even though they are Russian Doll Primes.
Remember when we omitted 2 and 5, because even numbers and numbers divided by 5 cannot be primes and so cannot be Russian Doll Primes? and consequently cannot form Russian Doll Primes? Well, that case does not apply to 2 and 5, because they are prime, and since they are single digits, therefore they are Russian Doll Primes, and are eligible to form Russian Doll Primes, if placed in the left-side, like 23 and 53.
So how to correct our code to include these special cases?
We can make a wrapper function that adds these two numbers and checks for Russian Doll Primes that can be formed using them (which will be the same generation function we are using above).
void generationWrapperFunction(int x) {
addToRussianDollPrimesList(2);
russianDollPrimesGeneration(2);
addToRussianDollPrimesList(5);
russianDollPrimesGeneration(5);
russianDollPrimesGeneration(0);
}
END UPDATED NOTE
This little function will produce a list of russian doll prime numbers, which can then be searched for the number we are looking for.
An alternative, yet I believe will be more time-consuming, is the following recursive function:
boolean isRussianDollPrime(int n) {
if (!isPrime(n)) return false;
if (n < 10) return true;
return isRussianDollPrime(n / 10);
}
This function can be modified to work with left-truncatable primes. The generation-based solution, however, will be much difficult to implement for left-truncatable primes.
Your problem is to use this code or to solve the problem ?
if to solve it you can generate primes using Sieve algorithm then check if the element is prime or not (if it was prime then check if element/10 is also prime)
Let's start with a simple assumption that we know how to write code to detect if a value is a prime. In a coding interview, they won't likely won't expect you to pull out "Sieve of Eratosthenes". You should start with simple code that handles the special cases of x<=1 (false) and x==2(true). Then check for an even number !(x % 2)(false). Then loop on i from 3..sqrt(x) (incrementing by +2 each time) to see if there's an odd number divisor for x.
boolean isPrime(long x)
{
// your code goes here
}
And once we have a function to tell us if a value is prime, we can easily build the function to detect if a value is a Russian Prime. Therefore we just need to loop on our value, each time check for prime, and then chop off the right hand side. And the easiest way to remove the right-most digit from a number is to simply divide it by 10.
boolean isRussianPrime(long x)
{
boolean result = isPrime(x);
while ((x != 0) && result)
{
// chop off the right digit of x
x = x / 10;
if (x != 0)
{
result = isPrime(x);
}
}
return result;
}
And that's really all there is to it.
package com.example.tests;
public class RussianDollPrimeNumber {
public static void main(String[] args) {
int x= 373;
int k;
int n =x;
for ( k= String.valueOf(x).length()-1;k>0;k--){
System.out.println(n);
if (isPrime(n)){
String m=String.valueOf(n).substring(0, k);
n=Integer.parseInt(m);
continue;
}else {
break;
}
}
if( k==0){
System.out.println("Number is Russianl Doll Number "+x);
}else {
System.out.println("Number is not Russianl Doll Number "+x);
}
}
private static boolean isPrime(int x) {
boolean check=true;
for (int i=2;i<x/2;i++){
if( (x%i)==0){
check=false;
}
}
return check;
}
}

Categories