Print divisors in order using theta(n) efficiency - c++

I'm struggling to implement this correctly. I want to create a function that determines all of the divisors of the user input userNum and outputs them to the user. When userNum = 16 i'm getting the output 1 16 2 8. I didn't expect the order to be correct, but i'm missing 4 and am struggling to figure out why. Any thoughts? I'm trying to do this in theta(sqrt(num)) efficiency.
void PrintDivisors(int num);
int main()
{
int userNum;
//Request user number
cout << "Please input a positive integer >=2:" << endl;
cin >> userNum;
PrintDivisors(userNum);
return 0;
}
void PrintDivisors(int num)
{
int divisorCounter;
for (divisorCounter = 1; divisorCounter < sqrt(num); divisorCounter++)
{
if (num % divisorCounter == 0 && num / divisorCounter != divisorCounter)
cout << divisorCounter << endl << num / divisorCounter << endl;
else if (num % divisorCounter == 0 && num / divisorCounter == divisorCounter)
cout << divisorCounter << endl;
}
}
Update: I have all the numbers printing, but still trying to determine how to print them in order while remaining within theta sqrt(n) efficiency

Change loop termination condition operation to <=, now you will observe 4.
Get rid of sqrt function call. Better use this loop
for (divisorCounter = 1; divisorCounter * divisorCounter <= num; divisorCounter++)

Make sure to check your edge conditions carefully.
What is sqrt(num)?
What is the largest divisorCounter that will pass the test in the for loop?
Would 4 pass the test?
I think if you look carefully at that line with these three questions in mind you will squash the bug.

For making it run in sqrt(n) time complexity:
For any n = a X b. either a<=sqrt(n) or b<=sqrt(n).
So if you can find all divisors in range [1,sqrt(n)] you can find other divisors greater than sqrt(n)
You can use a for loop to traverse numbers in range 1 to sqrt(n) and find all the divisors less than sqrt(n), which at the same time you can also use to find other numbers greater than(or equal to) sqrt(n).
Suppose a number i < sqrt(n) is divisor or n. In that case the number k = n/i will also be divisor of n. But bigger than sqrt(n).
For printing numbers in sorted order:
During finding divisors in range [1,sqrt(n)] print only divisor in range [1,sqrt(n)] You can use an array/vector to store numbers in range [sqrt(n),n] and print them after the for loop ends. Here is a sample code
vector<int> otherNums;
for(i=1;i*i<n;i++) {
if(num%i==0){
cout<<i<<endl;
otherNums.push_back(n/i);
}
}
if(i*i == n) otherNums.push_back(i);
for(i=(int)v.size() - 1 ;i>=0;i--)
cout<<otherNums[i]<<endl;

This is the solution I ended up using, which saves space complexity too. I was struggling to think of effective ways to loop over the solution in ascending order, but this one runs very fast and is nicer than appending to a vector or array or some weird string concatenation.
void printDivisors(int num)
{
for (int k = 1; k*k < num; k++)
{
if (num % k == 0)
cout << k << " ";
}
for (int d = sqrt(num); d >= 1; d--)
{
if (num % d == 0)
cout << num / d << " ";
}
cout << endl;
}

Related

My C++ prime number identifier and prime factor finder has a bug [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm a beginner to C++ and this website, so any dumb mistakes are out of ignorance. For practice, I'm trying to write a program that identifies a prime number and gives a composite's prime factors if the user requests. The prime IDer works, but the prime factors do not. When I type in twelve as my number, it gives me the factors 2 3 and 5, and 12's prime factors are 2 2 and 3. What am I messing up? Here is the code. Don't mind the weird spaces or names.
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
//Printing factors help
void print(std::vector<int> const& factors)
{
for (int i = 0; i < factors.size(); i++) {
std::cout << factors.at(i) << ' ';
}
}
int main() {
//Restarting it
std::string again;
again = "Yes";
//Actual loop
while (again == "Yes") {
//Variable/vectors
std::string pfacts;
double input = 0;
double result = 0;
double looper = 2;
int looper2 = 2;
int printed = 0;
int printed2 = 0;
std::vector<int> factors;
std::vector<int> holders;
//Asking for number
std::cout << "Please enter your number.\n";
std::cin >> input;
double holder = input;
//Ratting out trolls
if (input == 0) {
std::cout << "Your number is neither.\n";
looper = 1000003;
}
if (input == 1) {
std::cout << "Your number is neither.\n";
looper = 1000003;
}
//Prime/composite loop
while (looper < 1000002 and input != 1 and fmod(result, 1) == 0) {
result = input / looper;
//Finding composite
if (fmod(result, 1) == 0 and printed == 0) {
std::cout << "Your number is composite.\n";
printed = 1;
looper = 1000003;
}
//Finding prime
else if (fmod(result, 1) != 0 and printed2 == 0) {
std::cout << "Your number is prime.\n";
printed2 = 1;
}
}
//Asking about factors
if (printed == 1) {
std::cout << "Would you like to know it's prime factors? (Please type Yes or No exactly)\n";
std::cin >> pfacts;
}
//Actually finding them
if (pfacts == "Yes") {
while (looper2 < 1000002) {
if (holder / looper2 == 0) {
factors.push_back(holder);
looper2 = 1000003;
}
if (looper2 < 1000002 and fmod (fmod(holder, looper2), 1) == 0 and looper2 % 2 != 0 or looper2 / 2 == 1) {
factors.push_back(looper2);
holder = holder / looper2;
}
looper2 = looper2 + 1;
}
//Printing them
print(factors);
std::cout << "\n";
}
//Again?
std::cout << "Do you need to input another number? (Please type, exactly: Yes or No)\n";
std::cin >> again;
}
}
You're just making a really simple thing more complex with that looper , printed stuff,
a good programmer is one which solves hard things in easy way.
So it is hard to understand for me to know exactly what you're doing in the code above at least not without enough comments.
So here is my solution, i am just providing the algorithm so you can write your own code and learn from it.
First note things below.
A prime number is a positive integer which has exactly two factors first is 1 and another is that number itself , so two is smallest prime number.
A number is also prime if it is not divisible from 2 to its square root, you should consider this fact for performance.
Now the algorithm:
Take the number in a variable num.
Check if it is positive integer greater then 1, if not then it is not a prime.
Take num's squareroot with help of sqrt() function in variable num as you don't need original num any more.
Now add one to num and take its absolute value.
Start a loop from i = 2 to num: you're starting from 2 because two is the smallest prime.
In every iteration check num % i == 0, if yes then it is not a prime and you break, otherwise don't do anything.
Now after the loop ends check if i == num, if yes that means you never broke the hence the number is prime and you're done, otherwise you broke the loop hence the number is not prime and you ask for prime factors.
Now again you start from j = 2 to num.
Now if num % j == 0, you print j and do num = num / j, otherwise you increment j.
I hope it is helpful. I didn't test it on an IDE, because I don't have one because I don't write c++ code anymore. Tell me if you find any bugs.

basic nestled loop calculate prime numbers between 1 - 239, inclusive

I am working on a program in which I must print out the number of primes, including 1 and 239, from 1 - 239 ( I know one and or two may not be prime numbers, but we will consider them as such for this program) It must be a pretty simple program because we have only gone over some basics. So far my code is as such, which seems like decent logical flow to me, but doesnt produce output.
#include <iostream>
using namespace std;
int main()
{
int x;
int n = 1;
int y = 1;
int i = 0;
while (n<=239)
{x = n % y;
if (x = 0)
i++;
if (y < n)
y++;
n++;
while (i == 2)
cout << n;
}
return 0;
}
The way I want this to work is to take n, as long as n is 239 or less, and preform modulus division with every number from 1 leading up to n. Every time a number y goes evenly into n, a counter will be increased by 1. if the counter is equal to 2, then the number is prime and we print it to the screen. Any help would be so greatly appreciated. Thanks
std::cout << std::to_string(2) << std::endl;
for (unsigned int i = 3; i<240; i += 2) {
unsigned int j = 3;
int sq = sqrt(i);
for (; j <= sq; j += 2) if (!(i%j)) break;
if (j>sq) std::cout << std::to_string(i) << std::endl;
}
first of all, the prime definition: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
so you can skip all the even numbers (and hence ... i+=2).
Moreover no point to try to divide for a number greater than sqrt(i), because then it will have a divisor less than sqrt(i) and the code finds that and move to the next number.
Considering only odd numbers, means that we can skip even numbers as divisors (hence ... j+=2).
In your code there are clearly beginner errors, like (x = 0) instead of x==0. but also the logic doesn't convince. I agree with #NathanOliver, you need to learn to use a debugger to find all the errors. For the rest, good luck with the studies.
lets start with common errors:
first you want to take input from user using cin
cin>>n; // write it before starting your while loop
then,
if (x = 0)
should be:
if (x == 0)
change your second while loop to:
while (i == 2){
cout << n;
i++;
}

Implementing a prime number counter

For some reason, my last prime(int prime) isn't showing up at the end. Any clue ?
fyi: primeEval stands for a flag, if the loop ends && primeEval==2, the number is actually a prime number. qty stands for quantity of primes counted.
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}
New Answer:
With the change in your code you will now loop through all number. The problem with it now is that once you find a non prime number you will never reset primeEval and because of that you will never capture another prime number If you change your code to the following it will work
int main()
{
long primeEval = 0, prime = 0, qtyprime = 0;
time_t timerr = (time(NULL) + 10);
for (int i = 2; time(NULL) != timerr; i++) {
for (int j = 1; j <= i; j++) {
if ((i%j) == 0){
primeEval++; // incmrent factor
}
// if we are at the end and have 2 factors then we are prime
if (i == j && primeEval == 2) {
qtyprime++;
prime = i;
primeEval = 0; // Resets for the next number 'i'
}
// if we reach the end with more than 2 factors reset and go to the next number
if (i == j && primeEval > 2) {
primeEval = 0; // Resets for the next number 'i'
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
cin.get();
return 0;
}
I would also suggest you look at Which is the fastest algorithm to find prime numbers? to find some more efficient ways to get prime numbers.
Old Answer:
In your code you have:
for (int i = 2; time(NULL)!=timerr; i=+2)
So when you start checking from primes you start with 2 which is prime. Then you increment i by 2 so the next number you check is 4 which is an even number. All even numbers are not prime except for 2. Since you are always adding 2 you will always have an even number so the only prime number you will find is 2.
You have different issues:
for (int i = 2; time(NULL)!=timerr; i=+2) {
Here the syntax is just wrong: it must be i+=2, not i=+2, otherwise you will keep setting i to +2 and testing whether 2 is prime.
Then, as others have pointed out, why are you increasing i by 2? If you want to optimize the search, you should increase j by 2, not i! And j should in any case start from 2 (or, given your approach, from 1), and then you should try j = 3 and then you can increase j by 2 without the risk of skipping some important divisors.
Then, you reset primeEval to 0 only if you find a prime. If you test a number i that is not prime, primeEval stays at 2 and you'll never get into the block again.
So the final code could be:
#include <iostream>
using namespace std;
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
primeEval=0;
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}

Faster way to check if number is divisible with specific number

#include <iostream>
using namespace std;
int main()
{
long long n, k;
cin >> n >> k;
int num, count = 0;
do{
n--;
cin >> num;
if (num > 99 && (num % 10) % k == 0){
//cout << num << endl;
count++;
}
else if(num < 100 && (num % k) == 0){
//cout << num << endl;
count++;
}
}while(n);
cout << count << endl;
return 0;
}
I'm writing a program to check if a specific number is divisible by specific number inputted by user.
n = amount of numbers inputted
k = the number to check if numbers are divisible
My program works quite good so far, but it exceeds on time limit. Is there any faster algorithm or code than this to check if a number is divisible with another specific number?
Link : http://www.codechef.com/problems/INTEST/
First of all, the problem here is reading numbers from the input in a fast way, not doing the division. With that in mind, here is some code for fast reading:
vector<char> buffer(n * 10); // allocate a large buffer
cin.read(&buffer[0], buffer.size()); // fill the buffer with chars from input
buffer.resize(cin.gcount()); // cut buffer size to number of chars actually read
...
This reads the whole input file (note the buffer size that is limited by each number having less than 10 digits).
Then, convert the sequence of characters into numbers, and check each number for divisibility by k (num % k != 0, as others have noted). The code for that can be found in the "complex" solution that you posted (it occupies just 1 line of code there).
Modulo operator (%) is what you want. Example:
if (k != 0)
return n % k == 0;
or for the space sticklers:
if (k != 0)
return !(n % k);
Modulo returns the remainder of the division between the two numbers, for example 5 % 2 returns 1. If the remainder is 0, the numbers are divisible (IE 4 % 2 will return 0).
http://en.wikipedia.org/wiki/Modulo_operation
Instead of this code snippet
cin >> num;
if (num > 99 && (num % 10) % k == 0){
//cout << num << endl;
count++;
}
else if(num < 100 && (num % k) == 0){
//cout << num << endl;
count++;
}
You could write simply
cin >> num;
count += num % k == 0;
The point of the 'problem' is that the standard I/O libraries for most languages are very general purpose, and therefore may not be the optimal tools for reading or writing data when the format is well defined and performance is critical.
In this case, you're using the library functions to read from IO streams, which are a highly abstracted from the underlying storage system. Typically, the closer you get to the hardware, the faster your code will run.
I'd start by trying to use the C file IO functions like fopen and fread to read a large chunk of binary data from the file into memory, then process that memory 'in situ' scanning for numbers and counting the correct matches. Loop until theres no more lines to process, and remember it's much more efficent to read large blocks of data that small ones.
Instead of using
if ( n % k != 0 )
use,
int quotient = n/k;
if( quotient * k == n )
The modulus operator is slower than the second approach. (It took me 4.5 seconds to run the code with modulus operator and 1 second with the second approach)

Can you explain this code to me and why is work c++ prime numbers

This code is to find the prime numbers from 3 to n, n being an input. this code works perfect but I need to understand it much more clearly mostly the part within the nested for loop.
#include <iostream>
using namespace std;
int main ()
{
cout << "Please enter a number: \n";
int inputtedNumber;
cin >> inputtedNumber;
cout <<"the primes between 3 and that number are: \n";
int candidate = inputtedNumber;
for (int i=3; i<candidate; i++)
{
bool prime=true;
for (int j=2; j*j<=i;j++)
{
if (i % j == 0)
{
prime=false;
break;
}
}
if(prime) cout << i << "\n";
}
system("pause");
return 0;
}
thank you!
The inner loop looks at each number from 2 to the square root of i, to see if i is divisible by that number. If i is divisible by j, then i%j will be zero. If it finds a divisor, then we know it's not prime and can stop looking.
There's no need to go beyond the square root since, if there is a divisor larger than that, there must also be a corresponding divisor smaller than that, which will already have been found by this loop.
This line is key.
if (i % j == 0)
The if block is executed if i is divisible by j, which implies that i is not prime.
for (int i=3; i<candidate; i++) // for every i between 3 and candidate
{
bool prime=true;
for (int j=2; j*j<=i;j++) // for every j between 2 and the square root of i
{
if (i % j == 0) // if there is an i that is evenly divisible by j
{
prime=false; // set the flag
break; // break the inner loop
}
}
if(prime) cout << i << "\n"; // if i was a prime (no j's were evenly divisible), print it
}