How do I make an ascending function in C++? - c++

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

Related

How to multiply std::vector<int> by int where vector's each element should be one digit?

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

Optimising Recursion Problem for calculating Super Digits

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.

How to use a boolean in a while loop C++

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

Subtraction of reversed digits with recursion

i'm trying to do a subtraction of digits in a recursive way, lets say that I have the number 125 then the subtraction takes place doing it this way
5-2-1 = 2
I've already done the sum with recursion but i'm stuck thinking about it because i'm trying to get each digit and then subtract it within the function itself this way
int RecursiveMath::restaDigitos(int n){
if(n/10 <= 1){
return 0;
}else{
return restaDigitos(n/10) - n%10;
}
}
I do know this function is not working but it's what i've tried along with many combinations, I feel like i'm complicating it too much, any help/advice would be highly appreciated!
You can simplify the task because 5 - 2 - 1 is equal to 5 - (2 + 1), so we can sum up all digits except highest, and subtract this sum from it.
int subtractDigits(const unsigned int n, const bool first = true){
if(n == 0){
return 0;
}
if(first){
return n % 10 - subtractDigits(n / 10, false);
}
else{
return n % 10 + subtractDigits(n / 10, false);
}
}
AHHH This one was tricky
#include <stdio.h>
int restaDigitos(int n){
printf("Processing: %d\n", n);
printf("division: %d\n", n/10);
if(n==0){
return 0;
}else{
return n%10 + restaDigitos(n/10);
}
}
int main() {
int input = 125;
int firstVal = input % 10;
int result = restaDigitos(input / 10);
printf("result: %d\n", firstVal - result);
}
Two major corrections were made:
Your termination condition was neglecting the last case where a single digit remains so it terminated early
The first value cannot be recursive because it is positive. (5-2-1) -> The first number 5 is positive whereas the other values are negative
Hope this helped!
The problem is that you are also subtracting the last number (0 - 1 -2 - 5), but from what I can tell from your question, you want to add it (0 - 1 -2 + 5). My solution is to add another argument specifying the number of digits so that you know when to add instead of subtract
int RecursiveMath::restaDigitos(int n, int numDigits){
if (n == 0) {
return 0;
} else if (n / (pow(10, numDigits - 1)) >= 1){
return restaDigitos(n/10, numDigits) + n % 10;
} else {
return restaDigitos(n / 10, numDigits) - n % 10;
}
}
You are processing the first value differently that the others. Such a use case leads to tricky recursion ways, using default parameters or static values for one shot solutions.
Here you could use:
int restaDigitos(int val, bool first = true, int curr = 0) {
if (val == 0) return curr;
if (first) curr = val%10;
else curr -= val%10;
return restaDigitos(val/10, false, curr);
}
You can control that restaDigitos(125); gives as expected 2.

Recursive function to check digits

Write a recursive function to check how many digits in the number can be divided by the digit which is after them. Example: 84963 should return 2, because 8 can be divided by 4 and 6 can be divided by 3. My function doesnt seem to output anything at all.
#include <iostream>
using namespace std;
int fun (int n);
int main()
{
int n;
cin >> n;
cout << fun(n) << endl;
return 0;
}
int fun(int n){
int count = 0;
if (fun(n % 100) % fun(n % 10) == 0)
count++;
return count;
}
Your recursion does not make much sense at the moment. A more logical approach to this would be to see if the last number (so 1 in 321), can currently divide the second last number (so 2 in 321). You could do this by defining a function that checks if that is possible, and recursively passes on the number divided by 10. That function would look something like this:
int fun(int n)
{
if (n < 10)
return 0;
int last = n % 10;
n = n / 10;
int secondlast = n % 10;
if (secondlast != 0 && last != 0 && secondlast % last == 0)
return 1 + fun(n);
else
return fun(n);
}
Update note: After looking into Vlad from moscow's comment, I moved the last != 0 part of the condition forward, to solve a bug (divide by 0).
The problem Vlad from moscow was talking about is the following: If you want, for example, the part 04 to count as 0, you should use the code as it is above. Otherwise you should remove the secondlast != 0 part.
int countIfDiv(int num) {
int pair = num % 100;
int first = pair / 10;
if (first == 0) return 0;
int second = pair % 10;
int next = num / 10;
return first % second == 0 ? 1 + countIfDiv(next) : 0 + countIfDiv(next);
}
Just pull a pair, try the division, then chop the last number and repeat.
You're not actually updating n value so you get into an infinite loop, on the other hand, your function is, initially, only designed for 3 digits number. I think that it should be something similar to:
int fun(int n, int ant, int count){
if( n == 0 )
return count;
if (ant != 0 &&
(n%10) % ant == 0)
count++;
return fun(n/10, n%10, count);
}
I should work with different number of digits.
The valid code will be
size_t fun( int n )
{
const int base = 10;
int digit = n % base;
n /= base;
return ( n == 0 ?
0 :
( digit && n % base && !( n % base % digit ) ) + fun( n ) );
}