Failing prime factorisning program (c++) - c++

Im trying to solve this problem on programing.
Here is the question.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Now I've cooked up a c++ program, which tries to check it by brute force, however, while executing its stuck at 5. Here is the Program
#include <iostream>
#include <math.h>
using namespace std;
const long long no = 600851475143;
long long isprime(long long p)
{
long long reply = -1;
long long i = 2;
while (i < pow(p, 0.5)) {
if (i % p == 0)
reply = i;
}
if (reply == -1){
return 0;
cout<<" yup its prime "<<endl;
}
else
return reply;
}
long long factor(long long x)
{
for (long long i = 2; i < no; i++) {
cout<<"Trying "<<i<<endl;
if ((isprime(i) == 0)&& (no % i == 0)) {
return i;
cout<<"found "<<i<<endl;
break;
}
}
}
int main()
{
long long ans = no;
while (ans != 1) {
cout << factor(ans) << endl;
ans = ans / factor(ans);
}
}
and this is the output
~/Desktop/proj$ ./a.out
Trying 2
Trying 3
Trying 4
Trying 5
I really don't understand why its stuck at number 5, can someone help me out?
EDIT : Thanks b13rg , I realised my mistake . I now have a better algorithm , I have pasted it down for anybody needing it.
#include<iostream>
#include<math.h>
using namespace std;
long long fun (long long x)
{
for(long long i=2; i<sqrt(x);i++){
while (x%i==0){
cout<<i<<endl;
x=x/i;
}
}
}
int main(){
fun(600851475143);
return 0;}

You seem to never change the value of i or p in the while loop in the function isprime. It fails because sqrt(5) is larger than 2, and nothing in the while loop ever changes.
For the problem you're trying to solve:
You could first optimize the checking loop by only trying odd numbers, so first do 2, then 3, then 5 etc. To make it even faster you could hard code in the first few primes, but that might be beyond the scope of this project.
To find the largest prime factor, you would want to first find the smallest prime factor. For example, in the number above, the smallest is 5. The next step would be to divide 13195 by 5 to get 2369. Then start again to find the smallest prime factor of this number, and keep going until the dividing result is prime.
Number|Smallest prime
------|--------------
13169 | 5
2369 | 7
377 |13
29 |Largest prime factor of 13169

Related

Trying out a problem but code I had written is not giving output for large numbers. why?

I was trying this question.
The prime factors of 13195 are 5, 7, 13 and 29.What is the largest prime factor of the number 600851475143 ?
And I had written the following code:
#include<iostream>
#define num 600851475143
using namespace std;
int isprime(unsigned long long int n)
{
unsigned long long int c=0;
for(unsigned long long int i=2;i<n;i++)
{
if(n%i==0)
{
c++;
break;
}
}
if(c==0)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
unsigned long long int a,i,n=num;
while(n-- && n>1)
{
if(isprime(n)==1 && num%n==0)
{
cout<<n;
break;
}
}
return 0;
}
The problem occurring with the code is it is working for 13195 and other small values. But not getting any output for 600851475143. Can anyone explain why it is not working for large value and also tell the changes that should be made in these to get the correct output.
The below code snippets are from c (but should run quite nice with c++ as well):
#include <stdio.h>
#define uIntPrime unsigned long long int
#define uIntPrimeFormat "llu"
uIntPrime findSmallestPrimeFactor(uIntPrime num)
{
uIntPrime limit = num / 2 + 1;
for(uIntPrime i=2; i<limit; i++)
{
if((num % i) == 0)
{
return i;
}
}
return num;
}
uIntPrime findLargestPrimeFactor(uIntPrime num)
{
uIntPrime largestPrimeFactor = 1; // start with the smallest possible value
while (num > 1) {
uIntPrime primeFactor = findSmallestPrimeFactor(num);
if (primeFactor > largestPrimeFactor) largestPrimeFactor = primeFactor;
num = num / primeFactor;
}
return largestPrimeFactor;
}
How can this work?
(first function:) Counting the numbers up from 2 means you are starting with prime factors on the lower end. (Numbers that are non-prime when counting are just not working out as fraction-less divisors and at the same time their prime number factor components were already probed because they are lower.)
(second function:) If a valid factor is found then the factor is pulled out from the number in question. Thus the search for the now smallest prime in the pulled-out number can repeat. (The conditional might probably be superfluous due to lower numbers are found first anyway - but it might resemble a search pattern you are familiar with - like in a minimum/maximum/other-criteria search. I am now leaving it up to you to proof it right or wrong with testing with your own main routine.)
The stop condition is about having the last factor extracted means dividing the value by itself and getting a value of 1 for num.
(There is for sure still much space for speeding this up!)

How to code Euler #3 for any value?

/*
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{
unsigned long num = 600851475143;
unsigned long i;
long double root = sqrt(num);
long double tempRoot = 0;
unsigned long factor = 0;
unsigned long largest = 0;
for (i=2; i<root; i++)
{
if (num%i == 0)
{
num = num/i;
factor = i;
cout << factor << endl;
if (factor > largest)
{
largest = factor;
}
}
}
cout << largest << endl;
return 0;
}
This solution works because coincidentally the factors of 600851475143 are all prime numbers. But when debugging the code I was inputting various values for the variable num (=600851475143). For example, when I input 135 it showed me all the factors, including the non-prime ones. How do I add a prime number checker for the factors? I tried using the same method that I used here within a nested if, but failed miserably. Any help would be appreciated.
Also, please indicate if I am using unnecessarily large variable types in case of some variables.
Thanks.
You don't have to do a prime-number check. As you are factoring, just make sure to continue dividing out a candidate until it no longer divides the number. This is really easy to do in code: just change the if (num%i == 0) to while (num%i == 0).

Output wrong Project Euler 7

So I'm trying out Problem 7 of Project Euler.
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int a){
if (a==2||a==3){
return true;
}
if (a%2==0){
return false;
}
bool prime=true;
for (int b=2;b<sqrt(a);b++){
if (a%b==0)
prime=false;
}
if (prime==true)
return true;
else
return false;
}
int main(){
int infinite=0;
long long int primecounter=0;
for (int c=2;infinite==0;c++){
if (isPrime(c)==true){
primecounter++;
//cout<<c<<endl;
if (primecounter==10001)
{cout<<c;
break;}
}
}
return 0;}
This is what I've come up with so far. It works for the few numbers that I tested, like the 6th prime number etc. However, when I run it for the 10001st prime, it gives me 104021, and the answer is wrong. Can someone tell me what is wrong with my code?
Where you get it wrong is b < sqrt(a). Think of a=25, what happens in this case?
rest of answer already pointed by comments.
Although this is not required for this specific problem, you should take a look at Sieve of Eratosthenes algorithm. You will need it sooner or later to solve prime related problems.
You can solve it without getting help from 'cmath' too.Logic is like...
To check whether a number is prime, set a counter variable to 0; write a loop to divide the number by every number less than it till 1. If a number completely divides it, the counter will increase by one; the counetr will be exactly 2 for a prime number.
To calculate sucha big number u should choose a proper datatype too.I have used 'long long int' as a datatype.
My code for the project euler problem no 7 is as follows.Hope it helps you.Best wishes.Editions and improvements in this program are most welcome.Only bug is the time that it consumes,it takes more than an hour to reach the 10001th prime number.
#include<iostream.h>
#include<conio.h>
class prime
{
long long int a;
long long int j,i;
public:
void display();
};
void prime::display()
{
j=0;
long long int count=0;
long long int count1=0;
while(count1!=10001)
{
j=j+1;
i=j;
while(i!=0)
{
if(j%i==0)
{
count++;
}
i--;
}
if(count==2)
{
count1++;
cout<<count1<<"\t"; //The serial number of the prime number.
cout<<j<<"\t";// This will diaply all prime numbers till 10001.
}
if(count1==10001)
{
cout<<"\nThe 10001th prime number is:"<<j;
}
count=0;
}
}
void main()
{
prime k;
clrscr();
k.display();
getch();
}

Project Euler 3 - Highest Prime Factor

before I start I want to clarify that I am not looking for code examples to get the answer; that would defeat the object of Project Euler.
The problem can be found here http://projecteuler.net/problem=3
I think I have a way of solving the problem, but the Algorithm is VERY slow; it has been running for nearly two and a half hours now. So I am looking for general advice on optimisation.
Thanks.
#include<iostream>
using namespace std;
bool primality(int);
int main(){
long long lim = 600851475143;
long long div = lim/2;
bool run = true;
while(run){
if(lim%div==0 && primality(div)){
cout << "HPF: " << div;
run = false;
}
else{
div--;
}
if(div<=1){
break;
}
}
return 0;
}
bool primality(int num){
for(int i=2; i<num; i++){
if(num%i==0 && i!=num){
return false;
}
else{
return true;
}
}
}
If you start div at 2 and count up instead of down, and divide it out from the number when the modulo is zero, you gain two big advantages that are useful here:
You don't have to check if div is prime, since it can't be composite because any prime factors smaller than it would already have been divided out.
You reduce the remaining problem size every time you find a factor, and, as it turns out, the input number has fairly small prime factors.
You could then also break once div*div is greater than the remaining number, as you know at that point that it must be a prime. This is because any divisors greater than the square root are "paired" with one less than the square root. However, since this is an "easy" problem, this optimization is not needed here (although it is useful for later problems).
# Possible solution but still its *time consuming* but answer can be guessed by the last option in console output
#include<stdio.h>
#include<string>
#include<iostream>
#include<math.h>
int prime(unsigned long long);
using namespace std;
int main(){
unsigned long long ii, ij; unsigned long long in;
cin>>in; ij = ceil(in/2);
if( (ij % 2) == 0 ) ij -= 1;
for(ii = 3 ;ii < ij;ii+= 2){
if(in % ii == 0){
if(prime(ii) == 1 ){
cout<<" ans "<<ii<<endl;
}
}
}
return 0;
}
int prime(unsigned long long ii){
unsigned long long ij;
for(ij = 3;ij < ii/2 ;ij += 2){
if( (ii % ij) ==0){
return 0;
}
}
return 1;
}

Program won't run with really big numbers

I'm pretty new to programming and so I"m making this program in C++ that will take a number and find it's prime factors, which works great! Unless it's too big for an int variable. Now then I tried to change all of the int variables to long long variables so it wouldn't matter, but this doesn't seem to fix the problem. The program is as follows:
#include <iostream>
using namespace std;
bool prime (long long recievedvalue) { //starts a function that returns a boolean with parameters being a factor from a number
long long j =1;
long long remainderprime = 0;
bool ended = false;
while (ended == false){ //runs loop while primality is undetermined
if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
//not prime
return false;
break; // breaks loop
}
remainderprime=recievedvalue%j; //gives a remainder for testing
if ((remainderprime==0 && j>2) && (j!=recievedvalue || j == 4)){ //shows under which conditions it isn't prime
ended=true;
//not prime
return false;
}
else if (j==1){
j++;
}
else if ( recievedvalue==2 || j==recievedvalue ){ // shows what conditions it is prime
ended = true;
//prime
return true;
}
else {
j++;
}
}
}
long long multiple(long long tbfactor){ //factors and then checks to see if factors are prime, then adds all prime factors together
//parameter is number to be factored
long long sum = 0;
bool primetest = false;
long long remainderfact;
long long i=1;
while (i<=tbfactor){ //checks if a i is a factor of tbfactor
remainderfact=tbfactor%i;
if (remainderfact==0){ //if it is a factor it checks if it is a prime
primetest = prime(i);
}
if (primetest ==true){ //if it is prime it add that to the sum
sum += i;
primetest=false;
}
i++;
}
return sum;
}
int main()
{
long long input;
long long output;
cout << "Enter a number > 0 to find the sum of all it's prime factors: ";
cin >> input;
if (input == 0 || input <= 0){
cout << "The number you entered was too small."<< endl << "Enter number a number to find the sum of all it's prime factors: ";
cin >> input;
}
output = multiple(input);
cout << output << endl << "finished";
return 0;
}
Now then to be sure, the problem does the same thing whether or not it's a int or not. Also like I said I"m new to programming, and C for that matter so I look forward to your easily understandable replies. :)
I'm willing to be that your program IS running. I'm sure that someone is going to pop on and give you the answer in a heartbeat, but I'm hoping that it doesn't happen so that you get to experience the same thing that I did when I ran into the problem YEARS ago.
Do this: start with 1, and work up from there using powers of 2 (1, 2, 4, 8, 16, etc.) and just keep going, doubling the input number each time. When does it "stop running?" Does it get progressively slower?
Please comment back on my post or on your own, or edit your own, or post an answer, whatever it is you're allowed to do with only 56 rep. If the community will allow it (and of course I would like the community to further the lesson), I'd like to gently push you to the answer through a series of back-and-forth steps feedback rather than the typical fashion, since this is an obvious unique learning opportunity.
If you are trying to find if a number is a prime or not, here is a fast solution,
#include <iostream>
using namespace std;
#define ullong unsigned long long
bool prime (ullong x)
{
if(x <= 1)
return false;
ullong s = (ullong)sqrt(x);
for(ullong i=2;i<=s;i++)
if(x%i == 0)
return false;
return true;
}