I am trying to write a program that will let me know if a number has the odd divisor greater than one. Let's n be the number, and x be the divisor. x%2!=0 and x>1;
Code:
import java.util.Scanner;
public class Simple1{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
long n;
for(int i=0; i<t; i++) {
n=sc.nextLong();
if(n<3)System.out.println("NO");
else {
if(n%2!=0)System.out.println("YES");
else {
int ans=0;
for(long j=3; j<=n/2; j+=2) {
if(n%j==0) {
ans=1;
break;
}
}
if(ans==1)System.out.println("YES");
else System.out.println("NO");
}
}
}
}
}
This java code works fine. But it's not working for a specific input.. and that is n = 1099511627776. If I change the last digit to any int other than 6, then it works fine and gives output. Even numbers greater than that works. But only this number n=1099511627776, when I input this to my program, no terminating happens and no output. Help me to figure out what happens here.
The number 1099511627776 is two to the power 40. That means it has to check through the whole big for-loop to find no odd factors. You would get the same problem, to different extents, with 2199023255552 (2 to the 41) and 549755813888 (2 to the 39). You have to wait longer if you want to do it this way.
A much faster way is to divide n by 2 until you get an odd number.
E.g.
long n = sc.nextLong();
while (n > 1 && n % 2 == 0) {
n /= 2;
}
if (n > 1) {
System.out.println("Yes.");
} else {
System.out.println("No.");
}
An even faster way to tell if a number is a power of two is a bit-twiddling hack:
// Powers of 2 have the property that n & (n-1) is zero
if ((n & (n - 1)) != 0) {
System.out.println("Yes."); // Not a power of two, so has an odd factor
} else {
System.out.println("No."); // Is a power of two, so does not have an odd factor
}
Can you get rid of the powers of two another way?
long number = 1099511627776l;
long r = number >> Long.numberOfTrailingZeros(number);
Then r is an odd divisor, which might be greater than one.
If you think in base 10, then you know a number is divisible by ten if has a trailing zero. You can remove all of the powers of 10 by removing all of the zeros. It is the same for base 2, you can remove all of the factors of 2 by removing all of the trailing zeros (in binary representation).
The code below has no output when I run it, I think somehow it is infinite loop? How to fix it?
Write a method named getEvenDigitSum with one parameter of type int called number.
The method should return the sum of the even digits within the number.
If the number is negative, the method should return -1 to indicate an invalid value.
EXAMPLE INPUT/OUTPUT:
getEvenDigitSum(123456789); → should return 20 since 2 + 4 + 6 + 8 = 20
getEvenDigitSum(252); → should return 4 since 2 + 2 = 4
getEvenDigitSum(-22); → should return -1 since the number is negative
public class getEvenDigitSum {
public static int getEvenDigitSum(int number) {
int sum = 0;
int lastDigit=0;
if (number < 0) {
return -1;
}
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
}
return sum;
}
}
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
}
OK, and what happens if the number isn't even? You didn't make an else/else if statement after; if your number is odd, it stays the same, the loop is infinite, and hence your code does nothing.
Your condition only handles even digits, but think about what happens when you get a number that contains odd digit, like 1221 for example.
Try adding the missing else statement:
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
else {
// Deal with odd digit, leaving for you to implement
{
}
General tip: The best way to find errors in your code is to write tests and debug your code.
These are two skills every developer should poses and practice regularly
class Armstrong {
public static void main(String[] args) {
int low = 999, high = 99999;
for(int number = low + 1; number < high; ++number) {
int digits = 0;
int result = 0;
int originalNumber = number;
// number of digits calculation
while (originalNumber != 0) {
originalNumber /= 10;
++digits;
}
originalNumber = number;
// result contains sum of nth power of its digits
while (originalNumber != 0) {
int remainder = originalNumber % 10;
result += Math.pow(remainder, digits);
originalNumber /= 10;
}
if (result == number)
System.out.print(number + " ");
}
}
How does this program work? It would be very helpful. Program to find Armstrong between two intervals? Can someone explain step by step? Help me out.
Steb-by-step Explanantion
Initialize the start and end of the interval with 999 and 9999
You can change these numbers but ensure that low is always lesser than high:
int low = 999;
int high = 99999;
for (int number = low + 1; // Create a variable number and assign it one number greater than low
number < high; // This loop should keep repeating until number is less than high(end of the interval)
++number // After each repetition, increment the value of number by 1
) {
Create a variable digits to store the number of digits in number.
For example, if number is 100, this will be later set as 3 as the algorithm proceeds:
int digits = 0;
Create a variable result that will store the sum of powers of numbers:
int result = 0;
Copy the value of number to a local variable originalNumber because it has to be modified:
int originalNumber = number;
The logic of calculating number of digits in a number is keep dividing it by 10 until the number is 0.
Every time you divide any number by 10, the last digit is stripped out. So every time the last digit is stripped out, increment digit by 1 (digit++)
// number of digits calculation
while (originalNumber != 0) // Continue this while loop till originalNumber is not 0
{
originalNumber /= 10; // Divide the number by 10. Dividing a number by 10 removes its last digit.
++digits; // One digit was removed in the above step, which means it has to be counted, so increment digit by 1
}
// For example, for originalNumber = 423,
// 423 / 10 = 42 : digits = 1 (first loop)
// 42 / 10 = 4 : digits = 2 (second loop)
// 4 / 10 = 0 : digits = 3 (third loop)
// Now originalNumber has become 0, so the while loop condition originalNumber != 0 will be false and the loop will stop.
// Now we have digits = 3, which is the number of digits in 423
// When program reaches here, digits will have the number of digits in the
// number "originalNumber"
Copy number again to originalNumber because we want to modify the number
again and originalNumber has become 0 because of the digit counting loop above:
originalNumber = number;
An Armstrong number is a number which is equal to the sum of digits to the power of its number of digits.
e.g.: in 153, (1^3) + (5^3) + (3^3) = 153. We are obtaining the cube of each digit(1, 5, 3) because 153 has 3 digits 1, 5, 3.
If it was say 50, we would check ( 5^2 + 0^2) because 50 has 2 digits (50 is not Armstrong, because 25 + 0 = 25 which is not equal to 50)
We saw above dividing a number by 10 removes the last digit (423 / 10 = 42)
Similarly, if we only want this last digit, we can get it by modulus 10 (% 10): (423 % 10 = 3) (42 % 10 = 2) (4 % 10 = 4)
// Let's assume originalNumber is 153
while (originalNumber != 0) // Same as above, keep looping till the originalNumber is not 0(i.e. all digits have been removed)
{
Extract the last digit to remainder, (for 153: 153 % 10 = 3) (for 15: 15 % 10 = 5)
int remainder = originalNumber % 10;
Now we have the last digit, we need to raise this digit to the number of
digits i.e. 3(for 153): (3^3) = 27. We do this using Math.pow(3, 3). Add this number to result. In the end after each loop's number's power is added, at the end of the loop, result will contain their sum:
result += Math.pow(remainder, digits);
originalNumber /= 10; // Remove the last digit (same as above, for 153: 153 / 10 = 15)
// After this line finishes, one rightmost digit will be removed, this will keep
// happening till originalNumber = 153 becomes 15, then 1, then 0.
// When originalNumber is 0, loop stops and we will have the total sum in result
}
For an Armstrong number like 153, result will also contain 153. For a non-Armstrong number it will contain something else.
if (result == number) // For 153, both will be equal.
System.out.print(number + " "); // This will only execute if result is equal to number, or in other words, only if the number is Armstrong
}
Improvements
As per single responsibility principle, each function or class must exactly do one thing. You have a monolithic main() method that:
Defines the interval
Counts the digit of each number in the interval
Calculate the sum of powers of digits
Check if number is Armstrong and print it.
I would prefer breaking down each operation to a separate method, so that it improves readability and maintainability while respecting single-responsibiliy principle:
class Armstrong {
public static int countDigits(int number) {
int digits = 0;
while (number != 0) {
number /= 10;
++digits;
}
return digits;
}
public static int digitPowerSum(int number, int power) {
int result = 0;
while (number != 0) {
int remainder = number % 10;
result += Math.pow(remainder, power);
number /= 10;
}
return result;
}
public static boolean isArmstrong(int number) {
int digits = countDigits(number);
int sum = digitPowerSum(number, digits);
return sum == number ; // will return true if both numbers are equal else false
}
public static ArrayList<Integer> armstrongNumbersBetween(int low, int high) {
ArrayList<Integer> numbers = new ArrayList<>();
for(int number = low + 1; number < high; number++) {
if (isArmstrong(number)) {
numbers.add(number);
}
}
return numbers;
}
public static void main(String[] args) {
int low = 999, high = 99999;
ArrayList<Integer> numbers = armstrongNumbersBetween(low, high);
for(int number : numbers) {
System.out.print(number + " ");
}
}
}
Here, each method does exactly one thing and this helps in better reusability. You just have to call the required methods to perform a specific operation.
If something is unclear, let me know.
I tried to write a method (for kicks) that would sum up the digits at even places using Java recursion.
For example, the number 23495 would return 3+9 = 12.
I am unsuccessful and would appreciate hints or what I'm doing wrong.
int sumEven = 0;
int sumOdd = 0;
int i = 1;
if (n == 0)
return sumEven;
if (n != 0) {
if (i % 2 == 0)
{
i++;
sumEven += n % 10;
}
else
{
i++;
sumOdd += n % 10;
}
}
return sumEven + getEven (n/=10);
The problem is you're trying to do too much - take a look at my comment on the Q
A recursive method needs an input that contains everything it needs to work with, a return value, and an execution path where it calls itself until something happens that means it doesn't need to call itself any more - without this bit it will recourse until it overflows the stack
int sumEveryOtherDigit(int input){
if(input >= 100)
return input%10 + sumEveryOtherDigit(input/100);
else
return input%10;
}
This takes the input , and if there is any point to running again (if the input is at least 100) takes the rightmost digit plus running itself again with a smaller number
Eventually the number gets so small that there isn't any point running itself again so it just returns without running itself again and that is how the recursion stops
Now from your comment on another answer it seems you want to determine even and odd as working from the left so we need to either start with the number (1630) or the number divided by ten (23495 -> 2349) - basically to start the recursion going we always want to pass in a number with an even number of digits
int num = 23495;
int numOfDigits = (int)Math.log10(num)+ 1;
if(numOfDigits%2==0)
result = sumEveryOtherDigit(num);
else
result = sumEveryOtherDigit(num/10);
You should iterate over the digits of the input number, and then sum the remainder mod 10 only for even position digits:
int input = 23495;
input /= 10;
int sum = 0;
while (input > 0) {
sum += input % 10; // add last even digit
input /= 100; // advance by two digits, to the next even digit
}
System.out.println("sum of even digits of input is: " + sum);
This prints:
sum of even digits of input is: 12
I am working on a prime factorization program implemented in Java.
The goal is to find the largest prime factor of 600851475143 (Project Euler problem 3).
I think I have most of it done, but I am getting a few errors.
Also my logic seems to be off, in particular the method that I have set up for checking to see if a number is prime.
public class PrimeFactor {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < Math.sqrt(600851475143L); i++) {
if (Prime(i) && i % Math.sqrt(600851475143L) == 0) {
count = i;
System.out.println(count);
}
}
}
public static boolean Prime(int n) {
boolean isPrime = false;
// A number is prime iff it is divisible by 1 and itself only
if (n % n == 0 && n % 1 == 0) {
isPrime = true;
}
return isPrime;
}
}
Edit
public class PrimeFactor {
public static void main(String[] args) {
for (int i = 2; i <= 600851475143L; i++) {
if (isPrime(i) == true) {
System.out.println(i);
}
}
}
public static boolean isPrime(int number) {
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i = 3; i <= number; i++) {
if (number % i == 0) return false;
}
return true;
}
}
Why make it so complicated? You don't need do anything like isPrime(). Divide it's least divisor(prime) and do the loop from this prime. Here is my simple code :
public class PrimeFactor {
public static int largestPrimeFactor(long number) {
int i;
for (i = 2; i <= number; i++) {
if (number % i == 0) {
number /= i;
i--;
}
}
return i;
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
System.out.println(largestPrimeFactor(600851475143L));
}
}
edit: I hope this doesn't sound incredibly condescending as an answer. I just really wanted to illustrate that from the computer's point of view, you have to check all possible numbers that could be factors of X to make sure it's prime. Computers don't know that it's composite just by looking at it, so you have to iterate
Example: Is X a prime number?
For the case where X = 67:
How do you check this?
I divide it by 2... it has a remainder of 1 (this also tells us that 67 is an odd number)
I divide it by 3... it has a remainder of 1
I divide it by 4... it has a remainder of 3
I divide it by 5... it has a remainder of 2
I divide it by 6... it has a remainder of 1
In fact, you will only get a remainder of 0 if the number is not prime.
Do you have to check every single number less than X to make sure it's prime? Nope. Not anymore, thanks to math (!)
Let's look at a smaller number, like 16.
16 is not prime.
why? because
2*8 = 16
4*4 = 16
So 16 is divisible evenly by more than just 1 and itself. (Although "1" is technically not a prime number, but that's technicalities, and I digress)
So we divide 16 by 1... of course this works, this works for every number
Divide 16 by 2... we get a remainder of 0 (8*2)
Divide 16 by 3... we get a remainder of 1
Divide 16 by 4... we get a remainder of 0 (4*4)
Divide 16 by 5... we get a remainder of 1
Divide 16 by 6... we get a remainder of 4
Divide 16 by 7... we get a remainder of 2
Divide 16 by 8... we get a remainder of 0 (8*2)
We really only need one remainder of 0 to tell us it's composite (the opposite of "prime" is "composite").
Checking if 16 is divisible by 2 is the same thing as checking if it's divisible by 8, because 2 and 8 multiply to give you 16.
We only need to check a portion of the spectrum (from 2 up to the square-root of X) because the largest number that we can multiply is sqrt(X), otherwise we are using the smaller numbers to get redundant answers.
Is 17 prime?
17 % 2 = 1
17 % 3 = 2
17 % 4 = 1 <--| approximately the square root of 17 [4.123...]
17 % 5 = 2 <--|
17 % 6 = 5
17 % 7 = 3
The results after sqrt(X), like 17 % 7 and so on, are redundant because they must necessarily multiply with something smaller than the sqrt(X) to yield X.
That is,
A * B = X
if A and B are both greater than sqrt(X) then
A*B will yield a number that is greater than X.
Thus, one of either A or B must be smaller than sqrt(X), and it is redundant to check both of these values since you only need to know if one of them divides X evenly (the even division gives you the other value as an answer)
I hope that helps.
edit: There are more sophisticated methods of checking primality and Java has a built-in "this number is probably prime" or "this number is definitely composite" method in the BigInteger class as I recently learned via another SO answer :]
You need to do some research on algorithms for factorizing large numbers; this wikipedia page looks like a good place to start. In the first paragraph, it states:
When the numbers are very large, no efficient integer factorization algorithm is publicly known ...
but it does list a number of special and general purpose algorithms. You need to pick one that will work well enough to deal with 12 decimal digit numbers. These numbers are too large for the most naive approach to work, but small enough that (for example) an approach based on enumerating the prime numbers starting from 2 would work. (Hint - start with the Sieve of Erasthones)
Here is very elegant answer - which uses brute force (not some fancy algorithm) but in a smart way - by lowering the limit as we find primes and devide composite by those primes...
It also prints only the primes - and just the primes, and if one prime is more then once in the product - it will print it as many times as that prime is in the product.
public class Factorization {
public static void main(String[] args) {
long composite = 600851475143L;
int limit = (int)Math.sqrt(composite)+1;
for (int i=3; i<limit; i+=2)
{
if (composite%i==0)
{
System.out.println(i);
composite = composite/i;
limit = (int)Math.sqrt(composite)+1;
i-=2; //this is so it could check same prime again
}
}
System.out.println(composite);
}
}
You want to iterate from 2 -> n-1 and make sure that n % i != 0. That's the most naive way to check for primality. As explained above, this is very very slow if the number is large.
To find factors, you want something like:
long limit = sqrt(number);
for (long i=3; i<limit; i+=2)
if (number % i == 0)
print "factor = " , i;
In this case, the factors are all small enough (<7000) that finding them should take well under a second, even with naive code like this. Also note that this particular number has other, smaller, prime factors. For a brute force search like this, you can save a little work by dividing out the smaller factors as you find them, and then do a prime factorization of the smaller number that results. This has the advantage of only giving prime factors. Otherwise, you'll also get composite factors (e.g., this number has four prime factors, so the first method will print out not only the prime factors, but the products of various combinations of those prime factors).
If you want to optimize that a bit, you can use the sieve of Eratosthenes to find the prime numbers up to the square root, and then only attempt division by primes. In this case, the square root is ~775'000, and you only need one bit per number to signify whether it's prime. You also (normally) only want to store odd numbers (since you know immediately that all even numbers but two are composite), so you need ~775'000/2 bits = ~47 Kilobytes.
In this case, that has little real payoff though -- even a completely naive algorithm will appear to produce results instantly.
I think you're confused because there is no iff [if-and-only-if] operator.
Going to the square root of the integer in question is a good shortcut. All that remains is checking if the number within that loop divides evenly. That's simply [big number] % i == 0. There is no reason for your Prime function.
Since you are looking for the largest divisor, another trick would be to start from the highest integer less than the square root and go i--.
Like others have said, ultimately, this is brutally slow.
private static boolean isPrime(int k) throws IllegalArgumentException
{
int j;
if (k < 2) throw new IllegalArgumentException("All prime numbers are greater than 1.");
else {
for (j = 2; j < k; j++) {
if (k % j == 0) return false;
}
}
return true;
}
public static void primeFactorsOf(int n) {
boolean found = false;
if (isPrime(n) == true) System.out.print(n + " ");
else {
int i = 2;
while (found == false) {
if ((n % i == 0) && (isPrime(i))) {
System.out.print(i + ", ");
found = true;
} else i++;
}
primeFactorsOf(n / i);
}
}
For those answers which use a method isPrime(int) : boolean, there is a faster algorithm than the one previously implemented (which is something like)
private static boolean isPrime(long n) { //when n >= 2
for (int k = 2; k < n; k++)
if (n % k == 0) return false;
return true;
}
and it is this:
private static boolean isPrime(long n) { //when n >= 2
if (n == 2 || n == 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int k = 1; k <= (Math.floor(Math.sqrt(n)) + 1) / 6; k++)
if (n % (6 * k + 1) == 0 || n % (6 * k - 1) == 0) return false;
return true;
}
I made this algorithm using two facts:
We only need to check for n % k == 0 up to k <= Math.sqrt(n). This is true because for anything higher, factors merely "flip" ex. consider the case n = 15, where 3 * 5 = 5 * 3, and 5 > Math.sqrt(15). There is no need for this overlap of checking both 15 % 3 == 0 and 15 % 5 == 0, when we could just check one of these expressions.
All primes (excluding 2 and 3) can be expressed in the form (6 * k) + 1 or (6 * k) - 1, because any positive integer can be expressed in the form (6 * k) + n, where n = -1, 0, 1, 2, 3, or 4 and k is an integer <= 0, and the cases where n = 0, 2, 3, and 4 are all reducible.
Therefore, n is prime if it is not divisible by 2, 3, or some integer of the form 6k ± 1 <= Math.sqrt(n). Hence the above algorithm.
--
Wikipedia article on testing for primality
--
Edit: Thought I might as well post my full solution (*I did not use isPrime(), and my solution is nearly identical to the top answer, but I thought I should answer the actual question):
public class Euler3 {
public static void main(String[] args) {
long[] nums = {13195, 600851475143L};
for (num : nums)
System.out.println("Largest prime factor of " + num + ": " + lpf(num));
}
private static lpf(long n) {
long largestPrimeFactor = 1;
long maxPossibleFactor = n / 2;
for (long i = 2; i <= maxPossibleFactor; i++)
if (n % i == 0) {
n /= i;
largestPrimeFactor = i;
i--;
}
return largestPrimeFactor;
}
}
To find all prime factorization
import java.math.BigInteger;
import java.util.Scanner;
public class BigIntegerTest {
public static void main(String[] args) {
BigInteger myBigInteger = new BigInteger("65328734260653234260");//653234254
BigInteger originalBigInteger;
BigInteger oneAddedOriginalBigInteger;
originalBigInteger=myBigInteger;
oneAddedOriginalBigInteger=originalBigInteger.add(BigInteger.ONE);
BigInteger index;
BigInteger countBig;
for (index=new BigInteger("2"); index.compareTo(myBigInteger.add(BigInteger.ONE)) <0; index = index.add(BigInteger.ONE)){
countBig=BigInteger.ZERO;
while(myBigInteger.remainder(index) == BigInteger.ZERO ){
myBigInteger=myBigInteger.divide(index);
countBig=countBig.add(BigInteger.ONE);
}
if(countBig.equals(BigInteger.ZERO)) continue;
System.out.println(index+ "**" + countBig);
}
System.out.println("Program is ended!");
}
}
I got a very similar problem for my programming class. In my class it had to calculate for an inputted number. I used a solution very similar to Stijak. I edited my code to do the number from this problem instead of using an input.
Some differences from Stijak's code are these:
I considered even numbers in my code.
My code only prints the largest prime factor, not all factors.
I don't recalculate the factorLimit until I have divided all instances of the current factor off.
I had all the variables declared as long because I wanted the flexibility of using it for very large values of number. I found the worst case scenario was a very large prime number like 9223372036854775783, or a very large number with a prime number square root like 9223371994482243049. The more factors a number has the faster the algorithm runs. Therefore, the best case scenario would be numbers like 4611686018427387904 (2^62) or 6917529027641081856 (3*2^61) because both have 62 factors.
public class LargestPrimeFactor
{
public static void main (String[] args){
long number=600851475143L, factoredNumber=number, factor, factorLimit, maxPrimeFactor;
while(factoredNumber%2==0)
factoredNumber/=2;
factorLimit=(long)Math.sqrt(factoredNumber);
for(factor=3;factor<=factorLimit;factor+=2){
if(factoredNumber%factor==0){
do factoredNumber/=factor;
while(factoredNumber%factor==0);
factorLimit=(long)Math.sqrt(factoredNumber);
}
}
if(factoredNumber==1)
if(factor==3)
maxPrimeFactor=2;
else
maxPrimeFactor=factor-2;
else
maxPrimeFactor=factoredNumber;
if(maxPrimeFactor==number)
System.out.println("Number is prime.");
else
System.out.println("The largest prime factor is "+maxPrimeFactor);
}
}
public class Prime
{
int i;
public Prime( )
{
i = 2;
}
public boolean isPrime( int test )
{
int k;
if( test < 2 )
return false;
else if( test == 2 )
return true;
else if( ( test > 2 ) && ( test % 2 == 0 ) )
return false;
else
{
for( k = 3; k < ( test/2 ); k += 2 )
{
if( test % k == 0 )
return false;
}
}
return true;
}
public void primeFactors( int factorize )
{
if( isPrime( factorize ) )
{
System.out.println( factorize );
i = 2;
}
else
{
if( isPrime( i ) && ( factorize % i == 0 ) )
{
System.out.print( i+", " );
primeFactors( factorize / i );
}
else
{
i++;
primeFactors( factorize );
}
}
public static void main( String[ ] args )
{
Prime p = new Prime( );
p.primeFactors( 649 );
p.primeFactors( 144 );
p.primeFactors( 1001 );
}
}