Calling Boolean function in C++ - c++

Here is my program, which aims to show whether the input integer is a perfect number or not. It is required to use Boolean function and call it back in main function. However, after running the trial, there is no output. Can anyone help out this programming newbie...Thanks in advance for any help.
#include <iostream>
using namespace std;
bool perfect ( int num )
{
int sum = 0, i = 1;
while( i < num ) {
if ( num % i == 0 ) {
sum = sum + i;
i++;
}
}
if ( num == sum )
return 1 ;
else
return 0 ;
}
int main()
{
int num ;
cin >> num ;
if ( perfect ( num ) == 1 )
cout << " YES " << endl ;
else
cout << " NO " << endl ;
}

Let's look at your loop when num == 3 and i == 2.
int i = 1;
while( i < num ) {
if ( num % i == 0 ) {
sum = sum + i;
i++;
}
}
i < num is 2 < 3 which is true, so we'll enter the while loop.
num % i == 0 is 3 % 2 == 0 which is false, so we won't enter the conditional.
We head back to the top of the while loop.
i and num haven't changed, so this is an infinite loop.
You probably want something like:
bool perfect_number(int x) {
int sum_of_divisors = 0;
for (int divisor = 1; divisor < x; divisor++)
if (x % divisor == 0)
sum_of_divisors += divisor;
return sum_of_divisors == x;
}
Which we can optimize into:
bool perfect_number(int x) {
return x == 6 || x == 28 || x == 496 || x == 8128 || x == 33550336;
}

Your function perfect(int) return a bool and not an integer, so if(perfect(num)) can be used directly.
You could have used return type int for function perfect() to use 'if' condition as: if(perfect(num)==1)

Related

I was doing a code for , "Count Digits " , Evenly divides means whether N is divisible by a digit i.e. leaves a remainder 0 when divided

#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m,z;
cout<<"enter n: ";
cin>>n;
z=n;
int count=0;
while(n>0){
m = n % 10;
if(z%m == 0){
count++;
}
n=n/10;
}
cout<<count;
}
Code should work like that ex - for n = 12, it is divisible by both 1 , 2 so, the output will be 2
if i am taking any value which have '0' in their last then it is not working ..and i am getting an error "Floating-point exception (SIGFPE)".
Could anyone help me to get rid out of this.
This while loop
while(n>0){
m = n % 10;
if(z%m == 0){
count++;
}
n=n/10;
}
does not make a great sense. For example m can be equal to 0 after this statement
m = n % 10;
and as a result this statement
if(z%m == 0){
produces a run-time error.
The program can look for example the following way
#include <iostream>
int main()
{
unsigned int count = 0;
int n;
std::cout << "enter n: ";
if ( std::cin >> n )
{
const int Base = 10;
int tmp = n;
do
{
int digit = tmp % Base;
if ( digit != 0 && n % digit == 0 ) ++count;
} while ( tmp /= Base );
}
std::cout << "count = " << count << '\n';
}

How to check if number has a repeating digit using recursion?

I need to know if a number has a repeating digit using recursion and return 'yes' or 'no'. I am not allowed to use loops or arrays. This is what I've done untill now with 10 global variables and it works, but I think there is a better way.
#include <iostream>
using namespace std;
int counter0 = 0;
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
int counter5 = 0;
int counter6 = 0;
int counter7 = 0;
int counter8 = 0;
int counter9 = 0;
bool check(int k) {
int p = k % 10;;
if (k < 10) {
return false;
} else {
if (p == 0) {
counter0++;
} else if (p == 1) {
counter1++;
} else if (p == 2) {
counter2++;
} else if (p == 3) {
counter3++;
} else if (p == 4) {
counter4++;
} else if (p == 5) {
counter5++;
} else if (p == 6) {
counter6++;
} else if (p == 7) {
counter7++;
} else if (p == 8) {
counter8++;
} else if (p == 9) {
counter9++;
}
if(counter1>1 || counter2>1 || counter3>1 || counter4>1 || counter5>1 || counter6>1 || counter7>1 || counter8>1 || counter9>1)
{
return true;
}
k=k/10;
check(k);
}
}
int main() {
//cout << "Hello, World!" << std::endl;
int n;
cin >> n;
cout << (check(n) ? "yes" : "no") << endl;
//cout << n/10;
return 0;
}
#include <iostream>
using namespace std;
bool hasRepeatingDigit(int n, int mask)
{
// base case: if we have checked all the digits and didn't find any duplicates, return false
if (n == 0)
return false;
/*
p is the place of the last digit in n (n%10).
A digit can range from 0 to 9.
The place of 0 will be 1 << 0 which is 1.
The place of 1 will be 1 << 1 which is 2.
The place of 2 will be 1 << 2 which is 4.
...
...
The place of 9 will be 1 << 9 which is 512.
*/
int p = 1 << (n % 10);
// if place of p has already been marked then it's a duplicate
if (mask&p)
return true;
// otherwise scrap the last digit (n/10), mark place p and recurse on the remaining digits
return hasRepeatingDigit(n / 10, mask|p);
}
int main()
{
int n;
cin >> n;
cout << hasRepeatingDigit(n, 0) << endl;
}
Recursion problems always have a base case and an recursive case.
The base case is simple: k<11 has no repeated digits.
For the recursive case, k has repeated digits if either:
the lower two digits of k are equal, or
k/10 has repeated digits.
So:
bool check(int k) {
if (k < 11)
return false;
int digit = k % 10;
int next = k / 10;
int digit2 = next % 10;
if (digit == digit2)
return true;
else
return check(next);
// Or in one expression:
// return (digit == digit2) || check(next);
}
first, the code is incorrect...
if you enter n=11 it says 'no' but 1 repeated twice. you can fix it by changing the if statement from if(k < 10) to if(k == 0)
you can get down to the bits level but I can't see how much is useful...
in conclusion, this is the best you can do without arrays...
BUT: if you need to find if a digit repeated twice or more in a row the other answer is perfect

C++ : Why do I have to add a boolean expression?

The code is:
int main() {
int n, largest = 1;
cout << "enter :" << endl;
cin >> n;
int i = n - 1;
while(i > 0) {
if (n % i == 0){
largest = i;
}
i--;
}
cout << largest << endl;
system("pause");
return 0;
}
Why do these error occur? This code keeps making errors and my professor said that I should add a boolean expression. But I do not know why and where I have to add it?
(Inspired by Alexandrescu's CppCon 2019 talk)
Recall, that the control check on the loop is not necessary - we know that X % 1 is 0 for any X. Also, in-line with Alexandrescu's commitment to endless loops, we could rewrite the loop as following (it will have an added bonus of making it correct, but also will improve it's performance):
if (n <= 1) {
return;
}
largest = n - 1;
for (;; --largest) {
if (n % largest == 0)
break;
}
// Here largest is usable
Rewrite this loop
while( i > 0){
if ( n % i == 0){
largest = i;
}
i --;
}
for example like
while( i > 0 && n % i != 0 ) i--;
if ( i ) largest = i;
Also instead of the type int you should use the type unsigned int. Otherwise the user can enter a negative number. In this case the loop does not make sense.
Using your approach the program can look for example the following way
#include <iostream>
int main()
{
unsigned int n = 0, largest = 1;
std::cout << "enter a non-negative number: ";
std::cin >> n;
if ( n != 0 )
{
unsigned int i = n - 1;
while ( i > 0 && n % i != 0 ) i--;
if ( i ) largest = i;
}
std::cout << "The largest own divisor is " << largest << std::endl;
return 0;
}

Wrong Solution if Memoization is added to Recursion

I have created a DP program but the problem is that I get correct answers when I don't use memoization. As soon as I introduce memoization, I start getting the wrong answers for some problems
Here is the code in C++ 14 with memoization turned off (By commenting)
#include <iostream>
#include <math.h>
#include<algorithm>
using namespace std;
int max_Number_of_turns;
int dp[9999][1000];
int changeTheDigit(int n, int d) {
int rem = n % (int) (pow(10, 4 - d));
n /= (pow(10, 4 - d));
int x = n % 10;
n /= 10;
if (x == 9) x = 0;
else x = x + 1;
n = n * (10) + x;
n = n * (pow(10, 4 - d)) + rem;
return n;
}
int minMax(int n, int t) {
int ans =0;
//if(dp[n][t]>=0) { return dp[n][t];}
if (t > max_Number_of_turns) return n;
int N;
for (int i = 0; i < 4; i++) {
N = changeTheDigit(n, i + 1);
if (t % 2 == 0) {
//Manish chance
if(ans==0) ans=minMax(N, t+1);
else ans = min(ans, minMax(N, t + 1));
} else {
//Nitish Chance
ans = max(ans, minMax(N, t + 1));
}
}
//cout << ans << endl;
dp[n][t]=ans;
return ans;
}
using namespace std;
int main() {
int T, N, M;
cin >> T;
while (T--) {
cin >> N >> M;
max_Number_of_turns=M;
for(int i=0;i<9999;i++)
for(int j=0;j<1000;j++)
dp[i][j]=-1;
if(minMax(N,1)>N){
cout << "Nitish" << endl;
}
else{
cout << "Manish" << endl;
}
}
return 0;
}
Turn the memoization comment on (i.e. remove the comments from this line)
if(dp[n][t]>=0) { return dp[n][t];}
and my code will give wrong answers to some problems
For example, let us consider the input
1
4569 12
Original Correct Solution is Manish
But If I turn on memoization, My solution is Nitish
Can you suggest me that what am I doing wrong here
Also, a fun fact is that, if the change the DP code from
if(dp[n][t]>=0) { return dp[n][t];}
to
if(dp[n][t]>0) { return dp[n][t];}
Then everything is fine
Your problem is that the values for n and/or t are not checked and so could cause out-of-bounds issues with the array. You can see that if you insert the following at the start of your minMax function:
if (n < 0 || n >= 9999) cout << "n invalid at " << n << '\n';
if (t < 0 || t >= 1000) cout << "t invalid at " << t << '\n';
Running that with your sample input gives warnings before outputting the result:
n invalid at 9999
n invalid at 9999
n invalid at 9999
To fix this, you can just ensure you only use memoisation when you have enough storage for it, first when checking the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000 && dp[n][t] >= 0)
return dp[n][t];
and, second, when storing the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
dp[n][t] = ans;

Determine Amicable Pairs within Confines of Theta(n)

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";
}
}