recently I have been working on an assignment to find the fibonacci sum of a number (user input, positive integer) in recursive form, for example (output is):
9 = 8 + 1
14 = 13 + 1
30 = 21 + 8 + 1
and so on.
So far, I have made the recursive function to calculate the actual fibonacci numbers (such as 8 and 1 in the sum of 9), it looks like this :
static long[] f = new long[50];
static long fib(int n) {
if (n <= 1) { //base case
return 1;
}
if (n < f.length) {
if (f[n] != 0) {
return f[n];
}
return f[n] = fib(n - 1) + fib(n - 2);
}
return fib(n - 1) + fib(n - 2);
}
My assignment gives me this as a hint:
Hints:
Re-cast the theorem as
n = fj + (n - fj )
This suggests a recursive solution.
and with that, I have currently come up with this:
static void fibSum(int n)
{
System.out.print(n + " = ");
for(int i = 0; i >= 0 ; i++)
{
if(n - (fib(i)) == 0)
{
System.out.println(fib(i));
}
else if(n < (fib(i)) && n > (fib(i-1)))
{
System.out.println(fib(i-1) + " + ");
}
}
}
My output goes as far as [entering for example, 9 as the user input] '9 = 8 +', and with that said, my question for all of those who are reading this (and thank you for getting this far!) is why I am not getting the last number (1) in the broken-down sum, and is my solution considered recurisve, as it really does not follow the format that I have seen in past examples, and in the fib() method that I wrote. I did not know how to implement printing the plus signs through that format.
Here is my main method for reference:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter an integer number: ");
int n = scan.nextInt();
fibSum(n);
You seems to have various issues in your function fibSum:
Your For loop does not have an end. (while i is positive, increment i.)
You can store: fib(i) in your for loop to avoid multiple calculations.
You don't handle every cases on your if/else condition.
Exemple:
n = 2.
fib(0) = 1
if(2 - 1 == 0) => false
if(2 < 1 && 2 > fib(-1)) => false && error.
// Displays nothing. Should display: 2 = 1 + 1
Finally figured it out, this time using a while loop. No matter how many times I tried fixing the for loop, I ran into issues with my output, so I used a boolean variable and simply made it false once I reached n = 0.
Related
I had an interview and I've been asked to print numbers from 1 to a 1000 digit number -
1,
2,
3,
.
.
.
.,
999999999999999999999999999999999999999999999999........
I couldn't solve it but I'm still looking for the best way to do it, because obviously, you cant use integers or floats in a case like this and because it's a job interview I couldn't use any libraries that can handle it.
Can anyone think of a good solution? preferably in Java/pseudocode.
I had an interview and I've been asked to print numbers from 1 to a 1000 digit number
I guess the kind of answer they expected you to give is:
"We need to print the numbers from 1 to 10^1000-1. Last year, $80e9 worth of processors were sold worldwide [1], even if one processor per dollar had been sold and each processor was a thousand times faster than the fastest of them all [2] and only one instruction was used to print each number and all these processors had been produced during the last 1000 years, still: 1e1000 / (80e9 - 1000 - 8.4e9 - 1000) > 1e973 seconds to print all the numbers. That is 10e956 billion years."
Anyway, if you wish wait:
BigInteger n = BigInteger.ONE;
BigInteger last = BigInteger.TEN.pow(1000);
while(n.compareTo(last) < 0) {
System.out.println(n);
n = n.add(BigInteger.ONE);
}
Assuming only System.out.print is able to use (String is a library, see [3]), a possible solution without copy over and over again strings, and with the expected output could be:
static void printDigits(int n) {
ds(0, n, new byte[n]);
}
static void ds(int p, int k, byte[] d) {
if (p < d.length) { // if more digits to print
for (byte i = 0; i < 10; i++) { // from digit 0 to 9
d[p] = i; // set at this position
ds(p + 1, i == 0 ? k : (p < k ? p : k), d); // populate next storing first non-zero
}
} else {
if(k < d.length) { // if is not zero
if(k < d.length - 1 || d[d.length - 1] != 1) // if is not one
System.out.print(", "); // print separator
for(int i = k; i < d.length; i++) // for each digit
System.out.print((char)('0' + d[i])); // print
}
}
}
then, for printDigits(5) the output is
1, 2, 3, 4, ..., 99999
[1] https://epsnews.com/2020/09/14/total-microprocessor-sales-to-edge-slightly-higher-in-2020/
[2] https://en.wikipedia.org/wiki/Clock_rate
[3] https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Using recursion (if only to print):
void digits(int count) {
if (count < 0) throw new IllegalArgumentException("invalid count: " + count);
digits(count, "");
}
void digits(int count, String text) {
if (count == 0) {
System.out.println(text);
} else {
for (var i = 0; i < 10; i++) {
if (i == 0 && text.isEmpty()) {
digits(count-1, text);
} else {
digits(count-1, text+i);
}
}
}
}
I have the following statement and I do not understand very well what it asks for:
We say that a number n is rare when it verifies that for any number m <= n and such that both are cousins among themselves, it turns out that m is prime (two numbers are cousins each other when the greatest common divisor of both numbers is unity).
Write a program that lists all rare numbers between 3 and a value entered by the user.
After thinking how to shed it from the statement I got the solution, which I do not know if it is the correct one.
Can someone confirm that it is well and the result is what he really asks for?
import java.util.Scanner;
public class Cousins {
public static void main(String[] args) {
System.out.println("Enter a number to calculate the cousins:");
Scanner teclado = new Scanner(System.in);
int n = teclado.nextInt();
boolean cousins;
for (int m = 3; m < n; m++) {
cousins = mcd(n, m);
if (cousins == true) {
System.out.println(n + " " + m + " They are cousins among themselves.");
} else if (cousins == false) {
System.out.println(n + " " + m + " They are not cousins to each other.");
}
}
}
public static boolean mcd(int n, int m) {
boolean cousins = true;
for (int i = 2; i <= n; i++) {
if (n % i == 0 && m % i == 0) {
cousins = false;
}
}
return cousins;
}
}
Hmm, this seems not really correct to me. It would be correct, if your excercise would be to check if the numbers from 3 to the user-entered number (lets call it n) are cousins with n. This is what you are doing in your program:
You loop over the integeres from 3 to n and check if the current number and n are cousins. By the way in the loop inside the function mcd() I would add a second condition for finishing, like this:
for (int i = 2; i <= n && i <= m; i++)
But this is not really what you are supposed to do. You need tho check, whether the numbers from 3 to n are rare and not cousins with n.
To do so you basically need a second loop: For each number m between 3 and n you must iterate over the numbers i smaller than m to see if i and m are cousins. And for any number i, where this check returns true, see if this i is prime. If all i's that are cousins to m are prime, then m is rare.
Here is my try:
import java.util.Scanner;
public class Cousins {
public static void main(String[] args) {
System.out
.println("Enter a number to calculate the cousins:");
Scanner teclado = new Scanner(System.in);
int n = teclado.nextInt();
boolean cousins;
for (int m = 3; m < n; m++) {
boolean rare = true;
// Needless to check 1 as 1 is cousin to any number and is prime
for(int i = 2; i <= m; i++) {
if(mcd(i, m) && !numberIsPrime(i)) {
rare = false;
}
}
if(rare) {System.out.println(m + " is rare.");}
else {System.out.println(m + " is not rare.");}
}
}
public static boolean mcd(int n, int m) {
boolean cousins = true;
for (int i = 2; i <= n && i <= m; i++) {
if (n % i == 0 && m % i == 0) {
cousins = false;
}
}
return cousins;
}
public static boolean numberIsPrime(int n) {
boolean prime = true;
for(int i = 2; i < n; i++) {
if(n % i == 0) {prime = false;}
}
return prime;
}
}
EDIT: Sorry, my description above was a bit wrong, I have corrected it now.
EDIT: Regarding your comment: The output of the program that you have written (3,4,6,8, and so on) is the perfectly correct list of rare numbers between 1 and 100 according to the definition of rare that you have given. Ok, let's look at some examples. Let's take the number 5 and check if 5 is rare. To check this we must go through all integers i from 1 to 5. If any of them is a cousin of 5, but NOT prime, then 5 is not rare . Otherwise 5 is rare (according to your definition of rare). So let's do it:
i = 1: Is 1 a cousin of 5? Yes it is, because the only common divisor is 1. Is 1 prime? Yes. Ok. Continue with i=2.
i = 2: Is 2 a cousin of 5? Yes it is, because the only common divisor is 1. Is 2 prime? Yes Ok. Continue.
i = 3: Is 3 a cousin of 5? Yes it is, because the only common divisor is 1. Is 3 prime? Yes Ok. Continue.
i = 4: Is 4 a cousin of 5? Yes it is, because the only common divisor is 1. Is 4 prime? NO!!!
So we have found a number i < 5 which is a cousin of 5 but not prime. So 5 is not rare and that's why 5 is not part of the program output.
I hope it is clearer now.
Here is my program for outputting prime factorization of a given number. I am still just a beginner in java so I know it is not the most efficient code. The problem arises when I input relatively big numbers.
Input: 11 Output: 11
Input: 40 Output: 2 2 2 5
Input: 5427 Output: 3 3 3 3 67
Input: 435843 Output: 3 3 79 613
Input: 23456789 Output: none (there appears to be an infinite loop and the code should return 23456789 since it is a prime number on its own)
What might cause this issue?
import java.util.Scanner;
public class PrimeFactorization {
public static boolean isPrime(long n) {
boolean boo = false;
long counter = 0;
if (n == 1) {
boo = false;
} else if (n == 2) {
boo = true;
} else {
for (long i = 2; i < n; i++) {
if (n % i == 0) {
counter++;
}
}
if (counter == 0) {
boo = true;
}
}
return boo;
}
public static void primeFactorization(long num) {
for (long j = 1; j <= num; j++) {
if (isPrime(j)) {
if (num % j == 0) {
while (num % j == 0) {
System.out.printf(j + " ");
num = num / j;
}
}
}
if (num == 1) {
break;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter any number:");
long num = scanner.nextLong();
System.out.print("Prime factorization of your number is: ");
primeFactorization(num);
scanner.close();
}
}
There's no actual error - you're just doing things a very inefficient way. Basically, you're checking every number between 1 and 23456789 for primeness, before dividing.
There's absolutely no point in doing this check. As you work your way up from 1 to 23456789, each time you uncover a factor, you know it has to be prime, because you've already divided out all smaller factors. So if you do all of the following, this will still work correctly, and much more quickly.
Remove the isPrime method completely.
Remove the line if (isPrime(j)) {, and the matching }
Change the loop so that j starts at 2, like for(long j = 2 ; j <= num ; j++) {
Remove if (num == 1) { break; } from the end of the loop. It serves no purpose at all.
No matter how efficient the code, factorizing large numbers takes a while - so long it may feel like the computer has hung. Given your code, even modestly large numbers will take a long time.
The main thing you can do to improve your code's efficiency to to note that for any pair of factors of a number, one of them will be no more than the square root of the number. You can use this fact to limit the loop to reduce the order of you algorithm for O(n) to O(log n).
long sqrt = Math.sqrt(number);
for (long i = 2; i < sqrt; i++) {
...
There are many other things you can do, but this change will have the greatest effect.
If number changes value during the loop (as for example in your second factorizing loop), you'll if course need to recalculate the end value:
for (...)
// if number changes
sqrt = Math.sqrt(number);
I am revising for a software testing exam. One of the questions gives this method and asks to identify the fault as well as produce a test case (if one exists) which does not execute the fault.
Here is the code:
public static int oddOrPos(int[] x) {
//Effects: if x==null throw NullPointerException
// else return the number of elements in x that
// are either odd or positive (or both)
int count = 0;
for (int i = 1; i < x.length; i++)
{
if (x[i]%2 == 0 || x[i] > 0)
{
count++;
}
}
return count;
}
I have identified two problems. One being that i is initialised to 1 in the for loop so x[0] doesn't get tested. Also x[i] % 2 == 0 should be x[i] != 0
Are these problems faults or errors? I ask this because the question makes it appear that there is only one fault.
Also, I assume that because the for loop will always be executed, there is no test case which will not execute the fault.
Actually x[i] % 2 == 0 should be x[i] % 2 != 0 (if we want to detect odd values along with the positive ones. The existing code will detect even values instead).
The test case is just { -2 } - this element is even and negative, so should not get counted, and the method will return 0 even though it is faulty. { 1 } will also give 0, which is wrong.
If you want to detect odd negative values you'll have to look for -1 and not for 0 as it's done right now.
For odd positive values it will be 1. So basically you want anything but 0.
The % operator is a remainder operator, not really a modulo operator, it returns a negative number if the first given number is negative:
class Test1 {
public static void main(String[] args) {
int a = 5 % 3; // 2
int b = 5 / 3; // 1
System.out.println("5%3 produces " + a +
" (note that 5/3 produces " + b + ")");
int c = 5 % (-3); // 2
int d = 5 / (-3); // -1
System.out.println("5%(-3) produces " + c +
" (note that 5/(-3) produces " + d + ")");
int e = (-5) % 3; // -2
int f = (-5) / 3; // -1
System.out.println("(-5)%3 produces " + e +
" (note that (-5)/3 produces " + f + ")");
int g = (-5) % (-3); // -2
int h = (-5) / (-3); // 1
System.out.println("(-5)%(-3) produces " + g +
" (note that (-5)/(-3) produces " + h + ")");
}
}
Another "small" fault is the way the condition is done. Instead of checking for odd or positive, looking for positive or odd will be slightly faster. It's only because it's easier to check if a number is positive or not than getting its remainder.
Resources:
15.17.3. Remainder Operator %
The major thing here is that your for loop is starting at 1, and it should start at 0. You will always miss the first element of the array. Also x[i]%2 == 0 returns true for even numbers, not odd. So change that to x[i]%2 != 0.
public class test{
public static void main(String[] args){
int[] x = {3, 5, -1, -14}
if( 3 == oddOrPos(x)){
System.out.println("Working");
else
System.out.println("Test Fail");
}
public static int oddOrPos(int[] x) {
//Effects: if x==null throw NullPointerException
// else return the number of elements in x that
// are either odd or positive (or both)
int count = 0;
for (int i = 0; i < x.length; i++)
{
if (x[i]%2 != 0 || x[i] > 0)
{
count++;
}
}
return count;
}
}
As I understand it, you are right in your assumption. The first position of the array should be tested, hence the i[0] you pointed out.
However, x[i]%2 == 0 should instead be x[i]%2 == 1 for an odd number.
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 );
}
}