Prime Factorization of First 1000 Numbers in C++ - c++

I need to write a program that could find the sums of the prime factors of the first 1000 numbers, check if the sums are prime, and print them if they are.
I have some pseudo-code I've written and I have a working program for generating prime numbers that I'm trying to expand off of. I'm learning from the book "Jumping into C++," by the way (it's a Practice Problem in the book).
This is the pseudo-code:
// for every 1000 of the first bunch of numbers, check if the number is prime
// if (number isPrime())
// use expression <number_being_checked % number_being_compared_against == 0;>
// if (number_being_checked % number_being_compared_against == 0)
// for every number found from dividing the two numbers, check if number is prime
// add up prime numbers and check if the sums are prime
// else, return false in bool function isFactorPrime() (if I write such a function)
And this is the main() function right now:
int main ()
{
for (int i = 0; i < 1000; i++)
{
if (isFactorPrime(i))
{
cout << i
}
}
}
The issue I'm having right now is about what I should add to i (i + some_variable?) to get my sum that I can use in my check to see if it's a prime number. Should I make an inner for-loop and then add loop-variable in that to i, with expression i + j? Where I'd assign j the value of the number being checked (which is what I'm wondering how I could do. It's not like I'm going to take the user's input, I'm just iterating over the first 1000 numbers and checking them).
There are also some other Practice Problems in the book I need to ask help with, but for now I'll go with just this one.

Related

why do we iterate to root(n) to check if n is a perfect number

while checking if a number n is perfect or not why do we check till square root of (n)?
also can some body explain the if conditions in the following loop
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i)
{
sum+=i; //Initially ,sum=1
}
else
{
sum+=i+(n/i);
}
}
}
According to number theory, any number has at least 2 divisors (1, the number itself), and if the number A is a divisor of the number B, then the number B / A is also a divisor of the number B. Now consider a pair of numbers X, Y, such that X * Y == B. If X == Y == sqrt(B), then it is obvious that X, Y <= sqrt(B). If we try to increase Y, then we have to reduce X so that their product is still equal to B. So it turns out that among any pair of numbers X, Y, which in the product give B, at least one of the numbers will be <= sqrt(B). Therefore it is enough to find simply all divisors of number B which <= sqrt(B).
As for the loop condition, then sqrt(B) is a divisor of the number B, but we B / sqrt(B) is also a divisor, and it is equal to sqrt(B), and so as not to add this divisor twice, we wrote this if (but you have to understand that it will never be executed, because your loop is up to sqrt(n) exclusively).
It's pretty simple according to number theory:
If N has a factor i, it'll also has a factor n/i (1)
If we know all factors from 1 -> sqrt(n), the rest can be calculated by applying (1)
So that's why you only have to check from 1 -> sqrt(n). However, you code didn't reach the clause i==n/i which is the same as i == sqrt(n), so if N is a perfect square, sqrt(n) won't be calculated.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n; cin >> n;
int sum = 1;
for(int i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
if(i==n/i) { sum+=i; }
else { sum+=i+(n/i); }
}
}
cout << sum;
}
Input : 9
Output : 1
As you can see, the factor 3 = sqrt(9) is missed completely. To avoid this, use i <= sqrt(n), or to avoid using sqrt(), use i <= n/i or i*i <= n.
Edit :
As #HansOlsson and #Bathsheba mentioned, there're no odd square which are perfect number (pretty easy to prove, there's even no known odd perfect number), and for even square, there's a proof here. So the sqrt(n) problem could be ignored in this particular case.
However, in other cases when you just need to iterate over the factors some error may occurred. It's better using the right method from the start, than trying to track bugs down afterward when using this for something else.
A related post : Why do we check up to the square root of a prime number to determine if it is prime?
The code uses the trick of finding two factors at once, since if i divides n then n/i divides n as well, and normally adds both of them (else-clause).
However, you are missing the error in the code: it loops while i<sqrt(n) but has code to handle i*i=n (the then-clause - and it should only add i once in that case), which doesn't make sense as both of these cannot be true at the same time.
So the loop should be to <=sqrt(n), even if there are no square perfect numbers. (At least I haven't seen any square perfect numbers, and I wouldn't be surprised if there's a simple proof that they don't exist at all.)

Find 101 in prime numbers

I'm currently solving a problem which is pretty straightforward: I need to find all prime numbers up to N which contain 101 in them and count them.
Say if N is 1000 then the output should ne 6 since there is 101, 1013, 1015, 5101, 6101 and 8101. I used sieve's algorithm to get all of the prime numbers up to N, though I don't know how could I solve it completely. I thought of std::find, but resigned from that idea because the time complexity grows fast. I know I need to modify sieve's algorithm to fit my needs though I can't find any patterns.
Any help would be appreciated.
Edit:
I'm using this algorithm:
vector<int> sieve;
vector<int> primes;
for (int i = 1; i < max + 1; ++i)
sieve.push_back(i); // you'll learn more efficient ways to handle this later
sieve[0]=0;
for (int i = 2; i < max + 1; ++i) { // there are lots of brace styles, this is mine
if (sieve[i-1] != 0) {
primes.push_back(sieve[i-1]);
for (int j = 2 * sieve[i-1]; j < max + 1; j += sieve[i-1]) {
sieve[j-1] = 0;
}
}
}
Yes, checking every prime number for containing "101" is a waste of time. Generating all numbers containing 101 and checking whether they are prime is probably faster.
For generating the 101 numbers, let's look at the possible digit patterns, e.g. with 5 digits:
nn101
n101m
101mm
For each of these patterns, you get all the numbers by iterating n in an outer loop and m in an inner loop and doing the math to get the pattern's value (of course, you need not consider even m values, because the only even prime is 2). You are done when the values reaches N.
To check for being a prime, an easy way is to prepare a list of all primes up to M=sqrt(N), using a sieve if you like, and check whether your value is divisible by one of them.
This should be running in O(N^1.5). Why? The number of patterns grows with O(logN), the iterations inside each pattern with N/1000, giving O(N), the prime check with the number of primes up to M, being O(M/log(M)), finding these primes with a sieve being O(M^2). Altogether that's O(N * log(N) * sqrt(N) / log(sqrt(N)) + N) or O(N^1.5).
You don't need to modify your prime generation algorithm. When processing the primes you get from your gen alg you just have to check if the prime satisfies your condition:
e.g.
// p is the prime number
if (contains(p))
{
// print or write to file or whatever
}
with:
bool contains(int);
a function which checks your condition

How is this code working for finding the number of divisors of a number?

http://www.spoj.com/problems/NDIV/
This is the problem statement. Since i'm new to programming, this particular problem ripped me off, I found this particular code on the internet which when I tried submitting got AC. I want to know how this code worked, as I have submitted it from online source which itself is bad idea for beginners.
#include <bits/stdc++.h>
using namespace std;
int check[32000];
int prime[10000];
void shieve()
{
for(int i=3;i<=180;i+=2)
{
if(!check[i])
{
for(int j=i*i;j<=32000;j+=i)
check[j]=1;
}
}
prime[0] = 2;
int j=1;
for(int i=3;i<=32000;i+=2)
{
if(!check[i]){
prime[j++]=i;
}
}
}
int main()
{
shieve();
int a,b,n,temp,total=1,res=0;
scanf("%d%d%d",&a,&b,&n);
int count=0,i,j,k;
for(i=a;i<=b;i++)
{
temp=i;
total=1;
k=0;
for(j=prime[k];j*j<=temp;j=prime[++k])
{
count=0;
while(temp%j==0)
{
count++;
temp/=j;
}
total *=count+1;
}
if(temp!=1)
total*=2;
if(total==n)
res++;
}
printf("%d\n",res);
return 0;
}
It looks like the code works on the sieve of eratosthenes, but a few things i'm unable to understand.
Why the limit of array "check" is 32000?
Again why the limit for array prime is 10000?
Inside main, whatever is happening inside the for loop of j.
Too many confusions regarding this approach, can someone explain the whole algorithm how it's working.
The hard limit on the arrays is set probably because the problem demands so? If not then just bad code.
Inside the inner loop, you are calculating the largest power of a prime that divides the number. Why? See point 3.
The number of factors of a number n can be calculated as follows:
Let n = (p1)^(n1) * (p2)^(n2) ... where p1, p2 are primes and n1, n2 ... are their exponents. Then the number of factors of n = (n1 + 1)*(n2 + 1)...
Hence the line total *= count + 1 which is basically total = total * (count + 1) (where count is the largest exponent of the prime number that divides the original number) calculates the number of prime factors of the number.
And yes, the code implements sieve of Eratosthenes for storing primes in a table.
(Edit Just saw the problem - you need at least 10^4 boolean values to store the primes (you don't actually need to store the values, just a flag indicating whether the values are prime or not). The condition given is 0 <= b - a <= 10^4 , So start your loop from a to b and check for the bool values stored in the array to know if they are prime or not.)

Sieve of Erastothenes

I'm solving some programming problems in euler project, and i stoped in this problem:
generating the prime number
I understood the algorithm but i didn't understood one thing in the solution :
Here is a solution i took from another discussion:
void sieve_of_eratosthenes(int n)
{
bool *sieve = new bool[n+1];
// Initialize
sieve[0]=false;
sieve[1]=false;
sieve[2]=true;
for(int i=3;i<n+1;++i)
sieve[i]=true;
// Actual sieve
for(int i=1; i<n+1; ++i)
//**i didnt understood what is the purpose of this condition**
if(sieve[i]==true)
for(int j=2;j*i<n+1;++j)
sieve[j*i]=false;
// Output
cout << "Prime numbers are: " <<endl;
for(int i=0;i<n+1;++i)
if (sieve[i])
cout << i <<endl;
delete [] sieve;
}
int main()
{
int n = 70;
sieve_of_eratosthenes(n);
}
i understood that in the condition we try to know if the number is prime or not , but i don't understood why we jump the not prime number
any help will be useful to me, thank you
Efficiency. Lets look at the composite number 4. Do we really need to check all the other numbers for divisibility? No, because we already checked for its prime factors.
In short, checking composite numbers is a redundant process because we check its prime factors.
A prime number is a number that has no divisors besides 1 and itself.
The aim of the sieve is to mark all multiples of the prime number as not being prime.
To do so we check if the number is prime, and mark all numbers that are a multiple of that prime as not prime.
To visualize this a bit. Let's say we start from number 2.
Is 2 prime? Yes.
Mark all 2*x where x < n. That would mark 2,4,6,8
etc.
Is 3 prime? Yes. Mark all 3*x -> 3,6,9 etc.
Is 4 prime? No. If we would not have this condition we would mark
4,8,16 etc as not prime, but we have already done this with 2.

I have n spaces, in each space, I can place a number 0 through m. Writing a program to output all possible results. Need help :)

The idea is, given an n number of spaces, empty fields, or what have you, I can place in either a number from 0 to m. So if I have two spaces and just 01 , the outcome would be:
(0 1)
(1 0)
(0 0)
(1 1)
if i had two spaces and three numbers (0 1 2) the outcome would be
(0 1)
(1 1)
(0 2)
(2 0)
(2 2)
(2 1)
and so on until I got all 9 (3^2) possible outcomes.
So i'm trying to write a program that will give me all possible outcomes if I have n spaces and can place in any number from 0 to m in any one of those spaces.
Originally I thought to use for loops but that was quickly shotdown when I realzed I'd have to make one for every number up through n, and that it wouldn't work for cases where n is bigger.
I had the idea to use a random number generator and generate a number from 0 to m but that won't guarantee I'll actually get all the possible outcomes.
I am stuck :(
Ideas?
Any help is much appreciated :)
Basically what you will need is a starting point, ending point, and a way to convert from each state to the next state. For example, a recursive function that is able to add one number to the smallest pace value that you need, and when it is larger than the maximum, to increment the next larger number and set the current one back to zero.
Take this for example:
#include <iostream>
#include <vector>
using namespace std;
// This is just a function to print out a vector.
template<typename T>
inline ostream &operator<< (ostream &os, const vector<T> &v) {
bool first = true;
os << "(";
for (int i = 0; i < v.size (); i++) {
if (first) first = false;
else os << " ";
os << v[i];
}
return os << ")";
}
bool addOne (vector<int> &nums, int pos, int maxNum) {
// If our position has moved off of bounds, so we're done
if (pos < 0)
return false;
// If we have reached the maximum number in one column, we will
// set it back to the base number and increment the next smallest number.
if (nums[pos] == maxNum) {
nums[pos] = 0;
return addOne (nums, pos-1, maxNum);
}
// Otherwise we simply increment this numbers.
else {
nums[pos]++;
return true;
}
}
int main () {
vector<int> nums;
int spaces = 3;
int numbers = 3;
// populate all spaces with 0
nums.resize (spaces, 0);
// Continue looping until the recursive addOne() function returns false (which means we
// have reached the end up all of the numbers)
do {
cout << nums << endl;
} while (addOne (nums, nums.size()-1, numbers));
return 0;
}
Whenever a task requires finding "all of" something, you should first try to do it in these three steps: Can I put them in some kind of order? Can I find the next one given one? Can I find the first?
So if I asked you to give me all the numbers from 1 to 10 inclusive, how would you do it? Well, it's easy because: You know a simple way to put them in order. You can give me the next one given any one of them. You know which is first. So you start with the first, then keep going to the next until you're done.
This same method applies to this problem. You need three algorithms:
An algorithm that orders the outputs such that each output is either greater than or less than every other possible output. (You don't need to code this, just understand it.)
An algorithm to convert any output into the next output and fail if given the last output. (You do need to code this.)
An algorithm to generate the first output, one less (according to the first algorithm) than every other possible output. (You do need to code this.)
Then it's simple:
Generate the first output (using algorithm 3). Output it.
Use the increment algorithm (algorithm 2) to generate the next output. If there is no next output, stop. Otherwise, output it.
Repeat step 2.
Update: Here are some possible algorithms:
Algorithm 1:
Compare the first digits of the two outputs. If one is greater than the other, that output is greater. If they are equal, continue
Repeat step on moving to successive digits until we find a mismatch.
Algorithm 2:
Start with the rightmost digit.
If this digit is not the maximum it can be, increment it and stop.
Are we at the leftmost digit? If so, stop with error.
Move the digit pointer left one digit.
Algorithm 3:
Set all digits to zero.
“i'm trying to write a program that will give me all possible outcomes if I have n spaces and can place in any number from 0 to m in any one of those spaces.”
Assuming an inclusive “to”, let R = m + 1.
Then this is isomorphic to outputting every number in the range 0 through Rn-1 presented in the base R numeral system.
Which means one outer loop to count (for this you can use the C++ ++ increment operator), and an inner loop to extract and present the digits. For the inner loop you can use C++’ / division operator, and depending on what you find most clear, also the % remainder operator. Unless you restrict yourself to the three choices of R directly supported by the C++ standard library, in which case use the standard formatters.
Note that Rn can get large fast.
So don't redirect the output to your printer, and be prepared to wait for a while for the program to complete.
I think you need to look up recursion. http://www.danzig.us/cpp/recursion.html
Basically it is a function that calls itself. This allows you to perform an N number of nested for loops.