What is the correct syntax to use a while loop that exits when a boolean is true.
I'm not sure if this is works right:
while (CheckPalindrome(a, reverse) == false)
{
CalcPalindrome(a, reverse);
n = a;
while (n != 0)
{
remainder = n % 10; //Finds the 1's digit of n
reverse = reverse * 10 + remainder;
n /= 10;
}
CheckPalindrome(a, reverse);
}
You only need to call CheckPalindrome() once, and that's in while(CheckPalindrome())
Also, the proper syntax is while(!CheckPalindrome())
So your optimized code would be:
while (!CheckPalindrome(a, reverse))
{
n = a;
while (n != 0)
{
remainder = n % 10; //Finds the 1's digit of n
reverse = reverse * 10 + remainder;
n /= 10;
}
}
I'm not sure what that inner while loop is supposed to do, but that's the proper syntax for breaking from a while loop when a function returns false
Related
I have a class, call it 'BigNumber', which has a vector v field.
Each element should be one digit.
I want to implement a method to multiply this vector by an integer, but also keep elements one digit.
E.g: <7,6> * 50 = <3,8,0,0>
The vector represents a number, stored in this way. In my example, <7,6> is equal to 76, and <3,8,0,0> is 3800.
I tried the following, but this isn't good (however it works), and not the actual solution for the problem.
//int num, BigNumber bn
if (num > 0)
{
int value = 0, curr = 1;
for (int i = bn.getBigNumber().size() - 1; i >= 0; i--)
{
value += bn.getBigNumber().at(i) * num * curr;
curr *= 10;
}
bn.setBigNumber(value); //this shouldn't be here
return bn;
}
The expected algortithm is multiply the vector itself, not with a variable what I convert to this BigNumber.
The way I set Integer to BigNumber:
void BigNumber::setBigNumber(int num)
{
if (num > 0)
{
bigNum.clear();
while (num != 0)
{
bigNum.push_back(num % 10);
num = (num - (num % 10)) / 10;
}
std::reverse(bigNum.begin(), bigNum.end());
}
else
{
throw TOOSMALL;
}
};
The method I want to implement:
//class BigNumber{private: vector<int> bigNum; ... }
void BigNumber::multiplyBigNumber(BigNumber bn, int num)
{
if (num > 0)
{
//bn.bigNum * num
}
else
{
throw TOOSMALL;
}
}
As this is for a school project, I don't want to just write the code for you. So here's a hint.
Let's say you give me the number 1234 --- and I choose to store each digit in a vector in reverse. So now I've got bignum = [4, 3, 2, 1].
Now you ask me to multiply that by 5. So I create a new, empty vector result=[ ]. I look at the first item in bignum. It's a 4.
4 * 5 is 20, or (as you do at school) it is 0 carry 2. So I push the 0 into result, giving result = [0] and carry = 2.
Questions for you:
If you were doing this by hand (on paper), what would you do next?
Why did I decide to store the digits in reverse order?
Why did I decide to use a new vector (result), rather than modifying bignum?
and only after you have a worked out how to multiply a bignum by an int:
How would you multiply two bignums together?
The solutin for the problem is the follow code. I don't know if I can make this algorithm faster, but it works, so I'm happy with it.
BigNumber BigNumber::multiplyBigNumber(BigNumber bn, int num){
if (num > 0)
{
std::vector<int> result;
std::vector<int> rev = bn.getBigNumber();
std::reverse(rev.begin(),rev.end());
int carry = 0;
for(int i = 0; i<rev.size(); i++){
result.push_back((rev[i] * num + carry) % 10);
carry = (rev[i] * num + carry) / 10;
if(i == rev.size()-1 && carry / 10 == 0 && carry % 10 != 0 ) {
result.push_back(carry);
carry = carry / 10;
}
}
while((carry / 10) != 0){
result.push_back(carry % 10);
carry /= 10;
if(carry / 10 == 0) result.push_back(carry);
}
std::reverse(result.begin(),result.end());
bn.setBigNumber(result);
return bn;
}else{
throw TOOSMALL;
}
}
Below is my solution for finding the number of trailing zeros in a factorial, it works, i'm posting it to give an idea of how the algorithm works which is the sum of quotients of n divided by 5 ^ i, where i>0.
#include <cmath>
long zeros(long n) {
long sum = 0;
for (int i = 1;; ++i) {
int m = n / pow(5, i);
if (m == 0)
break;
else sum += m;
}
return sum;
}
I saw this solution which confused me with its use of the = operator. What does =5 mean in this context?
long zeros(long n) {
long result = 0;
while(n)
result += n/=5;
return result;
}
The expression result += n/=5 is equivalent to first updating the value of n to n/5 and then updating the value of result to result + n where n is now n/5.
// result += n/=5 is same as doing
n = n / 5;
result = result + n;
Here the /= is analogous to += in the sense that n/=5 is equivalent to n = n/5
Its to assign a value or variable to a variable
i.e m = n means that if n is 15, m will be the value of n which is 15
I have correctly written the program for getting the superdigit of a large number (long long) but can't seem to pass some cases due to timeout and abort calls. Please suggest some optimizations to improve the runtime of my program:
int superDigit(long long m) {
int d=countDigit(m);
if(d==1){
return m;
}
long s=sumDigit(m);
return superDigit(s);
}
//utility functions to calculate digit count and sum of digits
int countDigit(long long n)
{
int count = 0;
while (n != 0) {
n = n / 10;
++count;
}
return count;
}
long sumDigit(long long n)
{
long sum = 0;
while (n != 0) {
sum += n % 10;
n = n / 10;
}
return sum;
}
Theory: A superdigit is defined by the following rules:
If x has only 1 digit, then its super digit is x
Otherwise, the super digit of x is equal to the super digit of the sum of the digits of x
For example:
super_digit(9875): 9+8+7+5 = 29 ,then
super_digit(29): 2 + 9 = 11 ,then
super_digit(11): 1 + 1 = 2 ,then
super_digit(2): = 2
Only looping over the digits once per superDigit call and avoiding recursion should make it faster. Something like this:
long long superDigit(long long m) {
long long sum;
while(true) {
sum = 0;
while(m != 0) {
sum += m % 10;
m /= 10;
}
if(sum >= 10)
m = sum;
else
break;
}
return sum;
}
If you need support for repeated sequences, like 593 10 times (which is usually too big for a long long) you could add a wrapper like this:
long long superDigit(long long m, int times) {
long long r = superDigit(m) * times;
if(r >= 10) r = superDigit(r);
return r;
}
For numbers small enough to fit in a long long, you can check that it works. Example:
superDigit(148148148) == superDigit(148, 3)
If you need support for large numbers that are not repeated sequences, you could add yet another overload, taking the number as a std::string:
long long superDigit(const std::string& m) {
long long sum = 0;
for(auto d : m) sum += d - '0';
if(sum >= 10) return superDigit(sum);
return sum;
}
And you can check that it's also getting the same result as one of the previous overloads:
superDigit(593, 10) == superDigit("593593593593593593593593593593")
I think you are getting abort call for value of m! If the value of m is 0, then the recursion will continue lifetime. And if the value of m can be negative then take care the problem for negative values too.
Please check it!
int superDigit(long long m) {
if(m<=9)return m; // handling case 0
int d=countDigit(m);
if(d==1){
return m;
}
long s=sumDigit(m);
return superDigit(s);
}
Your code has a problem with a '0'. It gets into an endless loop that is terminated if the call stack overflows (if your compiler does not eliminated the tail recursion).
The digit count helper function is completely unnecessary
int superDigit(long long m) {
if(m<10){
return m;
}else{
int s = 0;
do {
s += m % 10;
m = m / 10;
}while (m > 0);
return superDigit(s);
}
}
You can eliminate the recursion by yourself by putting the whole thing into a loop.
int superDigit(long long m) {
while (m >9){
int s = 0;
do {
s += m % 10;
m = m / 10;
}while (m > 0);
m = s;
}
return m;
}
But recursion looks a bit more self explaining and modern compiler should be able to eliminate the tail recursion either.
I need to make a simple function in c++ that will say if an entered integer has its digits ascending from left to right. Ex, 123 is ascending. We just started learning recurssion, which is what I'm supposed to use, but I'm confused. So far what I was thinking is that you store the last digit as a temp, then compare that to the next digit, but how would you manage to do that?
bool ascending(int n) {
int temp = n % 10;
while (n / 10 > 0) {
n = n / 10;
if (temp > n % 10) {
return false;
break;
}
temp = n % 10;
}
}
This is the code I have so far, but I'm definitely messing up. I'm not even using recurrsion.
Here is one way you can go about it.
On every iteration, you check that last 2 digits are in order. And when the number is a single digit, return true
bool ascending(int n) {
int last_digit = n % 10;
int remainder = n / 10;
if (remainder == 0)
{
return true;
}
int second_last_digit = remainder % 10;
if (last_digit < second_last_digit)
{
return false;
}
else
{
return ascending(remainder); // Recusrive call
}
}
Euler published the remarkable quadratic formula:
n² + n + 41
It turns out that the formula will produce 40 primes for the consecutive
values n = 0 to 39. However, when n =
40, 40^(2) + 40 + 41 = 40(40 + 1) + 41
is divisible by 41, and certainly when
n = 41, 41² + 41 + 41 is clearly
divisible by 41.
Using computers, the incredible formula n² − 79n + 1601 was
discovered, which produces 80 primes
for the consecutive values n = 0 to
79. The product of the coefficients, −79 and 1601, is −126479.
Considering quadratics of the form:
n² + an + b, where |a| < 1000 and |b| < 1000
where |n| is the modulus/absolute value of n
e.g. |11| = 11 and |−4| = 4
Find the product of the coefficients, a and b, for the
quadratic expression that produces the
maximum number of primes for
consecutive values of n, starting with
n = 0.
This is the problem for Euler 27.
I have attempted a solution for trying to find the equation n^2 + n + 41 to see if my logic is correct then I will attempt to see if it works on the actual problem. Here is my code (I will place comments explaining the whole program also, I would start reading from the int main function first) just make sure to read the comments so you can understand my logic:
#include <iostream>
using namespace std;
bool isPrime(int c) {
int test;
//Eliminate with some simple primes to start off with to increase speed...
if (c == 2) {
return true;
}
if (c == 3) {
return true;
}
if (c == 5) {
return true;
}
//Actual elimination starts here.
if (c <= 1 || c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
return false;
}
//Then using brute force test if c is divisible by anything lower than it except 1
//only if it gets past the first round of elimination, and if it doesn't
//pass this round return false.
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
//If the c pasts all these tests it should be prime, therefore return true.
return true;
}
int main (int argc, char * const argv[]) {
//a as in n^2 + "a"n + b
int a = 0;
//b as in n^2 + an + "b"
int b = 0;
//n as in "n"^2 + a"n" + b
int n = 0;
//this will hold the result of n^2 + an + b so if n = 1 a = 1
//and b = 1 then c = 1^2 + 1(1) + 1 = 3
int c = 0;
//bestChain: This is to keep track for the longest chain of primes
//in a row found.
int bestChain = 0;
//chain: the current amount of primes in a row.
int chain = 0;
//bestAB: Will hold the value for the two numbers a and b that
// give the most consecutive primes.
int bestAB[2] = { 0 };
//Check every value of a in this loop
for (a = 0; a < 40; a++) {
//Check every value of b in this loop.
for (b = 0; b < 42; b++) {
//Give c a starting value
c = n*n + a*n + b;
//(1)Check if it is prime. And keep checking until it is not
//and keep incrementing n and the chain. (2)If it not prime then che
//ck if chain is the highest chain and assign the bestChain
// to the current chain. (3)Either way reset the values
// of n and chain.
//(1)
while (isPrime(c) == true) {
n++;
c = n*n + a*n + b;
chain++;
}
//(2)
if (bestChain < chain) {
bestChain = chain;
bestAB[0] = a;
bestAB[1] = b;
chain = 0;
n = 0;
}
//(3)
else {
n = 0;
chain = 0;
}
}
}
//Lastly print out the best values of a and b.
cout << bestAB[0] << " " << bestAB[1];
return 0;
}
But, I get the results 0 and 2 for a and b respectively, why is this so? Where am I going wrong? If it is still unclear just ask for more clarification on a specific area.
Your isprime method is inefficient -- but also wrong:
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
in the first iteration of the for loop, test = c, so c % test is just c % c, which will always be 0. So your isprime method claims everything is non-prime (other than 2, 3, 5)
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
Do you see the problem with that? If not, try working out some small sample values by hand.
As pointed out by others, your problem is in the isPrime method (test = c, so test % c = c % c == 0 is always true).
You can make your isPrime function run in O(sqrt(n)) instead of O(n) by initializing test to sqrt(c) (and only checking odd numbers). It is easy to see that if a number A is divisible by B < sqrt(A), then C = A/B must be > sqrt(A). Thus if there are no divisors < sqrt(A), there will be no divisors > sqrt(A).
Of course, you can run it a whole lot faster even, by using a probabilistic primality test, e.g. Miller-Rabin's primality test.
Also, I'm not sure, but I suspect you might reach the limit of int fairly quickly. It's probably a better idea to use unsigned long long from the start, before you start getting strange errors due to overflow & wrapping.