Number of even divisors using square root - c++

I'm solving an problem where it need to get the difference between the number of even and odd divisors ,and i need to use sqrt() function because the limit of the number is 10^9 so looping on the whole number is not an option cause of the time limit exceed.
this a function I tried to make but it doesn't work perfectly on all number.
Ex. 4 & 48745.
Case 4 : should output 2 even divisors {2,4} and 1 odd divisor {1} -- the below function output 3 even 1 odd
Case 48745 :should output 0 even divisors and 4 odd divisors {1,5,9749,48745} -- the below function output 2 even 2 odd
int di(int x)
{
int even=0,odd=0;
for(int i=1;i<=sqrt(x);i++)
{
if(x%i==0)
{
if(i%2)
odd++;
else
even++;
if(x/i %2==0 && x/i!=i)
even++;
else if(x/i!=i)
odd++;
}
}
return even-odd;
}

Try more simple code:
#include <iostream>
#include <cmath>
int divdiff(int x)
{
unsigned int even = 0;
unsigned int odd = 0;
const unsigned int sqrtx = std::sqrt(x);
for (int i = 1 ; i <= sqrtx ; ++i)
{
if (x % i == 0)
{
if (i % 2 == 0)
{
++even;
}
else
{
++odd;
}
}
}
even *= 2;
odd *= 2;
if (x == sqrtx * sqrtx)
{
if (x % 2 == 0)
{
--even;
}
else
{
--odd;
}
}
std::cerr << __func__ << '(' << x << "): even=" << even << ", odd=" << odd << std::endl;
return even - odd;
}
int main()
{
std::cout << divdiff(2*2) << std::endl;
std::cout << divdiff(2*3) << std::endl;
std::cout << divdiff(3*3) << std::endl;
std::cout << divdiff(7*11*13*17*23) << std::endl;
}

Related

Return biggest number after writing out coalltz sequence of given number

So if I write out a collatz sequence of the given number long int n in my first function then in the next I wanna return the biggest number how do I do take for example if I call the first writeCollatzSekvens(7) it writes out
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 and I wanna return 52.
void writeCollatzSekvens(long int n){
cout << n << " ";
while(n !=1){
if ( n % 2 == 0){
n = n/2;
cout << n << " ";
}
else{
n = (n*3) + 1;
cout << n << " ";
}
}
}
long int collatzMax(long int n){
int max = 0;
if (n > max){
max = n;
}
return max;
}
You have the following problem in your "collatzMax"-function:
long int collatzMax(long int n){
int max = 0; // max has now the value 0
if (n > max){ // Therefore we do here if (n > 0) and that is always true. N is always greater then 0
max = n; // This assignment will always been done, because the if is always true
// max is now n
}
return max; // The function will always return n
}
Your function is stateless. It does not remember the "old" max value. This will not work. It is anyway not called in your other function. And there it is needed.
If you want to have the max collatz number, then you need to calculate max-values in your main loop.
And, if you have calculated your max number in the main loop, you can return it at the end of the function.
This could then for example look like that:
#include <iostream>
long int writeCollatzSekvens(long int n) { // Changed function prototype. It will return a value now
long int maxNumber = 0;
std::cout << n << " ";
while (n != 1) {
// Continously check for a new max number
if (n > maxNumber) maxNumber = n;
if (n % 2 == 0) {
n = n / 2;
std::cout << n << " ";
}
else {
n = (n * 3) + 1;
std::cout << n << " ";
}
}
return maxNumber; // Return the calculated max collatz number
}
int main() {
long int mn = writeCollatzSekvens(7);
std::cout << "\n\nMax: " << mn << '\n';
}
Of course there are many other potential solutions
EDIT
If the function should be void, then we can add an additional output parameter maxNumber. And pass this parameter by reference or by pointer.
Please see the example below. using pointer:
#include <iostream>
void writeCollatzSekvens(long int n, long int* maxNumber) { // Changed function prototype. Use output pointer for max
*maxNumber = 0;
std::cout << n << " ";
while (n != 1) {
// Continously check for a new max number
if (n > *maxNumber) *maxNumber = n;
if (n % 2 == 0) {
n = n / 2;
std::cout << n << " ";
}
else {
n = (n * 3) + 1;
std::cout << n << " ";
}
}
}
int main() {
long int mn = 0;
writeCollatzSekvens(7, &mn);
std::cout << "\n\nMax: " << mn << '\n';
}
Using reference
#include <iostream>
void writeCollatzSekvens(long int n, long int& maxNumber) { // Changed function prototype. Use output reference for max
maxNumber = 0;
std::cout << n << " ";
while (n != 1) {
// Continously check for a new max number
if (n > maxNumber) maxNumber = n;
if (n % 2 == 0) {
n = n / 2;
std::cout << n << " ";
}
else {
n = (n * 3) + 1;
std::cout << n << " ";
}
}
}
int main() {
long int mn = 0;
writeCollatzSekvens(7, mn);
std::cout << "\n\nMax: " << mn << '\n';
}

Function: smallest positive integer

#include <iostream>
using namespace std;
int enough(int goal)
{
int C { };
int i { };
if (goal > 1)
{
while (((C += i) <= goal) && ((goal - i) <= (i + 1)))
{
i += 1;
}
}
else
{
i = 1;
}
return i;
}
int main()
{
cout << enough(21);
return 0;
}
So the purpose of this function is for it to return the smallest positive integer that can be summed consecutively from 1 before the cumulative sum becomes greater than the parameter "goal".
So, for example:
cout << enough(9) << endl;
will print 4 because 1+2+3+4 > 9 but 1+2+3<9
cout << enough(21) << endl;
will print 6 'cause 1+2+ . . .+6 > 21 but 1+2+ . . . 5<21
cout << enough(-7) << endl;
will print 1 because 1 > -7 and 1 is the smallest positive integer
cout << enough(1) << endl;
will print 1 because 1 = 1 and 1 is the smallest positive integer
My logic at first was using just while ((C += i) <= goal), but that went wrong, for example, for the parameter 21, where you get C = 20, which passes the test and ends up in i being augmented by 1 (resulting in the return value i = 7, which is clearly wrong).
Therefore I decided to create a test which tested both C and i, but that went wrong because the code isn't considering goal - i and i + 1 as separate tests for the while circuit, but I believe it is actually altering the value of ints goal and i, which screws everything up.
Any ideas where I went wrong?
Your approach is unnecessarily verbose. There is a closed-form (i.e. O(1)) solution for this.
The sum S of the arithmetic progression 1, 2, ..., n is
S = n * (n + 1) / 2
Rearranging this (completing the square), rejecting the spurious root, and rounding appropriately to fit the requirements of the question yields the result
n = std::ceil((-1 + std::sqrt(1 + 8 * S)) / 2)
This will not work for negative n, and possibly 0 too depending on the specific (and unspecified) requirements.
Or if you must use an O(N) approach, then
int enough(int goal){
int i = 0;
for (int total = 0; (total += ++i, total) < goal; );
return i;
}
will do it, which returns 1 for goal <= 1.
You could perhaps try to simplify your original O(N) approach by only having one condition in your while-loop, i.e., no &&:
#include <iostream>
using namespace std;
int enough(int goal)
{
if (goal <= 0)
{
return 1;
}
int total{};
int i{};
while (total < goal)
{
total += ++i;
}
return i;
}
int main()
{
cout << "enough(9): " << enough(9) << endl;
cout << "enough(21): " << enough(21) << endl;
cout << "enough(-7): " << enough(-7) << endl;
cout << "enough(1): " << enough(1) << endl;
cout << "enough(0): " << enough(0) << endl;
return 0;
}
Output:
enough(9): 4
enough(21): 6
enough(-7): 1
enough(1): 1
enough(0): 1

How to make the outcome of a boolean function to output a certain statement when the boolean is TRUE or FALSE in the main (c++)?

Problem
I am trying to write a program that can output all of a numbers prime factors. I started by making a function to check whether a factor is prime or not:
bool checkPrime() {
for (x = 1; x <= i; ++x) {
if (x % i != 0) {
return 1;
}
else {
return 0;
}
}
Main
int main() {
cout << "Enter any positive number: " << endl;
cin >> n;
cout << "Prime Factors of " << n << " are: " << endl;
for (i = 1; i <= n; ++i) {
if (n % i == 0) {
for (x = 1; x <= i; ++x) {
cout << i << " ";
}
}
cout << "\n";
system("pause");
}
Question
How can I implement my "checkPrime" function to check whether or not I run:
cout << i << " ";
I reckon the problem is to print the boolean return value of checkPrime() function as true or false. I'm not going in to the correctness of checkPrime() function in this answer. But for your purpose use something like the following.
std::cout << std::boolalpha << checkPrime() << std::noboolalpha << std::endl;
Refer: https://en.cppreference.com/w/cpp/io/manip/boolalpha
I didn't look into you checkPrime() function, but ideally it should accept n as an argument.
Change checkPrime to accept an input.
Fix the the implementation. The current implementation is not correct.
Add a call to the function in main and output the number based on the return value of the function.
bool checkPrime(int i)
{
// 1 and 2 are primes
if ( i < 2 )
{
return true;
}
if ( i % 2 == 0 )
{
return false;
}
// Check with only odd numbers.
// Division by even numbers is not necessary.
// Even numbers greater than 2 are not prime numbers.
// Also, you don't need to check for division by numbers greater than sqrt(i)
for (x = 3; x*x <= i; x +=2 )
{
if ( i % x == 0)
{
return false;
}
}
return true;
}
In main:
for (i = 1; i <= n; ++i)
{
if (n % i == 0 )
{
if ( checkPrime(i) )
{
cout << i << " ";
}
}
}
You can combine the two if statements into one if statement.
for (i = 1; i <= n; ++i)
{
if (n % i == 0 && checkPrime(i) )
{
cout << i << " ";
}
}

Classifying digits of an integer value

I spent a day on this code for count even and zero and odd numbers
From long datatype I used a function to send data. Here is the code
#include <iostream>
using namespace std;
void digitCount(long long int &num);
int main ()
{
long long int num;
cout <<"Enter any No. " <<endl;
cin >>num;
cout <<endl;
digitCount(num);
return 0;
}
void digitCount(long long int &num)
{
int e = 0, z = 0, o = 0, x = 0;
for (int i = 0; i <= num; i++)
{
x= num % 10;
if(x == 0)
{
++z;
num = num / 10;
}
else if(x%2==1)
{
++o;
num = num / 10;
}
else
{
++e;
num = num / 10;
}
}
cout << "No of zeros Digits = " << z<< endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
the problem is when I count odd numbers there is a number missed
for example when i input : 12345
the result is
no of even : 2
no of odd : 2 (should be 3)
no of zero : 0
and here the question :
Write a function that takes as parameter an integer (as a long value) and returns the number of odd, even, and zero digits. Also write a program to test your function. Use pass by reference method.
Instead of the for loop you should use:
while (num > 0)
You're constantly changing num and when it gets to 1 (in your 12345 example), i is at 3. I also modified your digitcount to demonstrate some decent formatting for readable code.
void digitCount(long long int &num) {
int e(0), z(0), o(0), x(0);
while (num > 0) {
x = num % 10;
if (x == 0) {
z++;
}
else if (x % 2 == 1) {
o++;
}
else {
e++;
}
num /= 10;
}
cout << "No of zeros Digits = " << z << endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
If you believe this solves your problem && is the best answer, please click the checkmark next to this answer. Thanks

Finding factors of a number. Not getting accurate results

Can someone help correct my algorithm? I've tested it on a few numbers, and it doesn't output the complete factorization. For numbers with a large number of factors, it just completely fails.
int num = 20;
for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
}
}
EDIT: The two answers provided did not work, still not getting full results.
EDIT2: Divisors VS Factors
Judging from you comment to #Luchian Grigore, you're confusing divisors with (prime) factorization. Divisors of a number are all numbers for which num % i == 0 is true. Factorization means getting a representation of num by a product of smaller numbers. If you want uniqueness of factorization, you usually use prime factorization.
To get all the divisors your code should be
for ( int i = 1; i <= num; ++i ) // note that 1 and num are both trivially divisors of num
{
if ( num % i == 0 ) // only check for divisibility
{
std::cout << i << std::endl;
}
}
to get the (prime) factorization, it's
for ( int i = 2; i <= num; ++i )
{
while ( num % i == 0 ) // check for divisibility
{
num /= i;
std::cout << i << std::endl;
}
// at this point, i cannot be a divisor of the (possibly modified) num.
}
The problem is that you're increasing i even if it is a divisor, and you shouldn't unless you find all its occurences.
So, for 4, you'd have 2 twice. But after the first 2 you encounter, you exit the loop because i is incremented to 3 and num became 2.
The following should work:
for(int i = 2; i <= num; )
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
}
else
{
i++;
}
}
for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
num = num/i;
i--; // Add this to account for multiple divisors
}
}
for(int i = 2; i <= num; i++)
{
if(num%i == 0)
{
cout << i << endl;
cout << num << endl;
}
}
This should work. Note, should use c++11 for move constructor, otherwise you are going to want to pass in a std::list& instead.
std::list<int64_t> factor(int64_t f)
{
std::list<int64_t> factors;
for(int64_t ii = 2; ii<=f; ii++) {
while(f % ii == 0) {
f = f/ii;
factors.push_back(ii);
}
}
return factors;
}