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

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

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

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

std::map <int,int> increment

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.

Error "expected primary-expression before int"

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.