Summing two numbers recursively digit by digit in C - c

I need to write to recursive functions, where in the first one, I need to sum two integers digit by digit. I have written some code, but it gives me the final result multiplied by 10. I see that the problem happens because when I sum first two digits I multiply them by 10.
The second function must count number of carries in the sum. Meaning if two digits were 3 and 8, then when we sum them we get 11, which is result 1, and carry 1. Simply, I just need to count how many carries occur.
Please note that I assume that both numbers have same number of digits.
#include <stdio.h>
int sum(int a, int b)
{
int temp = (a%10) + (b%10);
static int mul = 1;
if(a == 0 && b == 0)
return 0;
else
{
mul *= 10;
return (mul*temp) + sum(a/10, b/10);
}
}
int carry(int a, int b)
{
static int counter = 0;
if((a%10) + (b%10) > 9)
counter++;
if(a == 0 && b == 0)
return counter;
carry(a/10, b/10);
}
int main()
{
int a = 1941;
int b = 2282;
int result = sum(a, b);
printf("%d\n", result);
int car = carry(a, b);
printf("%d\n", car);
return 0;
}

return (mul*temp) + sum(a/10, b/10);
Should be:
return temp + 10*sum(a/10, b/10);
You don't need a static variable, Static variables are used to implement a global state whose lifetime extent the entire process. That's not something desirable and should only be used at last resort. Furthermore, that's definitely not what you need here, using static variables to implement your solution will leads to functions that only work the first time they are called.
You should use the recursive property of your algorithm to aggregate the result:
int sum(int a, int b)
{
if(a == 0 && b == 0) {
return 0;
}
else
{
return (a%10) + (b%10) + 10*sum(a/10, b/10);
}
}
sum(1941, 2282) will expand to :
sum(1941, 2282)
1 + 2 + 10*sum(194, 228)
1 + 2 + 10*(4 + 8 + 10*sum(19, 22))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*sum(1, 2))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*(1 + 2 + 10*sum(0, 0))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*(1 + 2 + 10*0)
You should use the same approach for carry :
int carry(int a, int b)
{
if(a == 0 && b == 0) {
return 0;
}
else if((a%10) + (b%10) > 9) {
return 1 + carry(a/10, b/10);
}
else {
return carry(a/10, b/10);
}
}
carry(1941, 2282) will expand to :
carry(1941, 2282)
0 + carry(194, 228)
0 + 1 + carry(19, 22)
0 + 1 + 1 + carry(1, 2)
0 + 1 + 1 + 0 + carry(0, 0)
0 + 1 + 1 + 0 + 0

Related

Recursion: Collatz sequence -Could someone please explain how this code returns the total number of steps?

#include <cs50.h>
int collatz(int n);
int main(void)
{
int n = get_int("Enter int: ");
int steps = collatz(n);
printf("%i\n", steps);
}
int collatz(int n)
{
if (n==1)
{
return 0;
}
else if ((n%2)==0)
{
return 1 + collatz(n/2);
}
else
{
return 1 + collatz(3 * n + 1);
}
}
I am geting stuck trying to visualise how the 'return 1' on each iteration of the function gets 'carried through'.
I can write the steps out on paper to show that it does work, however I am struggling to make clear in my mind without going through step-by-step, why you have to +1 on every iteration of collatz.
This code:
if (n==1)
{
return 0;
}
says: If there are no steps to perform (because n is already 1), return zero.
Otherwise, this code:
else if ((n%2)==0)
selects one of the following:
return 1 + collatz(n/2);
or:
return 1 + collatz(3 * n + 1);
Each of those performs one step (either n/2 or 3 * n + 1) and then calls collatz to find out how many steps it takes to finish with that value. When collatz returns the number of steps needed for n/2 or 3 * n + 1, this code adds one for the step performed here. That gives the number of steps needed for n, which this code then returns.
Try to visualize it as follows:
starting number: 3
** collatz(3): return 1 + collatz(10); **
collatz(10): return 1 + collatz(5);
** collatz(3): return 1 + (1 + collatz(5)); **
collatz(5): return 1 + collatz(16);
** collatz(3): return 1 + (1 + (1 + collatz(16))); **
collatz(16): return 1 + collatz(8);
** collatz(3): return 1 + (1 + (1 + (1 + collatz(8)))); **
collatz(8): return 1 + collatz(4);
** collatz(3): return 1 + (1 + (1 + (1 + (1 + collatz(4))))); **
collatz(4): return 1 + collatz(2);
** collatz(3): return 1 + (1 + (1 + (1 + (1 + (1 + collatz(2)))))); **
collatz(2): return 1 + collatz(1);
collatz(1): return 0;
** collatz(3): return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0; **

Optimize the Sum of Digits of N

Codewars Question: (Sum of Digits / Digital Root)
Given n, take the sum of the digits of n. If that value has more than one digit, continue reducing in this way until a single-digit number is produced. The input will be a non-negative integer.
Test Cases:
16 --> 1 + 6 = 7
942 --> 9 + 4 + 2 = 15 --> 1 + 5 = 6
132189 --> 1 + 3 + 2 + 1 + 8 + 9 = 24 --> 2 + 4 = 6
493193 --> 4 + 9 + 3 + 1 + 9 + 3 = 29 --> 2 + 9 = 11 --> 1 + 1 = 2
My code:
#include <bits/stdc++.h>
using namespace std;
int singleDigit(int n)
{
int ans;
while (n > 0)
{
int lastDigit = n % 10;
n /= 10;
ans += lastDigit;
}
while (ans > 9)
{
int n1 = ans;
ans = 0;
while (n1 > 0)
{
int lastDigit = n1 % 10;
n1 /= 10;
ans += lastDigit;
}
}
return ans;
}
int main()
{
cout << singleDigit(49319366) << endl;
return 0;
}
Is there a better or optimized way to solve this problem or to reduce time complexity?
This function works for non-negative integers, adapting for negative numbers is straightforward.
int singleDigit(int n)
{
return (n-1) % 9 + 1;
}
It has the following advantages:
no variables to forget to initialise
no loops to commit an off-by-one error
fast
The disadvantages are:
it is not immediately clear how or why it works
For more information on the last bullet point, see:
Direct formulas for the digital root
Modulo operation with negative numbers

Wanted to check if a credit card number is valid or not

I wanted to check if a credit card number is valid or not but when i run the code, every number I give as input, the output comes as invalid.
The example given below is what I should i do.
Example with David’s Visa: 4003600000000014.
For the sake of discussion, let’s first underline every other digit, starting with the number’s second-to-last digit:
4003600000000014
Okay, let’s multiply each of the underlined digits by 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives us:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
Now let’s add those products’ digits (i.e., not the products themselves) together:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
Now let’s add that sum (13) to the sum of the digits that weren’t multiplied by 2 (starting from the end):
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
, the last digit in that sum (20) is a 0, so David’s card is legit!
#include <stdio.h>
int main()
{
int no;
printf("Visa number: ");`
scanf("%d", &no);
int d_1, d_2, d_3, d_4, d_5, d_6, d_7, d_8, d_9, d_10, d_11, d_12, d_13, d_14, d_15;
d_15 = no%10;
d_14 = ((no%100)/10)*2;
d_13 = (no%1000)/100;
d_12 = ((no%10000)/1000)*2;
d_11 = (no%100000)/10000;
d_10 = ((no%1000000)/100000)*2;
d_9 = (no%10000000)/1000000;
d_8 = ((no%100000000)/10000000)*2;
d_7 = (no%1000000000)/100000000;
d_6 = ((no%10000000000)/1000000000)*2;
d_5 = (no%100000000000)/10000000000;
d_4 = ((no%1000000000000)/100000000000)*2;
d_3 = (no%10000000000000)/1000000000000;
d_2 = ((no%100000000000000)/10000000000000)*2;
d_1 = (no%1000000000000000)/100000000000000;
int d[7] = {d_2, d_4, d_6, d_8, d_10, d_12, d_14};
int n,add;
for (n=1; n<=7; n++)
if(d[n]>10)
{
d[n] = (d[n]%10);
d[(15-n)+1] = ((d[n]%100)/10);
int sum=0;
for (int i=0; i<7; i++)
sum += d[i];
}
else
{
add = d_14 + d_12 + d_10 + d_8 + d_6 + d_4 + d_2;
}
int sum = add + d_15 + d_13 + d_11 + d_9 + d_7 + d_5 + d_3 + d_1;
if ((sum % 10) == 0)
{
printf("%s\n", "The card is valid");
}
else
{
printf("%s\n", "The card is invalid");
}
}
every number I give as input, the output comes as invalid.
Too big
OP's int is likely 32-bit.
Reading text input that would attempt to form an int outside the int range is undefined behavior. Rest of code is irrelevant.
int no;
scanf("%d", &no); // attempt to read "4003600000000014" leads to UB.
Consider reading user input into a string first and then process the characters. #Weather Vane
char buf[100];
if (fgets(buf, sizeof buf, stdin)) {
int i;
sum[2] = { 0, 0 }; // sums of even indexed digits and odd indexed digits.
// Note: only 1 sum really needed, but using 2 sums to mimic OP's approach
for (i = 0; isdigit((unsigned char) buf[i]); i++) {
digit = buf[i] - '0';
if (i%2 == 0) {
digit *= 2;
if (digit >= 10) {
digit = (digit/10 + digit%10);
}
}
sum[i%2] += digit;
}
// reject bad input: too long or missing expected end
if (i > 16 || (buf[i] != '\n' && buf[i] != '\0')) {
puts("Bad input");
} else {
// pseudo code to not give everything away.
// do math on sum[0], sum[1]
// if as expected --> success
}
}
#include <stdio.h>
#include <cs50.h>
long credit;
int getting_the_final_total_number (void);
void checking_which_kind (void);
int main(void)
{
credit = get_long("Number: ");
int i = 0;
long number_count = credit;
//finding how many numbers are there.
while(number_count > 0)
{
number_count /= 10;
i++;
}
//we use and because (using or make once true, the code block will work and always telling INVALID)
if(i != 13 && i != 15 && i != 16)
{
printf("INVALID\n");
return 0;
}
int total = getting_the_final_total_number(); //adding sum_1 and sum_2
if(total % 10 != 0)
{
printf("INVALID\n");
return 0;
}
checking_which_kind();
}
//assigning the credit to another variable for the loop
int getting_the_final_total_number (void)
{
long credit_one = credit;
int mod_1;
int mod_2;
int sum_1 = 0;
int m;
int d;
int sum_2 = 0;
do
{
//cutting the number into two pieces with all the last numbers and all the second-last-numbers
//cutting the last numbers.
mod_1 = credit_one % 10;
credit_one = credit_one / 10;
sum_1 += mod_1;
//cutting the second-last-numbers.
mod_2 = credit_one % 10;
credit_one = credit_one / 10;
//doubling the mod_2 (the second-last-numbers)
mod_2 = mod_2 * 2;
//making them into one number (if there is 16 or 18 in the product then make them 1 and 6 or 1 and 8. After that add them all together ).
m = mod_2 % 10; //This is for only one standing numer like 1 or 2 or 9 etc (but no 12 or 14 or 16)
d = mod_2 / 10; //This is for ten's digit to make sure to become ONE standing digit
sum_2 = sum_2 + m + d;
}
while(credit_one > 0);
return sum_1 + sum_2;
}
//checking the first two number of credit
void checking_which_kind (void)
{
long cc = credit;
do
{
cc = cc / 10;
}
while(cc > 100);
if(cc / 10 == 5 && (cc % 10 > 0 || cc % 10 < 6))
{
printf("MASTERCARD\n");
}
else if(cc / 10 == 3 && (cc % 10 == 4 || cc % 10 == 7))
{
printf("AMERICAN EXPRESS\n");
}
else if(cc / 10 == 4 && cc % 10 >= 0)
{
printf("VISA\n");
}
else
{
printf("ERROR");
}
}

Not understand this recursive function that inverts digits of a number

I found this code
#include <stdio.h>
#include <math.h>
int rev(int num)
{
if(num < 10)
return num;
else
return (num % 10) * pow(10, (int)log10(num)) + rev(num/10);
}
int main(void)
{
printf("%d\n", rev(12345));
return 0;
}
And I set out to analyzing it, but now I have one doubt it is the following, to return to the starting point what values are obtained with (num % 10) according to my understanding should be (1,2,3,4,5) but when trying do the calculation manually I do not get the expected value.
What happens here, if someone explains to me this, or I missed out something?
int rev(int num) // num = 12345
{
if(num < 10) // false
return num;
else
return (num % 10) * pow(10, (int)log10(num)) + rev(num/10);
// (12345 % 10) * 10 ^ (log 12345) + rev(12345/10);
// 5 * 10 ^ (4) + rev (1234)
// 50000 + rev(1234)
}
Based on this, we can assume that:
rev(12345) = 50000 + rev(1234)
rev(1234) = 4000 + rev(123)
rev(123) = 300 + rev(12)
rev(12) = 20 + rev(1)
rev(1) = 1
So, the end result is:
rev(12345) = 50000 + 4000 + 300 + 20 + 1 = 54321
It is a simple math, the only non trivial rule is (int)log10(num), but it was explained by #QuestionC in his comment.

Magic in C recursion? who can explain?

Can somebody explain to me how this recursion works?
I'm getting stuck on how the result is 20 when the recursion leaves only on if a == b and it's a = 6 and b = 6
int main()
{
printf("%d \n",mistero(2, 6));
return 0;
}
mistero( a, b)
{
if( a == b ){
return a;
}
return a + mistero(a+1, b);
}
mistero(2, 6) =
2 + mistero(3, 6) =
2 + 3 + mistero(4, 6) =
2 + 3 + 4 + mistero(5, 6) =
2 + 3 + 4 + 5 + mistero(6, 6) =
2 + 3 + 4 + 5 + 6
= 20
Recursion works as below:
2 + mistero(3,6);
2 + 3 + mistero(4,6)
2 + 3 + 4 + mistero(5,6)
2 + 3 + 4 + 5 + mistero(6,6)
2 + 3 + 4 + 5 + 6 = 20
Just execute the code step by step and replace the function call by the return value.
When the function is first called :
return 2 + mistero(3,6);
mistero(3,6) returns 3 + mistero(4,6)
so the return statement eventually continues to get added till a==b
return 2+3+4+5+6
First your function definition has to be before your main, so that at compile time it is known in the main function otherwise you have to use a function prototype!
Also you forgot to define the return type and the types of the arguments. So your code should looks like this to work:
#include <stdio.h>
int mistero(int a, int b) {
//^ ^^^----^^^ variable type
//| Here return type
if( a == b ) {
return a;
}
return a + mistero(a+1, b);
}
int main() {
printf("%d \n",mistero(2, 6));
return 0;
}
Or with a function prototype:
#include <stdio.h>
int mistero(int a,int b);
int main() {
printf("%d \n",mistero(2, 6));
return 0;
}
int mistero(int a,int b) {
if( a == b ){
return a;
}
return a + mistero(a+1, b);
}
And this should show how it works:
return 2 + mistero(2 + 1, b);
return 2 + 3 + mistero(3 + 1, b);
return 2 + 3 + 4 + mistero(4 + 1, b);
return 2 + 3 + 4 + 5 + mistero(5 + 1, b);
return 2 + 3 + 4 + 5 + 6;
= 20
I am guessing the confusing aspect to this is the apparent lack of some sort of loop statement. I.e for or do while statement.
Think of it this way at the very end of the program.
return A + MISTERO(A+1, B) /* IS THE LOOP STATEMENT */
It causes the program to call the function MISTERO (A , B) from within the function MISTERO (A, B). So as long as this occurs you get a round about way of a loop. Until the loop is satisfied in the statement test if(A == B). Then the loop is escaped be a simple return A.
Thanks enjoy programming!!!

Resources