I am attempting project euler question number 3, and I don't get the desired result. My logic:
List all the factors of the number 13195 and save them in an array.
Check if each number in the array is a prime.
If the number is found to be prime save it in an other array.
display the contents of the second array.
Hope it contains only prime factors.
RESULT: The first array contains all the factors as expected, The second I think duplicates the first array or slips in some non-primes, Please help! :)
My code:
#include <iostream>
using namespace std;
long int x,y=2;
long int number=13195;
long int f[1000000],ff[1000000];
int st=1;
int open=0;
int open2=0;
int a=0;
bool isprime;
int main()
{
for(x=1;x<=number;x++)
{
if(number%x==0)
{
f[a] = x;
a++;
}
}
while(st<=16)
{
while(y<f[st])
{
if(f[st]%y==0 && f[st]!=y)
{
break;
}
else if(f[st]%y!=0 && f[st!=y])
{
ff[open] = f[st];
}
y++;
}
open++;
st++;
}
for(open2=0;open2<open;open2++)
{
cout<<ff[open2]<<" is a prime factor of "<<number<<"\n";
}
return 0;
}
using this for finding the prime works:
while(st<=a){
int k = f[open];
for(int i=2;i<k;i++)
{
if(k%i==0)
{
isprime = false;
break;
}
else if(f[open]!=0 && f[open]%i!=0 && f[open]!=i)
{
isprime =true;
}
}
if(isprime==true)
{
ff[st] = k;
open3++;
isprime = false;
}
open++;
st++;
}
cout<<"The primes of them are "<<open3<<"."<<"\n";
cout<<"Press RETURN to show them."<<"\n";
cin.get();
for(open2=0;open2<=open3;open2++)
{
cout<<ff[open2]<<" is a prime factor of "<<number<<"."<<"\n";
}
Why You Don't Try
for(x=1;x<=number;x++)
{
if(number%x==0 && isPrime(x))
{
f[a] = x;
a++;
}
}
..
..
int isPrime(int x)
{
for(int i=2;i<=x/2;i++)
{
if(x%i==0)
return 0;
}
return 1;
}
At least:
else if(f[st]%y!=0 && f[st!=y])
should be
else if(f[st]%y!=0 && f[st]!=y)
In the first way, you are trying to always access f[0] or f[1] by doing f[st!=y].
Related
I was doing this program in which I am supossed to print gapful numbers all the way up to a specific value. The operations are correct, however, for some reason after printing a couple of values the program crashes, what can I do to fix this problem?
Here's my code:
#include<math.h>
#include<stdlib.h>
using namespace std;
void gapful(int);
bool gapCheck(int);
int main(){
int n;
cout<<"Enter a top number: ";
cin>>n;
gapful(n);
system("pause");
return 0;
}
void gapful(int og){
for(int i=0; i<=og; i++){
fflush(stdin);
if(gapCheck(i)){
cout<<i<<" ";
}
}
}
bool gapCheck(int n){
int digits=0;
int n_save,n1,n2,n3;
if(n<100){
return false;
}
else{
n_save=n;
while(n>10){
n/=10;
digits++;
}
digits++;
n=n_save;
n1=n/pow(10, digits);
n2=n%10;
n3=n1*10 + n2;
if(n%n3 == 0){
return true;
}
else{
return false;
}
}
}
I'm open to any suggestions and comments, thank you. :)
For n == 110, you compute digits == 3. Then n1 == 110 / 1000 == 0, n2 == 110 % 10 == 0, n3 == 0*10 + 0 == 0, and finally n%n3 exhibits undefined behavior by way of division by zero.
You would benefit from more functions. Breaking things down into minimal blocks of code which represent a single purpose makes debugging code much easier. You need to ask yourself, what is a gapful number. It is a number that is evenly divisible by its first and last digit. So, what do we need to solve this?
We need to know how many digits a number has.
We need to know the first digit and the last digit of the number.
So start out by creating a function to resolve those problems. Then, you would have an easier time figuring out the final solution.
#include<math.h>
#include <iostream>
using namespace std;
void gapful(int);
bool gapCheck(int);
int getDigits(int);
int digitAt(int,int);
int main(){
int n;
cout<<"Enter a top number: " << endl;
cin>>n;
gapful(n);
return 0;
}
void gapful(int og){
for(int i=1; i<=og; ++i){
if(gapCheck(i)){
cout<<i << '-' <<endl;
}
}
}
int getDigits(int number) {
int digitCount = 0;
while (number >= 10) {
++digitCount;
number /= 10;
}
return ++digitCount;
}
int digitAt(int number,int digit) {
int numOfDigits = getDigits(number);
int curDigit = 0;
if (digit >=1 && digit <= numOfDigits) { //Verify digit is in range
while (numOfDigits != digit) { //Count back to the digit requested
number /=10;
numOfDigits -=1;
}
curDigit = number%10; //Get the current digit to be returned.
} else {
throw "Digit requested is out of range!";
}
return curDigit;
}
bool gapCheck(int n){
int digitsN = getDigits(n);
if (digitsN < 3) { //Return false if less than 3 digits. Single digits do not apply and doubles result in themselves.
return false;
}
int first = digitAt(n,1) * 10; //Get the first number in the 10s place
int second = digitAt(n,digitsN); //Get the second number
int total = first + second; //Add them
return n % total == 0; //Return whether it evenly divides
}
This code is trying to check if a number is prime, I know there are more efficient methods, using sets of numbers, but I just want this to work, but I get a Segmentation fault.
If you want to test the code, it happens to me when I plug in 10000877, or any greater number.
#include <math.h>
#include <iostream>
int main () {
int prime/*???*/;
std::cout << "Please input a number: ";
std::cin >> prime;
bool isPrime = true;
int biggestFactor = ceil((prime^(1/2)));
bool odd = prime%2 == 1 ? true : false;
int multiple = 0;
int ranges[biggestFactor];
bool boolean = false;
for(int i = biggestFactor; i!=1; i--) {
ranges[i-2] = ceil(prime / i);
}
if(odd) {
for(int i = 1; i<prime; i++) {
if(multiple > biggestFactor) {
break;
} else if(boolean) {
} else if(i* ranges [multiple] > prime) {
multiple++;
} else if(i*ranges[multiple] == prime) {
isPrime = false;
break;
}
}
} else {
if(prime != 2) {
isPrime = false;
}
}
if(isPrime) {
std::cout << "That number is prime." << std::endl;
} else {
std::cout << "That number is composite." << std::endl;
}
}
Aside from noted fact that prime^(1/2) is not square root of prime, your code (even though it's wrong) sort of works. You just overestimate the square root by using prime instead (the 1/2 is converted to int which is 0 and XOR with it is itself).
It works on small numbers, I tried.
Now with the large numbers you are running out of memory here, trying to allocate 4 * 10000877 bytes
int ranges[biggestFactor];
Whenever I try to recurse in the function prime, my program crashes at that step. I think the problem is passing the function small as a recursion. What am I doing wrong?
#include <iostream>
using namespace std;
int smallest(int n) {
for( int x = 2 ; x <= n/2 ; x++){
if (n%x==0) {
return x;
}
else {
return 0;
}
}
}
int prime(int n, int(*small)(int)) {
int factor;
if (n == 1){
return 0;
}
else {
factor = n % small(n);
cout << small(n) << endl;
return prime(factor , small);
}
}
int main() {
prime(50 , &smallest);
return 0;
}
As the comments point out, when small returns 0, you continue recursing when you shouldn't. This can be solved with a small update to your base case:
if (n <= 1){
return 0 ;
}
Furthermore, it's worth pointing out that as it stands, your prime function will never call itself more than once. When you call smallest, you are guaranteed to get a prime number!
This code decomposes a number into its prime factors.
The numbers are taken from a file. The first number from the file represents the number of elements in it, the numbers are from the interval [1, 10^18].
The problem with the code is that after reading and decomposing some numbers it stops. It is intended to decompose somewhere between 100 and 1000 numbers from which at least half are bigger than 10^9.
I suspect that the stack overflows, but I am not 100% sure. I would like to hear some suggestions in order to fix this memory allocation problem.
Thank you.
#include <iostream>
#include <stdio.h>
using namespace std;
void print_recurenta(int a,int i)
{
if((a==1)||(i>a))
return;
if(a%i==0)
{
printf("%d ",i);
a=a/i;
print_recurenta(a,i);
}
else
{
i++;
print_recurenta(a,i);
}
}
void factor_printf(int nr)
{
printf("\n%ld ",nr);
int i=2;
print_recurenta(nr,i);
}
int main()
{
int numere;
int nr=0;
FILE* f=fopen("input.txt","r");
if(f==0)
return -1;
fscanf(f,"%d",&numere);
while(fscanf(f,"%d",&nr)!=EOF)
{
fscanf(f,"%d",&nr);
factor_printf(nr);
}
return 0;
}
This problem CAN be solved recursively if we look for the next factor in a loop:
void print_recurenta(__int64 a, __int64 i)
{
if (a == 1)
return;
if (i*i > a)
{
printf("%llu ", a);
return;
}
if (a%i == 0)
{
printf("%llu ", i);
a = a / i;
}
else
{
for (++i; i*i < a && (a%i != 0); ++i)
;
}
print_recurenta(a, i);
}
I'm trying to print all the prime numbers in series, the code I ended up with is below, instead of printing all primes it prints random numbers, Some are prime and some are not :/
Why is that so?
#include <iostream>
using namespace std;
long int x,y=3;
int a=3;
bool isprime;
int main()
{
while(a<=100)
{
for(x=2;x<=y;x++)
{
if(y%x==0 && x!=y)
{
isprime=false;
break;
}
else if(y%x!=0 && x!=y)
{
isprime = true;
}
}
if(isprime==true && y%x!=0 && x!=y)
{
cout<<a<<" is a prime number."<<"\n";
isprime=false;
}
a++;
y++;
}
}
This
if(isprime=true && a%x!=0 && a!=y)
should be this
if(isprime==true && a%x!=0 && a!=y)
That's a common mistake. But even better is to realise that you don't need to compare bools against true of false, because they are true or false. So just
if (isprime && a%x!=0 && a!=y)
The logic just looks all wrong (and way too complicated), try this
isprime = true;
for(x=2;x<a;x++)
{
if(a%x==0)
{
isprime = false;
break;
}
}
if (isprime)
{
cout<<a<<"\n";
}
No need for y.
Well what jumps into my eyes is that you never increment y.
y is 3 in the beginning, so you only try if 2 is a possible divisor of a and then go to the next a.
Anyway, I am not sure what you wanted to achieve with y.
Let x run from 2 to a/2, as there is no need to try numbers bigger than a/2.
This is simply because there never will be a divisor bigger than a/2.
Example: a = 30. It would not make sense to try to divide by 16 or bigger, as the result can never be a integer (besides a itself of course)
However, this should do what you want:
int x = 0;
int a = 0;
bool isPrime = false;
for(a=3; a < 100; a+=2)
{
isPrime = true;
for(x = 2; x <= a/2; x++) {
if(a%x == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
cout << a << "\n";
}
}
there are of course other algorithms that can find primes, but I wanted to use your approach basically.
Cheers
Chris
EDIT:
Someone was faster :)
anyway: there is no need to run higher than a/2, this is a important optimization...!
EDIT2:
another optimization is of course skipping all even numbers, so start with a = 3 and increment by 2 for each loop iteration...
I see your code is ok now.
Nevertheless I made small changes, cleaning the code and making it a little bit faster.
#include <iostream>
using namespace std;
long int x, y = 2;
int a = 3;
bool isprime;
int main() {
while (a <= 100) {
while ((y + 1) * (y + 1) <= a) {
y++;
}
isprime = true;
for (x = 3; x <= y; x += 2) {
if (a % x == 0) {
isprime = false;
break;
}
}
if (isprime) {
cout << a << " is a prime number." << "\n";
}
a+=2;
}
}