Recurrence relation of recursive function that contains while loop - c

I have a recursive function int digit_sum(int number); that returns the sum of all the digits in the number. For example, digit_sum(159) = 1 + 5 + 9 = 15.
Here is the function:
int digit_sum(int n)
{
if (n < 0)
n = -n;
if (n < 10)
return n % 10;
while (n % 10 == 0 && n > 0)
n = n / 10;
return n % 10 + digit_sum(n - (n % 10));
}
I'm not sure exactly how to write a recurrence relation for this function. I know that T(0) is the sum of the first two if statement constants. However, with T(n), I am unsure how to express the while loop term and T(n-k).
The modulo operators are throwing me off. This is a guess, and I'm fairly certain this is wrong:
T(n) = c_1 + c_2 + c_3*n (while loop) + (n mod 10 + T(n - (n mod 10))) for n >= 10
I know that the entire T(n-k) term is wrong.

Here is a possible solution:
#include <stdio.h>
int digit_sum(int n)
{
if (n < 0)
return digit_sum(-n);
if (n < 10)
return n;
return (n % 10) + digit_sum(n / 10);
}
int main(int argc, char *argv[])
{
printf(" 9->%d\n", digit_sum(9));
printf(" 59->%d\n", digit_sum(59));
printf(" 159->%d\n", digit_sum(159));
printf("-159->%d\n", digit_sum(-159));
}

Related

unexpected output -scanf and function check

So i am trying to write this program but i get 10 no matter what the input is. My function seems correct to me so is it a scanf issue?
Write a program to input 10 integers and decide how many of them satisfy the
following rule:
abcd = (ab + cd)2 e.g. 3025=(30+25)
Use a function that receives an integer parameter returns 1 if it satisfies the above
rule, returns 0 otherwise.
int check(int n);
int main(void)
{
int n, i, j = 0;
printf("Input 10 integers: ");
for (i = 0; i < 10; i++)
{
scanf("%d", &n);
if (check(n) == 1)
{
j++;
}
}
printf("%d\n", j);
}
int check(int x)
{
if (((x / 100) + (x % 100)) * ((x / 100) + (x % 100)))
{
return 1;
}
else
{
return 0;
}
}
The issue I think is the check function,
if (((x / 100) + (x % 100)) * ((x / 100) + (x % 100))) // <---- anything not zero will be true
{
return 1;
}
The expression inside if will convert any integer which is not zero to true. The expression as it is written is if (x * x) which only false if x == 0.

Sum of Digits of a Five Digit Number in c?Could you spot the error?

BTW I know that's not the most efficient way to do it but if I wanted to do it like I did, what did I do incorrectly? The task was: Given a five digit integer, print the sum of its digits.
Constraint: 10000 <= n <= 99999
Sample Input: 10564
Sample Output: 16
My code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int n, sum;
int remainder_array[4] = { n % 1000; n % 100, n % 10, n };
int digits_array[4];
scanf("%d", &n);
// Complete the code to calculate the sum of the five digits on n.
if (10000 <= n && n <= 99999) {
else if (remainder_array[0] = 0) {
digits_array[0] = (n - remainder_array[0]) / 1000;
n = remainder_array[1];
} else if (remainder_array[1] != 0) {
digits_array[1] = (n - remainder_array[1]) / 100;
n = remainder_array[2];
} else if (reminder_array[2] != 0) {
digits_array[2] = (n - remainder_array[2]) / 10;
n = remainder_array[3];
} else if (reminder_array[3] != 0) {
digits_array[3] = n - remainder_array[3];
} else {
printf("%d", n / 1000);
}
sum = digits_array[0] + digits_array[1] + digits_array[2] + digits_array[3];
printf("%d", sum);
}
return 0;
}
your algorithm is far too complicated, It can be done much easier way without arrays.
int sumof5LSD(int x)
{
int result = 0;
for(int digit = 1; digit <=5; digit++)
{
result += abs(x % 10);
x /= 10;
}
return result;
}
int main(void)
{
printf("SUM: %d", sumof5LSD(10564));
}
https://godbolt.org/z/bcdM8P
or if you are not allowed to use loops:
int sumof5LSD(int x)
{
int result = 0;
result += abs(x % 10);
x /= 10;
result += abs(x % 10);
x /= 10;
result += abs(x % 10);
x /= 10;
result += abs(x % 10);
x /= 10;
result += abs(x % 10);
return result;
}
It is good to use functions to perform similar tasks.
Version with scanf
int main(void)
{
int n;
scanf("%d", &n);
printf("SUM of 5 digits of %d = %d", n, sumof5LSD(n));
}
it will also calculate the sum of 5 digits of the negative number
There are multiple issues in your code:
you initialize remainder_array from the value of n before reading the value of n.
the initializer is incorrect: the separator should be ,, not ;.
you start the statement inside the if body with else, which is a syntax error.
the test if (remainder_array[0] = 0) sets remainder_array[0] to 0 and evaluates to false.
remainder_array is misspelt a reminder_array
Your approach is fine, but you should intialize remainder_array with the actual remainders (5 of them), after reading and checking n:
#include <stdio.h>
int main() {
int n;
if (scanf("%d", &n) == 1 && 10000 <= n && n <= 99999) {
int remainder_array[5] = { n / 10000, n / 1000 % 10, n / 100 % 10, n / 10 % 10, n % 10 };
int sum = remainder_array[0] + remainder_array[1] + remainder_array[2] +
remainder_array[3] + remainder_array[4];
printf("%d\n", sum);
}
return 0;
}
Note that you don't actually need this remainder_array, you could just write:
#include <stdio.h>
int main() {
int n;
if (scanf("%d", &n) == 1 && 10000 <= n && n <= 99999) {
int sum = n / 10000 + n / 1000 % 10 + n / 100 % 10 + n / 10 % 10 + n % 10;
printf("%d\n", sum);
}
return 0;
}
Here is a more readable and more generic version:
#include <stdio.h>
int main() {
int n;
if (scanf("%d", &n) == 1 && 10000 <= n && n <= 99999) {
int sum = 0;
while (n >= 10) {
sum += n % 10;
n = n / 10;
}
sum += n;
printf("%d\n", sum);
}
return 0;
}
Apart from the errors and modifications what #P_J_ and #chqrlie has mentioned I have noticed some major logical errors and misunderstanding of a basic concept in your code(assuming that first else if is replaced by if)
you have given else if statement repeatedly, now what this does is that whenever the first condition it encounters is true it executes the block inside and exits from the branch i.e remaining statements after else if is not executed, this might cause a major logical error in your program.
if (10000 <= n && n <= 99999) {
else if (remainder_array[0] = 0) {
digits_array[0] = (n - remainder_array[0]) / 1000;
n = remainder_array[1];
} else if (remainder_array[1] != 0) {
digits_array[1] = (n - remainder_array[1]) / 100;
n = remainder_array[2];
} else if (reminder_array[2] != 0) {
digits_array[2] = (n - remainder_array[2]) / 10;
n = remainder_array[3];
} else if (reminder_array[3] != 0) {
digits_array[3] = n - remainder_array[3];
} else {
printf("%d", n / 1000);
}
Now in this picture if you notice the output you can see that the digits_array[1-3] are 0 this is because of the reason mentioned above(it is zero cause I have initialized it beforehand) hence the sum is zero.
And the second logical error is that you are dividing a 5 digit number by 1000 this will give you thousand's place i.e in example 10546 this step will result in 10 this is wrong, take another example 12233 not the sum for the digits should result in 11 but you will get 20 because when you divide 12233 by 1000 the first value of digits_array (digit_array[0]) is 12 so the entire output goes wrong. so to correct this divide it by 10000 (only for this program statement as it has 5 digits).
But still, if you wish to continue without changing the algorithm then this code should work fine.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int n, sum;
int digits_array[5]={0}; //5 because it is a five digit number.
scanf("%d", &n);
int remainder_array[] = { n % 1000, n % 100, n % 10, n };//This is still a useless array this is kept so as to enter if.
// Complete the code to calculate the sum of the five digits on n.
if (10000 <= n && n <= 99999) {
if (remainder_array[0] != 0) {
digits_array[0] = (n) / 10000;//subtracting n with contents of remainder_array added to the complexity of the algorithm so took out the statement.
n =(n)%10000;
} if (remainder_array[1] != 0) {
digits_array[1] = (n) / 1000;
n =(n)%1000;
} if (remainder_array[2] != 0) {
digits_array[2] = (n) / 100;
n =(n)%100;
} if (remainder_array[3] != 0) {
digits_array[3] = (n)/10;
n=(n)%10;
}
digits_array[4]=n;//the last element of the number
}
sum = digits_array[0] + digits_array[1] + digits_array[2] + digits_array[3]+digits_array[4];
printf("%d",sum);
return 0;
}
Note: This program is not the best way and some changes are made refer to other answers for a more effective code and get the basics right before going to nested if condition.
Enjoy coding

Math. Sorting. Do "n * (n + 1) / 2" always less than "n * n"? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
Please see code below. The code sorts an array in exactly n * (n + 1) / 2 iterations. I took the formula from Wikipedia 1 + 2 + 3 + 4 +.... No need to prove it, lets assume it just works.
#include <stdio.h>
int A[] = {3,1,4,8,6,17};
int nruns = 0;
#define N sizeof(A) / sizeof(int)
int imin(int idx){
int im = idx;
for(int i = idx; i < N; ++i, ++nruns)
if(A[i] < A[im])im = i;
return im;
}
int swap(li, ri){
int t = A[li];
A[li] = A[ri];
A[ri] = t;
return 0;
}
int main()
{
int im;
for(int i = 0; i < N; ++i){
im = imin(i);
swap(i, im);
}
for(int i = 0; i < N; ++i)
printf("%d ", A[i]);
printf("\nN = %d\nN*N = %d\nnruns = %d\n", N, N*N, nruns);
/*
(n*n + n) / 2 < n*n
Is above always true ?
*/
return 0;
}
This code at OnlineGDB
My question is, is it always true that "n * (n + 1) / 2" is less than "n * n" ?
Suppose n > 0. Then, if n * (n + 1) / 2 < n * n is true, (n + 1) / 2 < n is also true, thus, n + 1 < 2 * n, so n > 1. If (n > 0) AND (n > 1), then n > 1.
Suppose n < 0. Then, if n * (n + 1) / 2 < n * n is true, (n + 1) / 2 > n is also true, thus, n + 1 > 2 * n, so n < 1. If (n < 0) AND (n < 1) then n < 0.
Which means that this is true if (n > 1) OR (n < 0).
Suppose n is real and n < 0 or n > 1.
n•(n+1)/2 < n2 if and only if there is a positive h such that n•(n+1)/2 + h = n2.
So h would be n2 − n•(n+1)/2. Is this positive? It equals n2/2 − n/2. If n < 0, both n2/2 and n/2 are positive, so h is positive. If n > 1, n2/2 − n/2 = n•(n−1)/2, and both n and (n−1)/2 are positive, so h is positive. So, for n < 0 or n > 1, n•(n+1)/2 < n2.
On the other hand, if 0 ≤ n ≤ 1, we have h = n•(n−1)/2, and we can see that n is positive or zero while (n−1)/2 is negative or zero, so h is not positive, so n•(n+1)/2 ≥ n2.

sum-digits function - C language

Digits Sum function
I have to write a function - digits sum,
for ex.: the number : 9887, 9+8+8+7= 32 , 3+2= 5
Will this function work well?
int sum_digits(int num){
if (num < 10)
return num;
int a = sum_digits (num / 10) + num % 10;
if (a > 9)
a = sum_digits (a / 10) + a % 10;
return a;
}
int sum_digits(int num){
if (num < 10)
return num;
int a = sum_digits (num / 10) + num % 10;
if (a > 10)
a += sum_digits (a / 10) + a % 10;
return a;
}
This will work.
Note that a= is replaced by a+= and a>9 is replaced by a>10

Multiply digits of a number using recursion

I am doing the following exercise:
Given a four digit number such as 3183, compare each digit with the last and if greater or equal multiply it with the following
Example: for the number 3183 it would be n = 3*8*3 = 72.
My code:
#include <stdio.h>
int f ( int n )
{
if ( n < 10 )
return n ;
return (((n/10) % 10) >= (n%10) ? ((n/10)10) : 1) * f((n/100 )* 10 + n % 10 ) ;
}
int main()
{
printf( "%d", f( 3183 );
return(0);
}
Is there any way to shorten it or make it better?
Leave another approach more compacted than the original:
#include <stdio.h>
int f (int n, int u)
{
if (u > n) return(1);
return (n % 10 >= u ? n % 10 : 1) * f(n/10, u);
}
int main (void)
{
int n = 3284;
printf ("%d", f (n , n%10));
return(0);
}
EDIT I mis-read this yesterday. No point in effectively re-creating #Red Alert's answer now, but I can't delete it either since't it's accepted so here goes.
I assume we can create our own "inner" function to maintain state. I also assume digits are to be processed from the right, the original example isn't clear.
static int g(int n, int ack, int last)
{
const int here = n % 10;
const bool mult = here >= last;
if(n < 10)
return mult ? here * ack : here;
return g(n / 10, mult ? here * ack : ack, here);
}
int f(int n)
{
return g(n, 1, 0);
}
After accept answer
OP's code fails to compile, missing %
// (((n/10) % 10) >= (n%10) ? ((n/10) 10) : 1) * f((n/100 )* 10 + n % 10 ) ;
return (((n/10) % 10) >= (n%10) ? ((n/10)%10) : 1) * f((n/100 )* 10 + n % 10 ) ;
As #interjay recommend, save results rather than recalculating.
#include <stdio.h>
int f(int n) {
if (n < 10)
return n;
int lastdigit = n % 10;
int nextlastdigit = (n / 10) % 10;
return (nextlastdigit >= lastdigit ? nextlastdigit : 1)
* f((n / 100) * 10 + lastdigit);
}
int main(void) {
printf( "%u", f(2183); // --> 24
return(0);
}
To make better, I would reduce division calls and multiplication by 1. But better is subjective at this point.
unsigned cheroky(unsigned x) {
if (x < 10)
return x;
unsigned lastdigit = x % 10;
unsigned firstdigits = x / 10;
unsigned lastfirstdigit = firstdigits % 10;
unsigned nextx = firstdigits - lastfirstdigit + lastdigit;
unsigned product = cheroky(nextx);
if (lastfirstdigit >= lastdigit)
product *= lastfirstdigit;
return product;
}
To really improve, would use a non-recursive loop.
unsigned cheroky2(unsigned x) {
unsigned lastdigit = x % 10;
unsigned product = lastdigit;
while (x >= 10) {
x /= 10;
unsigned nextdigit = x % 10;
if (nextdigit >= lastdigit)
product *= nextdigit;
}
return product;
}
Are you allowed to use an intermediate recursive function? This eliminates the extra math you are doing to maintain the state of the last digit:
int f2 ( int n, int lastDigit )
{
int currentDigit = n%10;
int returnDigit = currentDigit;
if(currentDigit < lastDigit)
returnDigit = 1;
if(n < 10)
return returnDigit;
return returnDigit * f2(n/10, lastDigit );
}
int f ( int n )
{
if ( n < 10 )
return n ;
return n%10* f2(n/10, n%10);
}

Resources