why does my code not giving me reverse number accurately [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Java Code Example: i am facing issue when i insert 010 it shows only 1 instead of whole number and when i insert 200 it gave me reverse number only 2 while it should show me exact 002 how can i get exact number in reverse:
class Reverse{
public static void main(String args[]){
int remander,sum=0;
int number=454;
while(n>0) // loop here
{
remander=n%10; // Getting remainder
sum=(sum*10)+remander;
number=number/10;
}
System.out.println("Reverse"+sum);
}
}

It is clear that you are new to Java, and new to programming. Welcome to StackOverflow. I'm going to add some extra advice that I don't normally offer, to help you get better faster.
Don't reuse a variable for more than one thing. Use it for only one thing. That means that if a variable holds you input, don't overwrite it with intermediate values. Variables are (relatively) cheap, create another. You can practice this by marking your variables final which will prevent you from changing their values after assigned.
Use meaningful variable names. "r" is not a meaningful name. "remainder" is a meaningful name. This helps others immediately, and will help you later, when the program isn't fresh on your mind and you don't remember what "r" means.
Once you master not reusing variables, you will have a lot of variables. Look for variables that are "set once and read once" and try to rearrange your code to remove them completely. It will take some time to understand what I mean, but if you have heard of "refactoring" the idea is to remove the variable name because it isn't used twice (so it probably isn't a key part of your problem.
Now, applying these rules
final int number = 454;
// get the number digits, smallest to largest
int remainder = number;
int accumulator = 0;
while (remainder > 0) {
final int digit = remainder % 10;
accumulator = accumulator * 10 + digit;
remainder = remainder / 10;
}
final int reversed = accumulator;
note that digit is never used twice
final int number = 454;
// get the number digits, smallest to largest
int remainder = number;
int accumulator = 0;
while (remainder > 0) {
accumulator = accumulator * 10 + remainder % 10;
remainder = remainder / 10;
}
final int reversed = accumulator;
Note that all that "logic" could have a really good name put to it, so we'll create a "method"
public int reverse(int value) {
int remainder = value;
int accumulator = 0;
while (remainder > 0) {
accumulator = accumulator * 10 + remainder % 10;
remainder = remainder / 10;
}
return accumulator;
}
which cleans up the other code to
final int number = 454;
final int reversed = reverse(number);
or maybe even
final int reversed = reverse(454);

Related

How can I find minimum element of an integer in Java? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Imagine we are getting input from user as integer. I want my code to return minimum and maximum numbers in this integer value. For example, if user enters 56389, the code should display
Minimum number: 3
Maximum number: 9
If user enters single digit integer, let's say 7, the output should be:
Minimum number: 7
Maximum number: 7
I am trying to declare input as String instead of integer and compare all elements of the String with charAt(i) method. However, I cannot get the result.
I would be glad if you can help me!
This should work:
int number = Integer.valueOf(input);
int largest = 0;
int smallest = 9;
while(number != 0)
{
int rem = number % 10;
largest = Math.max(rem, largest);
smallest = Math.min(rem, smallest);
number = number / 10;
}
System.out.println(largest + " " + smallest);
You can parse the string input using wrapper classes util methods. The rest of the code you can refer below.
int[] getLargestAndSmallestDigits(String in){
int n = Integer.valueOf(in);
if (n==0) {
return new int[]{0,0};
}
int[] ans = {0,9};
while(n != 0)
{
int r = n % 10;
ans[0] = Math.min(r, ans[0]);
ans[1] = Math.max(r, ans[0]);
n = n / 10;
}
return ans;
}
If you choose to work with the number representing it as a string, that means you'll have to be using the charAt(int index) method to retrieve an individual character from the string.
Then, to convert any number character (that is, '0', '1', '2' ... '9') to the number itself, subtract character '0' from it ('0' will be explicitly converted to int (ASCII code) at runtime), and you'll get the number itself in int representation.
public static void main(String[] args) {
char charNine = '9';
int intNine = charNine - '0';
System.out.println(intNine);
}
The output is 9.

I need to print the 215th Lucas Numbers using an efficient algorithm. Using recursion takes way too long.

The purpose of this class is to calculate the nth number of the Lucas Sequence. I am using data type long because the problems wants me to print the 215th number. The result of the 215th number in the Lucas Sequence is: 855741617674166096212819925691459689505708239. The problem I am getting is that at some points, the result is negative. I do not understand why I am getting a negative number when the calculation is always adding positive numbers. I also have two methods, since the question was to create an efficient algorithm. One of the methods uses recursion but the efficiency is O(2^n) and that is of no use to me when trying to get the 215th number. The other method is using a for loop, which the efficiency is significantly better. If someone can please help me find where the error is, I am not sure if it has anything to do with the data type or if it is something else.
Note: When trying to get the 91st number I get a negative number and when trying to get the 215th number I also get a negative number.
import java.util.Scanner;
public class Problem_3
{
static long lucasNum;
static long firstBefore;
static long secondBefore;
static void findLucasNumber(long n)
{
if(n == 0)
{
lucasNum = 2;
}
if(n == 1)
{
lucasNum = 1;
}
if(n > 1)
{
firstBefore = 1;
secondBefore = 2;
for(int i = 1; i < n; i++)
{
lucasNum = firstBefore + secondBefore;
secondBefore = firstBefore;
firstBefore = lucasNum;
}
}
}
static long recursiveLucasNumber(int n)
{
if(n == 0)
{
return 2;
}
if(n == 1)
{
return 1;
}
return recursiveLucasNumber(n - 1) + recursiveLucasNumber(n - 2);
}
public static void main(String[] args)
{
System.out.println("Which number would you like to know from "
+ "the Lucas Sequence?");
Scanner scan = new Scanner(System.in);
long num = scan.nextInt();
findLucasNumber(num);
System.out.println(lucasNum);
//System.out.println(recursiveLucasNumber(num));
}
}
Two observations:
The answer you are expecting (855741617674166096212819925691459689505708239) is way larger than you can represent using a long. So (obviously) if you attempt to calculate it using long arithmetic you are going to get integer overflow ... and a garbage answer.
Note: this observation applies for any algorithm in which you use a Java integer primitive value to represent the Lucas numbers. You would run into the same errors with recursion ... eventually.
Solution: use BigInteger.
You have implemented iterative and pure recursion approaches. There is a third approach: recursion with memoization. If you apply memorization correctly to the recursive solution, you can calculate LN in O(N) arithmetical operations.
Java data type long can contain only 64-bit numbers in range -9223372036854775808 .. 9223372036854775807. Negative numbers arise due to overflow.
Seems you need BigInteger class for arbitrary-precision integer numbers
I wasn't aware of the lucas numbers before this thread, but from wikipedia it looks like they are related to the fibonacci sequence with (n = nth number, F = fibonacci, L = lucas):
Ln = F_(n-1) + F_(n+1)
Thus, if your algorithm is too slow, you could use the closed form fibonacci and than compute the lucas number from it, alternative you could also use the closed form given in the wikipedia article directly (see https://en.wikipedia.org/wiki/Lucas_number).
Example code:
public static void main(String[] args) {
long n = 4;
double fibo = computeFibo(n);
double fiboAfter = computeFibo(n + 1);
double fiboBefore = computeFibo(n - 1);
System.out.println("fibonacci n:" + Math.round(fibo));
System.out.println("fibonacci: n+1:" + Math.round(fiboAfter));
System.out.println("fibonacci: n-1:" + Math.round(fiboBefore));
System.out.println("lucas:" + (Math.round(fiboAfter) + Math.round(fiboBefore)));
}
private static double computeFibo(long n) {
double phi = (1 + Math.sqrt(5)) / 2.0;
double psi = -1.0 / phi;
return (Math.pow(phi, n) - Math.pow(psi, n)) / Math.sqrt(5);
}
To work around the long size limit you could use java BigDecimal (https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html). This is needed earlier in this approach as the powers in the formula will grow very quickly.

Possible multiplications of k distinct factors with largest possible factor n

Let M(n,k) be the sum of all possible multiplications of k distinct factors with largest possible factor n, where order is irrelevant.
For example, M(5,3) = 225 , because:
1*2*3 = 6
1*2*4 = 8
1*2*5 = 10
1*3*4 = 12
1*3*5 = 15
1*4*5 = 20
2*3*4 = 24
2*3*5 = 30
2*4*5 = 40
3*4*5 = 60
6+8+10+12+15+20+24+30+40+60 = 225.
One can easily notice that there are C(n,k) such multiplications, corresponding to the number of ways one can pick k objects out of n possible objects. In the example above, C(5,3) = 10 and there really are 10 such multiplications, stated above.
The question can also be visualized as possible n-sized sets containing exactly k 0's, where each cell that does not contain 0 inside it, has the value of its index+1 inside it. For example, one possible such set is {0,2,3,0,5}. From here on, one needs to multiply the values in the set that are different than 0.
My approach is a recursive algorithm. Similiarly to the above definition of
M(n,k), I define M(n,j,k) to be the sum of all possible multiplications of exactly k distinct factors with largest possible factor n, AND SMALLEST possible factor j. Hence, my approach would yield the desired value if ran on
M(n,1,k). So I start my recursion on M(n,1,k), with the following code, written in Java:
public static long M (long n, long j, long k)
{
if (k==1)
return usefulFunctions.sum(j, n);
for (long i=j;i<=n-k+1+1;i++)
return i*M(n,i+1,k-1);
}
Explanation to the code:
Starting with, for example, n=5 , j=1, k=3, the algorithm will continue to run as long as we need more factors, (k>=1), and it is made sure to run only distinct factors thanks to the for loop, which increases the minimal possible value j as more factors are added. The loop runs and decreases the number of needed factors as they are 'added', which is achieved through applying
M(n,j+1,k-1). The j+1 assures that the factors will be distinct because the minimal value of the factor increases, and k-1 symbolizes that we need 1 less factor to add.
The function 'sum(j,n)' returns the value of the sum of all numbers starting from j untill n, so sum(1,10)=55. This is done with a proper, elegant and simple mathematical formula, with no loops: sum(j,n) = (n+1)*n/2 - (i-1)*i/2
public static long sum (long i, long n)
{
final long s1 = n * (n + 1) / 2;
final long s2 = i * (i - 1) / 2;
return s1 - s2 ;
}
The reason to apply this sum when k=1, I will explain with an example:
Say we have started with 1*2. Now we need a third factor, which can be either of 3,4,5. Because all multiplications: 1*2*3, 1*2*4, 1*2*5 are valid, we can return 1*2*(3+4+5) = 1*2*sum(3,5) = 24.
Similiar logic explains the coefficient "i" next to the M(n,j+1,k-1).
say we have now the sole factor 2. Hence we need 2 more factors, so we multiply 2 by the next itterations, which should result in:
2*(3*sum(4,5) + 4*sum(5,5))
However, for a reason I can't explain yet, the code doesn't work. It returns wrong values and also has "return" issues that cause the function not to return anything, don't know why.
This is the reason i'm posting this question here, in hope someone will aid me. Either by fixing this code or sharing a code of his own. Explaining where I'm going wrong will be most appreciable.
Thanks a lot in advance, and sorry for this very long question,
Matan.
-----------------------EDIT------------------------
Below is my fixed code, which solves this question. Posting it incase one should ever need it :) Have fun !
public static long M(long n, long j, long k)
{
if (k == 0)
return 0;
if (k == 1)
return sum(j,n);
else
{
long summation = 0;
for (long i=j; i<=n; i++)
summation += i*M(n, i+1, k-1);
return summation;
}
}
I see that u got ur answer and i really like ur algorithm but i cant control myself posting a better algorithm . here is the idea
M(n,k) = coefficient of x^k in (1+x)(1+2*x)(1+3*x)...(1+n*x)
u can solve above expression by divide and conquer algorithm Click Here to find how to multiply above expression and get polynomial function in the form of ax^n + bx^(n-1)....+c
overall algorithm time complexity is O(n * log^2 n)
and best part of above algorithm is
in the attempt of finding solution for M(n,k) , u will find solution for M(n,x) where 1<=x<=n
i hope it will be useful to know :)
I am not sure about your algorithm, but you certainly messed up with your sum function. The problem you have is connected to type casting and division of integer numbers. Try something like this:
public static long sum (long i, long n)
{
final long s1 = n * (n + 1) / 2;
final long s2 = (i * i - i) / 2;
return s1 - s2 ;
}
You have a problem with your sum function : here is the correct formula:
public static long sum (long i, long n)
{
double s1 = n*(n+1)/2;
double s2 = i*(i-1)/2;
return (long)(s1-s2);
}
Here the full solution :
static int n = 5;
static long k = 3;
// no need to add n and k them inside your M function cause they are fixed.
public static long M (long start) // start = 1
{
if(start > k) // if start is superior to k : like your example going from 1..3 , then you return 0
return 0;
int res = 0; // res of your function
for(long i=start+1;i<n;i++){
res+=start*i*sum(i+1,n); // here you take for example 1*2*sum(3,5) + 1*3*sum(4,5).... ect
}
return res+M(start+1); // return res and start again from start+1 wich would be 2.
}
public static long sum (long i, long n)
{
if(i>n)
return 0;
double s1 = n*(n+1)/2;
double s2 = i*(i-1)/2;
return (long)(s1-s2);
}
public static void main(String[] args) {
System.out.println(M(1));
}
Hope it helped

Checking whether a number is in Fibonacci Sequence?

It was asked to find a way to check whether a number is in the Fibonacci Sequence or not.
The constraints are
1≤T≤10^5
1≤N≤10^10
where the T is the number of test cases,
and N is the given number, the Fibonacci candidate to be tested.
I wrote it the following using the fact a number is Fibonacci if and only if one or both of (5*n2 + 4) or (5*n2 – 4) is a perfect square :-
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0 ; i < n; i++){
int cand = sc.nextInt();
if(cand < 0){System.out.println("IsNotFibo"); return; }
int aTest =(5 * (cand *cand)) + 4;
int bTest = (5 * (cand *cand)) - 4;
int sqrt1 = (int)Math.sqrt(aTest);// Taking square root of aTest, taking into account only the integer part.
int sqrt2 = (int)Math.sqrt(bTest);// Taking square root of bTest, taking into account only the integer part.
if((sqrt1 * sqrt1 == aTest)||(sqrt2 * sqrt2 == bTest)){
System.out.println("IsFibo");
}else{
System.out.println("IsNotFibo");
}
}
}
}
But its not clearing all the test cases? What bug fixes I can do ?
A much simpler solution is based on the fact that there are only 49 Fibonacci numbers below 10^10.
Precompute them and store them in an array or hash table for existency checks.
The runtime complexity will be O(log N + T):
Set<Long> nums = new HashSet<>();
long a = 1, b = 2;
while (a <= 10000000000L) {
nums.add(a);
long c = a + b;
a = b;
b = c;
}
// then for each query, use nums.contains() to check for Fibonacci-ness
If you want to go down the perfect square route, you might want to use arbitrary-precision arithmetics:
// find ceil(sqrt(n)) in O(log n) steps
BigInteger ceilSqrt(BigInteger n) {
// use binary search to find smallest x with x^2 >= n
BigInteger lo = BigInteger.valueOf(1),
hi = BigInteger.valueOf(n);
while (lo.compareTo(hi) < 0) {
BigInteger mid = lo.add(hi).divide(2);
if (mid.multiply(mid).compareTo(x) >= 0)
hi = mid;
else
lo = mid.add(BigInteger.ONE);
}
return lo;
}
// checks if n is a perfect square
boolean isPerfectSquare(BigInteger n) {
BigInteger x = ceilSqrt(n);
return x.multiply(x).equals(n);
}
Your tests for perfect squares involve floating point calculations. That is liable to give you incorrect answers because floating point calculations typically give you inaccurate results. (Floating point is at best an approximate to Real numbers.)
In this case sqrt(n*n) might give you n - epsilon for some small epsilon and (int) sqrt(n*n) would then be n - 1 instead of the expected n.
Restructure your code so that the tests are performed using integer arithmetic. But note that N < 1010 means that N2 < 1020. That is bigger than a long ... so you will need to use ...
UPDATE
There is more to it than this. First, Math.sqrt(double) is guaranteed to give you a double result that is rounded to the closest double value to the true square root. So you might think we are in the clear (as it were).
But the problem is that N multiplied by N has up to 20 significant digits ... which is more than can be represented when you widen the number to a double in order to make the sqrt call. (A double has 15.95 decimal digits of precision, according to Wikipedia.)
On top of that, the code as written does this:
int cand = sc.nextInt();
int aTest = (5 * (cand * cand)) + 4;
For large values of cand, that is liable to overflow. And it will even overflow if you use long instead of int ... given that the cand values may be up to 10^10. (A long can represent numbers up to +9,223,372,036,854,775,807 ... which is less than 1020.) And then we have to multiply N2 by 5.
In summary, while the code should work for small candidates, for really large ones it could either break when you attempt to read the candidate (as an int) or it could give the wrong answer due to integer overflow (as a long).
Fixing this requires a significant rethink. (Or deeper analysis than I have done to show that the computational hazards don't result in an incorrect answer for any large N in the range of possible inputs.)
According to this link a number is Fibonacci if and only if one or both of (5*n2 + 4) or (5*n2 – 4) is a perfect square so you can basically do this check.
Hope this helps :)
Use binary search and the Fibonacci Q-matrix for a O((log n)^2) solution per test case if you use exponentiation by squaring.
Your solution does not work because it involves rounding floating point square roots of large numbers (potentially large enough not to even fit in a long), which sometimes will not be exact.
The binary search will work like this: find Q^m: if the m-th Fibonacci number is larger than yours, set right = m, if it is equal return true, else set left = m + 1.
As it was correctly said, sqrt could be rounded down. So:
Even if you use long instead of int, it has 18 digits.
even if you use Math.round(), not simply (int) or (long). Notice, your function wouldn't work correctly even on small numbers because of that.
double have 14 digits, long has 18, so you can't work with squares, you need 20 digits.
BigInteger and BigDecimal have no sqrt() function.
So, you have three ways:
write your own sqrt for BigInteger.
check all numbers around the found unprecise double sqrt() for being a real sqrt. That means also working with numbers and their errors simultaneously. (it's horror!)
count all Fibonacci numbers under 10^10 and compare against them.
The last variant is by far the simplest one.
Looks like to me the for-loop doesn't make any sense ?
When you remove the for-loop for me the program works as advertised:
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cand = sc.nextInt();
if(cand < 0){System.out.println("IsNotFibo"); return; }
int aTest = 5 * cand *cand + 4;
int bTest = 5 * cand *cand - 4;
int sqrt1 = (int)Math.sqrt(aTest);
int sqrt2 = (int)Math.sqrt(bTest);
if((sqrt1 * sqrt1 == aTest)||(sqrt2 * sqrt2 == bTest)){
System.out.println("IsFibo");
}else{
System.out.println("IsNotFibo");
}
}
}
You only need to test for a given candidate, yes? What is the for loop accomplishing? Could the results of the loop be throwing your testing program off?
Also, there is a missing } in the code. It will not run as posted without adding another } at the end, after which it runs fine for the following input:
10 1 2 3 4 5 6 7 8 9 10
IsFibo
IsFibo
IsFibo
IsNotFibo
IsFibo
IsNotFibo
IsNotFibo
IsFibo
IsNotFibo
IsNotFibo
Taking into account all the above suggestions I wrote the following which passed all test cases
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long[] fib = new long[52];
Set<Long> fibSet = new HashSet<>(52);
fib[0] = 0L;
fib[1] = 1L;
for(int i = 2; i < 52; i++){
fib[i] = fib[i-1] + fib[i - 2];
fibSet.add(fib[i]);
}
int n = sc.nextInt();
long cand;
for(int i = 0; i < n; i++){
cand = sc.nextLong();
if(cand < 0){System.out.println("IsNotFibo");continue;}
if(fibSet.contains(cand)){
System.out.println("IsFibo");
}else{
System.out.println("IsNotFibo");
}
}
}
}
I wanted to be on the safer side hence I choose 52 as the number of elements in the Fibonacci sequence under consideration.

Project Euler 12 - Optimization [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 9 years ago.
Improve this question
I am working on Project Euler Problem 12. Could anyone provide any tips on how to improve my code so it executes in my life time?
public class HighlyDivisibleTriangularNumber {
public static void main(String[] args) {
int divisors = 0;
int count = 1;
while(divisors <= 501) {
long triNum = triangularNumber(count);
divisors = getFactors(triNum);
System.out.println(triNum+"_"+divisors);
count++;
}
}
private static int getFactors(long triNum) {
int divisors = 0;
while(triNum > 1) {
triNum = triNum / 2;
divisors++;
}
return divisors;
}
private static long triangularNumber(int i) {
long total = 0;
for(int k = 1; k <= i; k++) {
total += k;
}
return total;
}
}
1) triangular numbers
The first (and probably most important) optimization you can do is in how you compute the triangular numbers.
You can observe that the nth triangular number (let's call it t(n) ) is equal to n + t(n-1).
So each time you compute a triangular number, you can just take the triangular number before it and add n. This would lead to the naive recursive function :
private static long triangularNumber(int i) {
if(i == 1) return 1;
else return i+triangularNumber(i-1);
}
But this won't improve the performance much... to resolve this, I suggest you do some research on memoization and adapt the function I gave you (I won't give you the answer, this is an excellent exercise)
Now, on a regular computer you should have the answer to the problem in a reasonable time. But it can be improved a little better
2) counting divisors
Your function for counting divisors is wrong. What you should do is try to divide your number by successive natural numbers and see if the result is an natural integer.
private static int getFactors(long triNum) {
int divisors = 0;
for(int i = 1; i <= triNum; ++i) {
if(triNum%i == 0) // triNum is a multiple of 1 <=> i is a divisor of triNum
divisors++;
}
return divisors;
}
You can even improve this by counting only to the square root of trinum and adding two divisors each time. But there's a trick if you do this, I'll let you figure it out if you decide to try this.
Why do do recompute the triNum each time? Just add the difference each time (basically your count).
public static void main(String[] args) {
int divisors = 0;
int count = 1;
long truNum = 0;
while(divisors <= 501) {
triNum += count;
divisors = getFactors(triNum);
System.out.println(triNum+"_"+divisors);
count++;
}
}
Furthermore, your approach to count the factors is completely off. You are just searching for the first power of two to be greater than the given number. Read up on (prime)-factorization. Note that you need to account for the combinations of (prime) factors, too.
Example: 12
12 = 2 * 2 * 3
But the divisors of 12 are
1, 2, 3, 4 (= 2*2), 6 (= 2*3), 12
So in total there are 6 divisors of 12 and not 3 as the mere prime factorization may lead you to believe.

Categories