Multiply digits of a number using recursion
I am doing the following exercise:
For a four-digit number such as
3183
, compare each digit with the last, and if greater or equal, multiply by the following
Example: for a number 3183
it will 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 a way to shorten or improve it?
source to share
EDIT I read this yesterday. It doesn't make sense to effectively recreate @ Red Alert's answer, but I can't seem to delete it since it's accepted the way it does.
My guess is that we can create our own "internal" function to maintain state. I also assume the numbers should be handled from the right, the original example is not 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);
}
source to share
After accepting the answer
OP's code not compiled, 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 recommends, keep the results, not recalculate.
#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 do better, I would decrease division and multiplication by 1. But better subjectively for now.
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, a non-recursive loop will be used.
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;
}
source to share
Is it possible to use an intermediate recursive function? This removes the extra math you do 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);
}
source to share