I'm trying to write a function that would return a prime factorisation of a given number (as part of solving project euler's problem #12). To count the prime factors. I use std::map.
The code is as follows:
#include "stdafx.h"
#include <iostream>
#include <map>
#include <algorithm>
bool IsPrime(unsigned int number)
{
if (number < 1) return 0; // zero is not prime. For our purposes, one would be.
for (unsigned int i = 2; i*i <= number; ++i)
{
if (number % i == 0)
return false;
}
return true;
}
int divisors(unsigned int num)
{
int orig_num = num;
std::map <int, int> primefactors;
for(unsigned int i = 1; i <= num; ++i)
if (num % i == 0 && IsPrime(i))
{
num /= i;
++primefactors[i];
std::cout << primefactors[i] << "\t";
}
std::cout << orig_num << " = ";
for(auto& iter:primefactors)
std::cout << iter.first << "^" << iter.second << " * ";
return 0;
}
int main()
{
divisors(661500);
return 0;
}
The problem is that all the counts of primefactors are returned as 1s, although the number in main was chosen specifically to be a product of primes to larger than 1 powers (661500 = 1^1*2^2*3^3*5^3*7^2).
My guess is that I'm incrementing something wrong.
You are dividing only once per prime. But you should continue dividing by the prime as long as number is divisible by it:
for(unsigned int i = 2; i <= num; ++i)
if (IsPrime(i))
{
while (num % i == 0) {
num /= i;
++primefactors[i];
std::cout << primefactors[i] << "\t";
}
}
Actually there is no need for IsPrime(i) condition:
for(unsigned int i = 2; i <= num; ++i)
while (num % i == 0) {
num /= i;
++primefactors[i];
std::cout << primefactors[i] << "\t";
}
Proof: if i is not a prime, then condition num % i == 0 implies that num is divisible by a prime factor p of i. But p < i so our loop had to go through p some time before i. And while loop would effectively erase all occurences of p in num. In particular by the time that for reaches i we have that num is no longer divisible by p. Contradiction. I.e. in the loop above if num % i == 0 is satisfied, then i is prime.
Related
Write a function int fact(int n) which displays the factors of the integer n, and returns the number of factors. Call this function in main() with user input
#include<iostream>
using namespace std;
int fact(int n);
int main() {
int n,factor;
cout << "Enter an integer : ";
cin >> n;
factor = fact(n);
cout << factor;
return 0;
}
int fact(int n)
{
for (int i = 1; i <= n; ++i)
{
if (n % i == 0)
cout << i << endl;
}
return 0;
}
If I enter 7, I get 1,7,0 . How do i remove this 0 and how do i find the number of factors?
You should count in your int fact() function. Set a variable to 0 and increment each time you currently display i. Then at the end of the function instead of returning 0 return the count variable.
int fact(int n)
{
int count=0;
for (int i = 1; i <= n; ++i)
{
if (n % i == 0) {
cout << i << endl;
count++;
}
}
return count;
}
The key part is "and returns the number of factors". You don't do that. Keep a count of the factors:
int fact(int n)
{
int count = 0;
for (int i = 1; i <= n; ++i)
{
if (n % i == 0)
{
// found a factor, add to the count
count++;
cout << i << endl;
}
}
// return the count instead
return count;
}
Then, your main function can use that count:
factor = fact(n); // fact(n) will already print the factors
// now just print the number
cout << "Number of factors: " << factor << '\n';
#include <iostream>
#include <vector>
std::vector<int> fact(int n);
int main() {
int n;
std::cout << "Number: ";
std::cin >> n;
std::vector<int> factors = fact(n);
for (auto i : factors) {
std::cout << i << ' ';
}
std::cout << '\n';
std::cout << "Number of factors: " << factors.size() << '\n';
return 0;
}
std::vector<int> fact(int n) {
std::vector<int> vec{1};
for (int i = 2; i <= n / 2; ++i) {
if (n % i == 0) {
vec.push_back(i);
}
}
vec.push_back(n);
return vec;
}
If you're going to return anything from fact(), it should be the factors. To do so, I am using a std::vector. It is an array that can grow on demand. The numbers 1 and n are always factors, so I don't bother doing the math for them. The vector is initialized already holding the value 1, and I only calculate numbers up to and including half of n (Anything greater than n/2 won't divide evenly, so my loop is finished about half as fast by recognizing the actual range). I then just add n to the vector, which I return.
My main prints the vector, and the vector knows its own size, which is the number of factors.
Alternatively, you can just keep a count in your fact() function.
#include <iostream>
#include <vector>
// Prints factors of n and returns the number of factors
int fact(int n);
int main() {
int n;
std::cout << "Number: ";
std::cin >> n;
int numFactors = fact(n);
std::cout << "Number of factors: " << numFactors << '\n';
return 0;
}
int fact(int n) {
int factorCount = 2; // Already counting 1 and n
std::cout << "1 ";
for (int i = 2; i <= n / 2; ++i) {
if (n % i == 0) {
std::cout << i << ' ';
++factorCount;
}
}
std::cout << n << '\n';
return factorCount;
}
The main problem with your code is that your function always returns zero. You need to keep a count of factors and return it.
Besides that your code performance badly as the loop goes on much longer than needed. You can use the square root of n as the limit in the for loop. Like:
int fact(int n)
{
if (n < 1) return 0;
int res = 0;
int limit = sqrt(n);
for (int i = 1; i <= limit; ++i)
{
if (n % i == 0)
{
res += 2;
cout << i << " - " << n/i << endl;
}
}
if (limit * limit == n)
{
--res;
}
return res;
}
For n = 36 the output is:
1 - 36
2 - 18
3 - 12
4 - 9
6 - 6
and the returned value is 9
Below is another approach. It doesn't use square root. Instead it keeps the number of loops low by using the square of i as loop limit.
int fact(int n)
{
if (n < 1) return 0;
int res = 0;
int i = 1;
int i_square = i * i;
while (i_square < n)
{
if (n % i == 0)
{
res += 2;
cout << i << " - " << n/i << endl;
}
++i;
i_square = i * i;
}
if (i_square == n)
{
++res;
cout << i << " - " << n/i << endl;
}
return res;
}
Fact() always returns 0 so this line print 0
cout << factor;
for the number of factors you can change the return value of fact() :
int fact(int n)
{
int nb = 0;
for (int i = 1; i <= n; ++i)
{
if (n % i == 0) {
cout << i << endl;
nb++;
}
}
return nb;
}
I'm trying to create a function for an assignment that finds the two prime numbers that add up to the given sum. The instructions ask
"Write a C++ program to investigate the conjecture by listing all the even numbers from 4 to 100,000 along
with two primes which add to the same number.
Br sure you program the case where you find an even number that cannot be expressed as the sum of two
primes (even though this should not occur!). An appropriate message to display would be “Conjecture
fails!” You can test this code by seeing if all integers between 4 and 100,000 can be expressed as the sum
of two primes. There should be lots of failures."
I have created and tested the "showPrimePair" function before modifying it to integrate it into the main program, but now I run into this specific error
"C4715 'showPrimePair': not all control paths return a value"
I have already done my research to try to fix the error but it still
remains.
#include <iostream>
#include <stdio.h>
//#include <string> // new
//#include <vector> //new
//#include <algorithm>
using namespace std;
bool isPrime(int n);
//bool showPrimePair(int x);
//vector <int> primes; //new
const int MAX = 100000;
//// Sieve Sundaram function // new
//
//void sieveSundaram()
//{
// bool marked[MAX / 2 + 100] = { 0 };
// for (int i = 1; i <= (sqrt(MAX) - 1) / 2; i++)
// for (int j = (i * (i + 1)) << 1; j <= MAX / 2; j = j + 2 * i + 1)
// marked[j] = true;
//
// primes.push_back(2);
// for (int i = 1; i <= MAX / 2; i++)
// if (marked[i] == false)
// primes.push_back(2 * i + 1);
//}
// Function checks if number is prime //links to showPrimePair
bool isPrime(int n) {
bool prime = true;
for (int i = 2; i <= n / 2; i++)
{
if (n % i == 0) // condition for nonprime number
{
prime = false;
break;
}
}
return prime;
}
// Function for showing prime pairs ( in progress) Integer as a Sum of Two Prime Numbers
bool showPrimePair(int n) {
bool foundPair = true;
for (int i = 2; i <= n / 2; ++i)
// condition for i to be a prime number
{
if (isPrime(i) == 1)
{
// condition for n-i to be a prime number
if (isPrime(n - i) == 1)
{
// n = primeNumber1 + primeNumber2
printf("%d = %d + %d\n", n, i, n - i);
foundPair = true;
break;
}
}
}
if (foundPair == false) {
cout << " Conjecture fails!" << endl;
return 0;
}
}
// Main program in listing conjectures for all even numbers from 4-100,000 along q/ 2 primes that add up to same number.
int main()
{
//sieveSundaram();
cout << "Goldbach's Conjecture by Tony Pham " << endl;
for (int x = 2; x <= MAX; x++) {
/*if (isPrime(x) == true) { //works
cout << x << " is a prime number " << endl;
}
else {
cout << x << " is not a prime number " << endl;
}*/
showPrimePair(x);
}
cout << "Enter any character to quit: ";
cin.get();
}
First you can find all prime numbers in the desired range using the Sieve of Eratosthenes algorithm. Next, you can insert all found primes into a hash set. Finally for each number n in the range you can try all primes p that don't exceed n/2, and probe if the n-p is also a prime (as long as you have a hash set this operation is very fast).
Here is an implementation of Dmitry Kuzminov's answer. It takes a minute to run but it does finish within a reasonable time period. (Also, my implementation skips to the next number if a solution is found, but there are multiple solutions for each number. Finding every solution for each number simply takes WAAAAY too long.)
#include <iostream>
#include <vector>
#include <unordered_set>
std::unordered_set<long long> sieve(long long max) {
auto arr = new long long[max];
std::unordered_set<long long> ret;
for (long long i = 2; i < max; i++) {
for (long long j = i * i; j < max; j+=i) {
*(arr + (j - 1)) = 1;
}
}
for (long long i = 1; i < max; i++) {
if (*(arr + (i - 1)) == 0)
ret.emplace(i);
}
delete[] arr;
return ret;
}
bool is_prime(long long n) {
for(long long i = 2; i <= n / 2; ++i) {
if(n % i == 0) {
return false;
}
}
return true;
}
int main() {
auto primes = sieve(100000);
for (long long n = 4; n <= 100000; n+=2) {
bool found = false;
for (auto prime : primes) {
if (prime <= n / 2) {
if (is_prime(n - prime)) {
std::cout << prime << " + " << n - prime << " = " << n << std::endl;
found = true;
break; // Will move onto the next number after it finds a result
}
}
}
if (!found) { // Replace with whatever code you'd like.
std::terminate();
}
}
}
EDIT: Remember to use delete[] and clean up after ourselves.
I am attempting to implement a program that reads a positive integer from the user and outputs all the perfect numbers between 2 and userNum. It also outputs all the pairs of amicable numbers that are between 2 and userNum. Both numbers must be within the range. I am seriously struggling with this.
Requirements:
1) calls to AnalyzeDivisors must be kept to theta(userNum) times all together. 2) Function void AnalyzeDivisors must take the following arguments int num, int& outCountDivs, int& outSumDivs. 3) Function bool IsPerfect must take the following argument int num.
I am honestly at a loss for how to do this within that efficiency range. I currently am able to determine all the perfect numbers in the range by bending the rules as far as parameters to the IsPerfect Function, but how can I determine amicable pairs without calling Analyze Dividors an inordinate amount of times each iteration of the for loop in main?
Any help would be greatly appreciated! Code below:
main
int main()
{
int userNum;
//Request number input from the user
cout << "Please input a positive integer num (>= 2): " << endl;
cin >> userNum;
for (int counter = 2; counter <= userNum; counter++)
{
//Set variables
int outCountDivs = 0, outSumDivs = 0, otherAmicablePair = 0;
bool perfectNum = false, isAmicablePair = false;
//Analyze dividors
AnalyzeDividors(counter, outCountDivs, outSumDivs);
//determine perfect num
perfectNum = IsPerfect(counter, outSumDivs);
if (perfectNum)
cout << endl << counter << IS_PERFECT_NUM;
}
return 0;
}
AnalyzeDividors
void AnalyzeDividors(int num, int& outCountDivs, int& outSumDivs)
{
int divisorCounter;
for (divisorCounter = 1; divisorCounter <= sqrt(num); divisorCounter++)
{
if (num % divisorCounter == 0 && num / divisorCounter != divisorCounter && num / divisorCounter != num)
{
//both counter and num/divisorCounter
outSumDivs += divisorCounter + (num / divisorCounter);
outCountDivs += 2;
}
else if ((num % divisorCounter == 0 && num / divisorCounter == divisorCounter) || num/divisorCounter == num)
{
//Just divisorCounter
outSumDivs += divisorCounter;
outCountDivs += 1;
}
}
}
IsPerfect
bool IsPerfect(int userNum, int outSumDivs)
{
if (userNum == outSumDivs)
return true;
else
return false;
}
I think I found a solution that fits the requirements. I found amicable numbers by storing every number and sum of divisors in a map. If a number's sum of divisors is entered in the map, and the sum of divisor's sum of divisors was the current number, then they are amicable.
Because the results are saved each time, you only call AnalyzeDivisors once per number.
Pardon the lazy variable naming.
#include <iostream>
#include <map>
#include <cmath>
void AnalyzeDivisors(int num, int& divc, int &divs)
{
divc = 1;
divs = 1;
for (int x = 2, y = std::sqrt(num); x <= y; ++x)
{
if (num % x == 0)
{
++divc;
divs += x;
if (num / x != x)
{
++divc;
divs += num / x;
}
}
}
}
bool IsPerfect(int num)
{
static std::map<int, int> amicable;
int divc = 0, divs = 0;
AnalyzeDivisors(num, divc, divs);
if (amicable.find(divs) != amicable.end() && amicable[divs] == num)
std::cout << num << " and " << divs << " are best bros for life.\n";
amicable[num] = divs;
return num == divs;
}
int main()
{
int num;
std::cout << "Pick a number: ";
std::cin >> num;
for (int x = 2; x < num; ++x)
{
if (IsPerfect(x))
std::cout << x << " is perfect in every way!\n";
}
}
I need to create a c++ program which displays all the prime numbers less than or equal to an inputted value. The catch is (and the part I can't seem to do) is that I have to use two functions to do so, and I cannot output the values within the same function that determines if they are prime or not. Below are two programs, the first is a program which does not work, this is as far as I got through trial and error after realizing that the second program does not meet the requirements. The second program works, but does not fulfill the requirements stated above. Thank you in advance, this has been driving me bonkers.
First:
bool is_Prime(int);
#include <iostream>
using namespace std;
int main() {
int m, n;
n = 2;
cout << "Your input: ";
cin >> m;
cout << "The prime numbers less than or equal to " << m << " are:" << endl;
while ( n <= m)
{
is_Prime(m);
if (true) {
cout << n << endl;
}
n++;
}
return 0;
}
bool is_Prime(int m) {
for (int n = 1; n < m; n++) {
bool prime = true;
for (int x = 2; x*x <= m; x++) {
if (m % x == 0) {
prime = false;
}
}
if (prime = true)
{
return true;
}
}
}
Second:
bool is_Prime(int m);
#include <iostream>
using namespace std;
int main() {
int m;
cout << "Your input: ";
cin >> m;
cout << "The prime numbers less than or equal to " << m << " are:" << endl;
is_Prime(m);
return 0;
}
bool is_Prime(int m) {
for (int n = 1; n < m; n++) {
bool prime = true;
for (int x = 2; x*x <= n; x++) {
if (n % x == 0) {
prime = false;
}
}
if (prime)
cout << n << " " << endl;
}
return 0;
}
So, the problem is that following function prints the numbers itself.
bool is_Prime(int m) {
for (int n = 1; n < m; n++) {
bool prime = true;
for (int x = 2; x*x <= n; x++) {
if (n % x == 0) {
prime = false;
}
}
if (prime)
cout << n << " " << endl;
}
return 0;
}
Solution one:
Modify the function so that it only checks one given number if it is a prime, and in main, make a loop from 1 up to the max number, call is_prime for each numer, and print the number if the function returns true.
bool is_Prime(int p) {
for (int x = 2; x*x <= p; x++) {
if (p % x == 0) {
return false;
}
}
return true;
}
...
//in main:
for(int p = 1; p < m; p++)
{
if(is_prime(p))
cout << p << endl;
}
Solution two (better):
Make another variable in the function, eg. a std::vector<int> v;, and instead of printing found primes, add them to the vector with v.push_back(n);. The return the whole vector (after all numbers are checked). In main, just print every number contained in the vector. This enables you to use better algorithms in the function (because one call checks all numbers), like sieve approaches, to make everything faster.
There are quite a few errors in your second attempt (labeled as first).
is_Prime(m);
This is constantly checking the one number, not all of the numbers less than m, replace m with n.
if (true) {
This will always be executed. Either store the return value of is_Prime, or call it directly in the if statement.
if (prime = true)
This will set prime to true and then test prime. You want ==.
You don't return false at the end of is_Prime
for (int n = 1; n < m; n++) {
This isn't necessary in the is_Prime function as you have the while loop in the outside function.
I'm trying to modify this program to their equivalent iterative but it becomes very difficult to me because as yet i'm still a newbie, it comes to an algorithm that decomposes a number into its prime factors, here the code:
#include <iostream>
#include <map>
#include <cmath>
std::map< int, std::pair<int, int> > decompositions;
void descompon_number(int num, int root, int i = 2 )
{
auto iterator = decompositions.find(num);
if (iterator == decompositions.end())
{
if (num > 1 && i <= root)
{
if (num % i == 0)
{
int n = num / i;
decompositions[num] = std::make_pair(i, n);
descompon_number(n, (int) std::sqrt(n));
}
else
descompon_number(num, root, i + 1);
}
else
decompositions[num] = std::make_pair(num, 1);
}
}
void show(int num, int factor, int exponent, int see)
{
auto pair = decompositions[num];
if (num <= 1 || factor != pair.first)
{
if (see)
std::cout << factor;
if (exponent > 1 && see)
std::cout << "^" << exponent;
if (pair.first > 1 && see)
std::cout << " * ";
exponent = 0;
}
if (num > 1)
show(pair.second, pair.first, exponent + 1, see);
}
void descompon(int a, int b, int see)
{
if (a <= b)
{
descompon_number(a, (int) std::sqrt(a));
if (see)
std::cout << a << " = ";
show(a, decompositions[a].first, 0, see);
if (see)
std::cout << std::endl;
descompon(a + 1, b, see);
}
}
int main()
{
descompon(2, 100, 1);
return 0;
}
Someone can help me out with this
Finding prime factors iteratively is not very complicated.
Here's the pseudocode how to do this.
Let P be a list of the first n prime numbers, such that Pn <= sqrt(m).
array findPrimeFactors(m)
answer = new array
for p in P
while m can be divided by p
m = m / p
answer.append(p)
if m == 1
break
return answer
Note: empty array is returned if m is prime.
You can use an erastotenes' sieve to compute prime numbers, and later you can use the algorithm posted by popovitsj.
The following code can be optimized, but its main purpose is to show you how to proceed.
Complete example:
#include <iostream>
#include <vector>
using namespace std;
// Returns a vector containing the first <number> prime numbers
vector<int> erastotenes_sieve(int number)
{
vector<int> result;
int *sieve = new int[number];
for (int i = 0; i < number; i++) sieve[i] = 0;
// Traverse the sieve marking multiples.
for (int i = 2; i < number / 2; i++)
for (int j = i + i; j < number; j += i)
sieve[j] = 1;
// Collect unaffected indexes, those are prime numbers.
for (int i = 2; i < number; i++)
if (!sieve[i])
result.push_back(i);
delete [] sieve;
return result;
}
vector<int> descompon_number(int number)
{
vector<int> result;
if (number == 1 || number == 0)
{
result.push_back(number);
return result;
}
for (int &prime : erastotenes_sieve(number))
{
while (number % prime == 0 && number != 1)
{
number /= prime;
result.push_back(prime);
}
}
return result;
}
int main()
{
for (auto &i : descompon_number(20))
{
cout << i << endl;
}
return 0;
}