I am making a prime number finder, that would find the prime numbers for a given number that the user inputs. What I have now seems to either miss primes, or add non-primes to the ArrayList. My code seems logical to me, and I'm confused as to why this is happening. Can anyone tell me what I am doing wrong? Or maybe a simpler way to do this (I feel like I am over-complicating)? Some examples of errors would be: Enter 21, only 3 shows as a prime. Enter 11000, 25 and 55 show up (not prime obviously). Thanks in advance!
import java.util.*;
public class PrimeFactors {
public static void main(String args[]) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextLong();
System.out.println("\nThe prime factors are: " + primeFactor(num) + "\n");
}
public static ArrayList<Long> primeFactor(long n) {
long output = 0;
long guess = 2;
ArrayList<Long> primeFactors = new ArrayList<Long>();
while (guess <= n) {
long primes = 0;
long i = 2;
long x = 0;
long rt = 1;
long duplicate = 0;
output = n % guess;
// Finds the sqrt.
while (x <= n) {
x = rt * rt;
rt++;
}
// Finds odd factors.
if ((output == 0) && (guess % 2 != 0)) {
// This divides the odd factor by an incrementing number that is not 1 or the number itself.
while (i < rt) {
primes = primes + (guess % i);
// If the sum of the remainders to the division is not 0, then the number is prime.
// I used duplicate to make sure it didn't just go through once and count as prime.
if (primes != 0){
// There were duplicates, so I added them for the division later.
duplicate = duplicate + guess;
// This was used to wait for the while loop to finish, then find if the amount of times the guess went through was equal to its value - 1 and another 1 for the final number (primes are only divisible by one and itself).
if (i == (factors - 1)) {
if ((duplicate / guess) == (guess- 2)) {
primeFactors.add(guess);
}
}
}
i++;
}
}
guess++;
}
return primeFactors;
}
}
The math and logic you're doing here is very strange and I don't quite follow what's happening.
To that end, I would vote +1 for making the code simpler. This can be done with two simple methods. The first method will find factors for a number and run them through a prime checker. If they are a factor and pass the prime check, they get added to the array.
Bonus points: increase the speed of the algorithm by only searching through the bottom half of each of the factor checker and prime checker. Logic being that any value beyond half a number cannot be a factor of that number.
More bonus points for speed, increment by 2 skipping all multiples of 2, since they are automatically not prime. Good luck!
import java.util.ArrayList;
import java.util.Scanner;
/***************************************************
*
* #file: PrimeFactors.java
* #date: Mar 17, 2013
* #author: AaronW
*/
/**
*
* #author AaronW
*/
public class PrimeFactors {
public PrimeFactors() {
}
/**
*
* #param args
*/
public static void main(String[] args) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextInt();
System.out.println("\nThe factors are: " + findFactors((double)num) + "\n");
}
public static ArrayList<Integer> findFactors(Double num) {
ArrayList<Integer> factors = new ArrayList<Integer>();
for (int x = 1; x <= num; x++) {
System.out.println("Testing " + num + " % " + x + " = " + num % x);
// First, let's see if a number is factor of your target number
if (num % x == 0) {
System.out.println(x + " is a factor");
// Now that we know it's a factor, let's test to see if it's prime
if (isPrime(x)) {
// If it's prime, add it to the ArrayList
System.out.println("And " + x + " is prime.");
factors.add(x);
} else {
System.out.println("But " + x + " is not prime.");
}
} else {
System.out.println(x + " is not a factor");
}
}
return factors;
}
public static boolean isPrime(double num) {
// Let's start by assuming everything is prime and try to prove that false
// If we fall through the loop without proving it false, we have a prime
boolean prime = true;
for (int x = 2; x < num; x++) {
// if our target number can be divided by any number between 1 and itself, it is not prime
if (num % x == 0) {
prime = false;
}
}
return prime;
}
}
For a start, instead of
long x = 0;
long z = 1;
while (x <= n) {
x = z * z;
z++;
}
while (j < z) {
You can just do this
z = (int) Math.Sqrt(n)
while (j <= z) {
Then for each j I would check if it divides n with no remainder.
If it divides n with no remainder, divide n by j and add j to the prime factors. Then instead of incrementing j, try the same j again, for instance for 9 you do 3 twice for its factors.
Anything more complex than that is unnecessary - you will try each j until it can divide into n no more, and you will always try primes before composites formed of those primes, so you know off the bat you'll end up with only prime factors.
OK, there are a few problems with your code:
j, x, j & n, poorly named variables make for hard work debugging.
Where are your System.out.println() calls so you can see what is going on in your code?
The square root of n would be a more optimal point to stop looking for prime up to n.
Can I suggest you look at this: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes for a rapid way of finding primes.
One suggestion to make the code simpler. In you primeFactors method, first findout is it a factor, which I believe you are already doing, then call another method to determine if this is a prime. If that is prime add to the list.
I'll give you some pseudo-code for a simple to implement (not efficient) algorithm:
the value to factorize is N
keep going until N is equal to one
start at 2 and find lowest number X that divides N evenly
X is one factor
N/X is your new N to factor
Your variable names are inconsistent. factors is particularly bad, as it is only a guess of a single factor. Call it guess instead.
The arithmetic you do with factors, primes, and dup are also strange. Why are you adding to dup or primes? Try being your own computer, and executing your algorithm for the number 12; you'll see that you don't have a correct algorithm at all.
You've foreclosed the possibility of repeated factors by incrementing factors at the end.
Related
I'm trying to write a java code that displays the prime factorization of a number in two forms: multiplied out and multiplied out with exponents. For example, the proper output would look like this:
Enter a number
100
The prime factorization of 100 is:
100 = 2 * 2 * 5 * 5
100 = 2^2 * 5^5
Except my current code only outputs this:
Enter a number
100
The prime factorization of 100 is:
100 = 2 2 5 5
Here's what my code looks like:
import java.util.Scanner;
public class Factorization {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
// user inputs variables here
System.out.println("Enter a number");
long n = keyboard.nextLong();
System.out.println("The prime factorization of " + n + " is: ");
System.out.print(n+" = ");
// solution for 1 as an input
if(n==1){
System.out.println("1");
}
// for each potential factor
for (long factor = 2; factor*factor <= n; factor++) {
// if factor is a factor of n, repeatedly divide it out
while (n % factor == 0) {
System.out.print(factor + " ");
n = n / factor;
}
}
// if biggest factor occurs only once, n > 1
if (n > 1){
System.out.println(n);
} else {
System.out.println();
}
}
}
How can I make it give the proper output?
Thank you so much!
Printing out the first form is easy, and would just require a slight modification to your code so that it would print out the *. The second form, however, is a bit more tricky as you can't just directly print out the factors as you obtain them, since you need to count how many times each one occurs to know their exponent. There are a few different ways you could do this, but I thought the simplest would be to use 2 ArrayLists. One of these ArrayLists would contain the bases, while the other would contain the exponents for each base. This is my implementation, and I added some comments for clarification.
import java.util.Scanner;
import java.util.ArrayList;
public class Factorization{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
// user inputs variables here
System.out.println("Enter a number");
long n = keyboard.nextLong();
long m = n;
System.out.println("The prime factorization of " + n + " is: ");
System.out.print(n+" = ");
ArrayList<Long> bases = new ArrayList<Long>(); //ArrayList containing each unique factor
ArrayList<Long> exponents = new ArrayList<Long>(); //ArrayList containing exponents, or the amount of times that factor is multiplied
// solution for 1 as an input
if(n==1){
System.out.println("1");
}
// for each potential factor
for (long factor = 2; factor*factor <= n; factor++) {
// if factor is a factor of n, repeatedly divide it out
while (n % factor == 0) {
n = n / factor;
if (!bases.contains(factor)){ //if the factor is not already in the bases list, it's unique and should be added
bases.add(factor);
exponents.add(1L);
}
else{ //if the factor is already in the bases list, increment its exponent by 1
exponents.set(bases.indexOf(factor), exponents.get(bases.indexOf(factor)) + 1);
}
}
}
// if biggest factor occurs only once, n > 1
if (n > 1){
if (!bases.contains(n)){
bases.add(n);
exponents.add(1L);
}
else{
exponents.set(bases.indexOf(n), exponents.get(bases.indexOf(n)) + 1);
}
}
//printing out the first form
for (int i = 0; i < bases.size(); i++)
{
for (int j = 0; j < exponents.get(i); j++) //each base is printed out an amount of times equal to its exponent
{
if (i != 0 || j != 0) //making sure we don't print * before the first base
{
System.out.print(" * ");
}
System.out.print(bases.get(i));
}
}
System.out.println();
System.out.print(m+" = ");
//printing out the second form
for (int i = 0; i < bases.size(); i++)
{
if (i >= 1) //making sure we don't print * before the first base
{
System.out.print(" * ");
}
System.out.print(bases.get(i) + "^" + exponents.get(i));
}
}
}
If you want to learn more about ArrayLists, I recommend you check out the official Java documentation on it here: https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html.
I hope this helps.
The task seems pretty easy - on input I get number of tests (numOfTests), then two numbers (downBorder, upBorder) and I have to find how many numbers between those numbers (downBorder, upBorder) are significant numbers where significant number is a number which arithmetic average of proper divisors(all divisors except one and the same number) are smaller or equal than square root of that number.
I wrote the code and probably it works however it's too slow.
My code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws java.lang.Exception
{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); //faster than Scanner
int numOfTests = Integer.parseInt(bf.readLine());
for(int i = 0; i < numOfTests; i++)
{
String[] borders = bf.readLine().split(" ");
long downBorder = Long.parseLong(borders[0]);
long upBorder = Long.parseLong(borders[1]);
//System.out.println(String.format("down: %s, up: %s", downBorder, upBorder));
System.out.println(countNumberOfSignificantNumbers(downBorder, upBorder));
}
}
/**
* print numbers of significant numbers - (arithmetic average of all divisors that is not bigger than root of that number)
* e.g 4 is significant but 6 is not
* #param downBorder
* #param upBorder
*/
private static int countNumberOfSignificantNumbers(Long downBorder, Long upBorder) {
int numberOfSignificantNumbers = 0;
for(Long i = downBorder; i <= upBorder; i++)
{
if(i%2 != 0)
continue;
else
{
double avgOfProperDivisors = getAvgArithOfSumOfNumberDividers(i);
if(avgOfProperDivisors != 0 && avgOfProperDivisors <= Math.sqrt(i))
numberOfSignificantNumbers++;
}
}
return numberOfSignificantNumbers;
}
/**
* method returns the arithemtic average of all proper divisors (all divisors except one and number itself)
* #param number
* #return
*/
public static double getAvgArithOfSumOfNumberDividers(Long number)
{
long maxD = number/2;
long sum=0;
long numOfDivs = 0;
for(long i = 2; i <= maxD; i++)
{
if(number % i == 0)
{
numOfDivs++;
sum += i;
}
}
return (numOfDivs > 0) ? (double)sum/numOfDivs : 0;
}
}
The bottleneck in this task is counting average of divisors. How can I make it better and faster?
Example input:
2
4 6
1 3
Example output:
1
0
Significant Number will always be a perfect square of a prime number like 4, 9, 25, 49, 121 etc. All you need to check is how many perfect square of a prime numbers lie between upBorder and downBorder.
You can reduce the complexity of the loop from O(number) to O(sqrt(number)).
This is based on the observation that if number is divisible by i, then it is also divisible by number/i. Given this, you can count the two divisors at once; given that the sparsity of the divisors increases as the number increases (i.e. the number of numbers you have to check before finding a divisor), you can save a lot of work in this way.
For example:
for (long i = 2; i*i <= n; ++i) {
if (n % i == 0) {
// i is a divisor, so increment the counters.
numOfDivs++; sum += i;
long c = n / i;
if (c != i) {
// c is a distinct divisor from i, so also increment the counters.
numOfDivs++; sum += c;
}
}
}
For example, 10 = 5*2. This approach finds a divisor when i=2, meaning that c=5. It can stop checking after i=3. In contrast, checking while i<=10/2 will stop checking after i=5.
As the number increases, the difference becomes far greater. For example, with number==1000, you check 499 numbers with i<=1000/2, but just 30 with i*i <= 1000.
(This is an extension from my previous question).
How to print a text notification beside prime fibonacci numbers?
Task:
The section of the assignment I am having difficulty with reads as follows:
Determine which of the first 20 Fibonacci numbers are prime numbers.
Put a “this is a prime” text notification in the printout from the Basic challenge.
Store the FibPrimes in an array called FibPrimes.
Problem:
I cannot seem to figure out how to take each individual fibonacci number, determine it is prime, put the prime fibonacci numbers in an array, and print the output. I was able to make a working program previously, but I didn't use code to calculate the primes, I manually entered them into an array (see previous attempt at bottom).
Attempt:
Here is what I have attempted:
The code that is relevant to this question is emphasized with comments.
package fibonaccinumbers;
public class FibonacciNumbers {
public static void main(String[] args) {
// Creation of Fibonacci Numbers Array.
// Let i represent the index number.
int [] FibNums = new int[20];
FibNums[0] = 0;
FibNums[1] = 1;
// Will add on each successive FibNums.
// Will be used to calculate average.
int FibSum = 1;
// RELEVANT TO QUESTION.
// Creation if Fibonacci Primes Array.
// Let n represent the index number.
int [] FibPrimes = new int[7];
int n=0;
// Printing first two fibonacci numbers.
System.out.println(0);
System.out.println(1 + "*");
// Printing remaining fibonacci numbers up to 20th term.
for (int i=2; i<FibNums.length;i++){ // Begin number generation loop.
FibNums[i] = FibNums[i-1] + FibNums[i-2];
// Checks if the fibonacci number is odd.
// A number is not odd if two divides into it evenly.
boolean oddcheck = true;
if (FibNums[i]%2==0){
oddcheck = false;
}
// RELEVANT TO QUESTION.
// A prime number can only be divided by 1 and inself.
// Divide FibNums[i] by every number inbetween.
// If a number divides evenly, it is not a prime (exception: 2).
// Else, the number is a prime.
boolean primecheck;
for (int divisor = 2; divisor < FibNums[i]/2; divisor++){
if (FibNums[i] % divisor == 0){
primecheck = false;
} else {
primecheck = true;
}
// REVELANT TO QUESTION.
// Add FibNums[i] to the FibPrimes[n] array if it is a prime.
if (primecheck == false){
FibPrimes[n] = FibNums[i];
n = n + 1;
}
// RELEVANT TO QUESTION.
// If any element in the FibPrimes array is equal to the FibNums
// array, then the number is a prime.
for (n=0; n<FibPrimes.length; n++){
if (FibNums[i] == FibPrimes[n]){
System.out.print("This is a prime." + " ");
}
}
// Prints odd fibonacci numbers with a star beside it.
// Prints even fibonacci numbers with no star beside it.
if (oddcheck == true){
System.out.println(FibNums[i] + "*");
} else {
System.out.println(FibNums[i]);
}
FibSum = FibSum + FibNums[i];
} // End number generation loop.
System.out.print ( "The average is" + " " + FibSum/20);
}
}
Output:
0
1*
The average is 0The average is 0The average is 0The average is 0This is a prime. 8
This is a prime. 8
The average is 013*
13*
13*
13*
The average is 321*
This is incorrect.
Previous Attempt:
This solution "worked", but in order to not take the "lazy route" I must do the calculations using code. Only relevant snippets are shown:
// Creation if Fibonacci Primes Array.
// Ideally, this should be caulculated.
int [] FibPrimes = new int[7];
FibPrimes[0] = 2;
FibPrimes[1] = 3;
FibPrimes[2] = 5;
FibPrimes[3] = 13;
FibPrimes[4] = 89;
FibPrimes[5] = 233;
FibPrimes[6] = 1597;
// If any element in the FibPrimes array is equal to the FibNums
// array, then the number is a prime.
for (int n=0; n<FibPrimes.length; n++){
if (FibNums[i] == FibPrimes[n]){
System.out.print("This is a prime." + " ");
}
}
Output:
0
1*
1*
This is a prime. 2
This is a prime. 3*
This is a prime. 5*
8
This is a prime. 13*
21*
34
55*
This is a prime. 89*
144
This is a prime. 233*
377*
610
987*
This is a prime. 1597*
2584
4181*
The average is 547
This is the desired output! However, I cannot use this because I must calculate the prime fibonacci numbers using code. This is the "lazy route".
Thank you.
Just 10 mins on google and you will be able to create something simple and fast.
Using the mathematical formulas below :
which you can find more one this paper you can make your prime fibonacci sequence. In addition you will need a way to check which numbers in the sequence are primes so a quick way is through AKS algorithm
Here is a full example of all the above :
public class FibonacciSequence {
public static void main(String[] args) {
for (int i = 1; i <= 20; i++) {
int num = (int) ((getY_1(i) - getY_2(i)) / Math.sqrt(5));
if (isPrime(num)) {
System.out.print("This is a prime : ");
}
System.out.println(num);
}
}
public static double getY_1(int N) {
return Math.pow((1 + Math.sqrt(5.0)) / 2.0, N);
}
public static double getY_2(int N) {
return Math.pow((1 - Math.sqrt(5.0)) / 2.0, N);
}
public static boolean isPrime(int num) {
if (num == 2 || num == 3)
return true;
if (num % 2 == 0 || num % 3 == 0) {
return false;
}
int i = 5;
int s = 2;
while (i * i <= num) {
if (num % i == 0) {
return false;
}
i += s;
s = 6 - s;
}
return true;
}
}
Of course you can exclude the value (1) if you don't feel like identifying it as a prime :P.
Output :
This is a prime : 1
This is a prime : 1
This is a prime : 2
This is a prime : 3
This is a prime : 5
8
This is a prime : 13
21
34
55
This is a prime : 89
144
This is a prime : 233
377
610
987
This is a prime : 1597
2584
4181
6765
P.S : I had free time :P
The following was the problem on codeforce
Two soldiers are playing a game. At the beginning first of them chooses a positive integer n and gives it to the second soldier. Then the second one tries to make maximum possible number of rounds. Each round consists of choosing a positive integer x > 1, such that n is divisible by x and replacing n with n / x. When n becomes equal to 1 and there is no more possible valid moves the game is over and the score of the second soldier is equal to the number of rounds he performed.
To make the game more interesting, first soldier chooses n of form a! / b! for some positive integer a and b (a ≥ b). Here by k! we denote the factorial of k that is defined as a product of all positive integers not large than k.
What is the maximum possible score of the second soldier?
Input
First line of input consists of single integer t (1 ≤ t ≤ 1 000 000) denoting number of games soldiers play.
Then follow t lines, each contains pair of integers a and b (1 ≤ b ≤ a ≤ 5 000 000) defining the value of n for a game.
Output
For each game output a maximum score that the second soldier can get.
So i tried to calculate the number of prime factors of n(as in the prime factorization of n).
Following is my my code but it fails for the test case
a=5000000 and b= 4999995
import java.util.Scanner;
import java.lang.*;
public class Main {
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int count=0;
Scanner input=new Scanner(System.in);
int testcases=input.nextInt();
for(int m=1;m<=testcases;m++){
count=0;
long a=input.nextLong();
long b=input.nextLong();
double n=1;
for(double i=b+1;i<a+1;i++)
n=n*i;
//System.out.println(Math.sqrt(n));
for(int i=2;i<Math.sqrt(n);i++){
if(n%i==0){
while(n%i==0){
n=n/i;
count++;
}
}
}
if(n!=1) count++;
System.out.println(count);
}
}
}
In your case, a! / b! is
3,124,993,750,004,374,998,750,000,120,000,000
which is somewhat larger than 2^111. Only numbers up to 2^53 can be safely represented as an integer with a double value. If you use long, you can crank that up to 2^63, which still isn't enough.
You must either use BigInteger or you must change your approach: Instead of dividing the result of a! / b! into prime factors, divide the factors that contribute to the factorial and then merge the prime factor sets.
To illustrate with your example:
5000000 == 2^6 * 5^7
4999999 == 4999999
4999998 == 2 * 3 * 191 * 4363
4999997 == 43 * 116279
4999996 == 2^2 * 1249999
a! / b! == 2^9 * 3 * 5^7 * 43 * 191 * 4363 * 116279 * 1249999 * 4999999
As the input for a and b is small, we can create an array numOfPrime, which at index ith,
numOfPrime[i] = number of prime factor of i
So, we notice that numOfPrime[i] = 1 + numOfPrime[i/x] with x is any prime factor of i.
For simplicity, let x be the smallest prime factor of i, we can use Sieve of Eratosthenes to precalculate x for each i
int[]x = new int[5000001];
for(int i = 2; i < x.length; i++)
if(x[i] == 0)
for(int j = i + i; j < x.length; j+= i)
if(x[j] == 0)
x[j] = i;
int[]numOfPrime = new int[5000001];
for(int i = 2; i < x.length; i++)
if(x[i] == 0)
numOfPrime[i] = 1;
else
numOfPrime[i] = 1 + numOfPrime[i/x[i]];
You can take a look at my submission for this problem
Based on #m-oehm's answer:
int[] factors = new int[a-b];
for(int i=0;i<a-b;i++)
factors[i] = b+1+i;
boolean done = false;
int i = 2;
while(!done){
done = true;
for(int j=0; j<a-b; j++){
if(i>Math.sqrt(factors[j]) && factors[j]!=1){ // factors[j] is prime
factors[j] = 1;
count++;
}else{
while(factors[j]%i==0){ // divide factors[j] by i as many times as you can
factors[j]/=i;
count++;
}
}
if(factors[j]!=1) // if all factors have reach 1, you're done
done = false;
}
i++;
}
I want to count the number of each prime factor of an integer. For an example 18=2^1*3^2. I want to get all exponent part of each prime number. For number 18, it is 1+2=3.Below is the program which generates all the prime factors of an integer.
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
System.out.print(i + ", ");
n /= i;
}
}
if (n > 1)
System.out.print(n + ", ");
For input 18, this program prints 2, 3, 3, . As for completing my requirement, to count the occurrence of each prime factor, i can first add them all to a list, then a for loop from starting to ending of the list can count the occurrence of each number. But this idea doesn't seem good to me. Unnecessary i am adding one for loop, for all prime factors, which just tells me that this prime factor comes n times in the list.Any better approach to get the number of individual number of prime factors of an integer.
yy, just as #attila and #robert said:
import java.util.Scanner;
import java.util.TreeMap;
public class Test{
public static void main( String args[] ){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
TreeMap<Integer, Integer> factors = new TreeMap<Integer, Integer>();
for (int i = 2; i <= n / i; i++) {
int count = 0;
while (n % i == 0) {
System.out.print(i + ", ");
n /= i;
count ++;
}
if( count > 0 )
factors.put( i, count );
}
if (n > 1){
System.out.print(n + ", ");
factors.put( n, 1 );
}
System.out.println();
System.out.println( "-------------" );
for( Integer factor : factors.keySet() ){
System.out.println( factor + "^" + factors.get( factor ) );
}
}
}
i'm using a treemap because it keeps the factors in their natural order, which is neat :)
you could also use a hashmap which should be a bit faster. but the implementation of the prime decomposition should be so slow that i don't think it matters much :)
Every time you are executing n/=i;, you are encountering a factor. So by incrementing a counter (Starting from 0) at that point, you get the total number of factors at the end of the factorization process.
Note that you need an extra if for properly handling prime numbers. For primes you do not find any factors, so the counter will be 0 -- you need to set it to 1 after the loop in this case (one factor: itself)