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";
}
}
Related
So far I have this code. I'm trying to print prime factorization with exponents. For example, if my input is 20, the output should be 2^2, 5
#include <iostream>
#include <cmath>
using namespace std;
void get_divisors (int n);
bool prime( int n);
int main(int argc, char** argv) {
int n = 0 ;
cout << "Enter a number and press Enter: ";
cin >>n;
cout << " Number n is " << n << endl;
get_divisors(n);
cout << endl;
return 0;
}
void get_divisors(int n){
double sqrt_of_n = sqrt(n);
for (int i =2; i <= sqrt_of_n; ++i){
if (prime (i)){
if (n % i == 0){
cout << i << ", ";
get_divisors(n / i);
return;
}
}
}
cout << n;
}
bool prime (int n){
double sqrt_of_n = sqrt (n);
for (int i = 2; i <= sqrt_of_n; ++i){
if ( n % i == 0) return 0;
}
return 1;
}
I hope someone can help me with this.
You can use an std::unordered_map<int, int> to store two numbers (x and n for x^n). Basically, factorize the number normally by looping through prime numbers smaller than the number itself, dividing the number by the each prime as many times as possible, and recording each prime you divide by. Each time you divide by a prime number p, increment the counter at map[p].
I've put together a sample implementation, from some old code I had. It asks for a number and factorizes it, displaying everything in x^n.
#include <iostream>
#include <unordered_map>
#include <cmath>
bool isPrime(const int& x) {
if (x < 3 || x % 2 == 0) {
return x == 2;
} else {
for (int i = 3; i < (int) (std::pow(x, 0.5) + 2); i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
}
std::unordered_map<int, int> prime_factorize(const int &x) {
int currentX = abs(x);
if (isPrime(currentX) || currentX < 4) {
return {{currentX, 1}};
}
std::unordered_map<int, int> primeFactors = {};
while (currentX % 2 == 0) {
if (primeFactors.find(2) != primeFactors.end()) {
primeFactors[2]++;
} else {
primeFactors[2] = 1;
}
currentX /= 2;
}
for (int i = 3; i <= currentX; i += 2) {
if (isPrime(i)) {
while (currentX % i == 0) {
if (primeFactors.find(i) != primeFactors.end()) {
primeFactors[i]++;
} else {
primeFactors[i] = 1;
}
currentX /= i;
}
}
}
return primeFactors;
}
int main() {
int x;
std::cout << "Enter a number: ";
std::cin >> x;
auto factors = prime_factorize(x);
std::cout << x << " = ";
for (auto p : factors) {
std::cout << "(" << p.first << " ^ " << p.second << ")";
}
}
Sample output:
Enter a number: 1238
1238 = (619 ^ 1)(2 ^ 1)
To begin with, avoid using namespace std at the top of your program. Second, don't use function declarations when you can put your definitions before the use of those functions (but this may be a matter of preference).
When finding primes, I'd divide the number by 2, then by 3, and so on. I can also try with 4, but I'll never be able to divide by 4 if 2 was a divisor, so non primes are automatically skipped.
This is a possible solution:
#include <iostream>
int main(void)
{
int n = 3 * 5 * 5 * 262417;
bool first = true;
int i = 2;
int count = 0;
while (i > 1) {
if (n % i == 0) {
n /= i;
++count;
}
else {
if (count > 0) {
if (!first)
std::cout << ", ";
std::cout << i;
if (count > 1)
std::cout << "^" << count;
first = false;
count = 0;
}
i++;
if (i * i > n)
i = n;
}
}
std::cout << "\n";
return 0;
}
Note the i * i > n which is an alternative to the sqrt() you are using.
I'm trying to get all prime numbers in the range of 2 and the entered value using this c++ code :
#include<iostream>
using namespace std;
int main() {
int num = 0;
int result = 0;
cin >> num;
for (int i = 2; i <= num; i++) {
for (int b = 2; b <= num; b++) {
result = i % b;
if (result == 0) {
result = b;
break;
}
}
cout << result<< endl <<;
}
}
the problem is that I think am getting close to the logic, but those threes and twos keep showing up between the prime numbers. What am I doing wrong?
I've fixed your code and added comments where I did the changes
The key here is to understand that you need to check all the numbers smaller then "i" if one of them dividing "i", if so mark the number as not prime and break (the break is only optimization)
Then print only those who passed the "test" (originally you printed everything)
#include <iostream>
using namespace std;
#include<iostream>
using namespace std;
int main()
{
int num = 0;
int result = 0;
cin >> num;
for (int i = 2; i <= num; i++) {
bool isPrime = true; // Assume the number is prime
for (int b = 2; b < i; b++) { // Run only till "i-1" not "num"
result = i % b;
if (result == 0) {
isPrime = false; // if found some dividor, number nut prime
break;
}
}
if (isPrime) // print only primes
cout << i << endl;
}
}
Many answers have been given which explains how to do it. None have answered the question:
What am I doing wrong?
So I'll give that a try.
#include<iostream>
using namespace std;
int main() {
int num = 0;
int result = 0;
cin >> num;
for (int i = 2; i <= num; i++) {
for (int b = 2; b <= num; b++) { // wrong: use b < i instead of b <= num
result = i % b;
if (result == 0) {
result = b; // wrong: why assign result the value of b?
// just remove this line
break;
}
}
cout << result<< endl <<; // wrong: you need a if-condtion before you print
// if (result != 0) cout << i << endl;
}
}
You have multiple errors in your code.
Simplest algorithm (not the most optimal though) is for checking whether N is prim is just to check whether it doesn't have any dividers in range [2; N-1].
Here is working version:
int main() {
int num = 0;
cin >> num;
for (int i = 2; i <= num; i++) {
bool bIsPrime = true;
for (int b = 2; bIsPrime && b < i; b++) {
if (i % b == 0) {
bIsPrime = false;
}
}
if (bIsPrime) {
cout << i << endl;
}
}
}
I would suggest pulling out the logic of determining whether a number is a prime to a separate function, call the function from main and then create output accordingly.
// Declare the function
bool is_prime(int num);
Then, simplify the for loop to:
for (int i = 2; i <= num; i++) {
if ( is_prime(i) )
{
cout << i << " is a prime.\n";
}
}
And then implement is_prime:
bool is_prime(int num)
{
// If the number is even, return true if the number is 2 else false.
if ( num % 2 == 0 )
{
return (num == 2);
}
int stopAt = (int)sqrt(num);
// Start the number to divide by with 3 and increment it by 2.
for (int b = 3; b <= stopAt; b += 2)
{
// If the given number is divisible by b, it is not a prime
if ( num % b == 0 )
{
return false;
}
}
// The given number is not divisible by any of the numbers up to
// sqrt(num). It is a prime
return true;
}
I can pretty much guess its academic task :)
So here the think for prime numbers there are many methods to "get primes bf number" some are better some worse.
Erosthenes Sieve - is one of them, its pretty simple concept, but quite a bit more efficient in case of big numbers (like few milions), since OopsUser version is correct you can try and see for yourself what version is better
void main() {
int upperBound;
cin >> upperBound;
int upperBoundSquareRoot = (int)sqrt((double)upperBound);
bool *isComposite = new bool[upperBound + 1]; // create table
memset(isComposite, 0, sizeof(bool) * (upperBound + 1)); // set all to 0
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) { // if not prime
cout << m << " ";
for (int k = m * m; k <= upperBound; k += m) // set all multiplies
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++) // print results
if (!isComposite[m])
cout << m << " ";
delete [] isComposite; // clean table
}
Small note, tho i took simple implementation code for Sive from here (writing this note so its not illegal, truth be told wanted to show its easy to find)
What is the sum of all the primes below 2000000?
Example of sum below 10 is 2+3+5+7 = 17
I wrote this code, but still getting the wrong answers:
I tested for numbers lower than a few hundreds, and it has shown the correct answers.
#include <iostream>
#include <math.h>
using namespace std;
bool isPrime(long n)
{
if (n < 2)
return false;
if (n == 2)
return true;
if (n == 3)
return true;
int k = 3;
int z = (int)(sqrt(n) + 1); // square root the n, because one of the product must be lower than 6, if squared root of 36
if (n % 2 == 0)
return false;
while (n % k != 0)
{
k += 2;
if (k >= z)
return true;
}
return false;
}
long primeSumBelow(long x)
{
long long total = 0;
for (int i = 0; i < x; i++) // looping for times of prime appearing
{
if (isPrime(i) == true)
total += i;
if (isPrime(i) == false)
total += 0;
}
cout << "fd" << endl;
return total;
}
int main()
{
cout << primeSumBelow(20) << endl;
cout << primeSumBelow(2000000) << endl;
system("pause");
return 0;
}
The total counter's type is correctly long long. Unfortunately the function primeSumBelow returns only long so, depending on the platform, the correctly calculated result is truncated when it's returned from this function.
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.
I'm writing a code that will (hopefully) allow the user to input a number, and which will output the sum of the prime numbers between 2 and that number (inclusive). I'm getting one problem, however, on the penultimate line of the code. I've looked up other solutions to this question, but they don't seem to be caused by the same error as mine. Here's the code:
#include <iostream>
using namespace std;
int Q;
int sum_primes(int N) {
cout << "Enter a number and I will generate the sums of the primes up to (and including) that number: ";
cin >> Q;
int i, count, sum = 0;
for(N = 1; N <= Q; N++) {
count = 0;
for(i = 2; i <= N/2; i++) {
if (N % i == 0) {
count++;
break;
}
}
if (count == 0 && N != 1)
sum = sum + N;
return N = sum;
}
}
int main() {
cout << "The sum of these primes is: " << sum_primes(int N);
return 0;
}
cout << "..." << sum_primes(int N);
Replace int N with a number. You already defined the function, now you need to give it a parameter.
Or maybe you wanted to give N's value through user input. Then use this instead:
int N;
cin >> N;
cout << "The sum of these primes is: " << sum_primes(N);
Also, as GigaWatt pointed out, the line on which you did:
return N = sum;
is unnecessary. Simply returning sum will work just as well.
Here's the complete code:
#include <iostream>
#include <cmath>
bool isPrime(int x) {
if (x == 1) return false;
if (x == 2) return true;
bool prime = true;
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) { prime = false; break; }
}
return prime;
}
int sum_primes(unsigned int N) {
int sum = 0;
for ( int i = 1; i <= N; i++ ) {
if (isPrime(i)) sum += i;
}
return sum == 0 ? 1 : sum;
}
int main() {
int Q;
std::cin >> Q;
std::cout << "Sum of primes " << sum_primes(Q);
}
There are in fact multiple issues with this code. I'll list a few, but this is by no means exhaustive!
You've got some slightly crazy structuring of your code there. I guess this will become apparent when you fix the simple syntax error. Just as a point of style, I'd pass in Q as an argument to sum_primes as well as N.
You're outputting "The sum of these primes is" before asking "Enter a number".
return N = sum will exit your outer for-loop immediately. This is almost certainly not what you wanted.
I suspect you'll need to hunt down a better instroduction to C++ than you're currently working from. I'm afraid I can't offer you any advice with that.
Your argument to sum_primes is incorrect.
The function is defined to take an int, but you're not passing it one.