Is my recursion solution to this problems correct? - c

I need to solve this by recursion, here is what they ask to do:
Write a recursion function that takes a positive number and returning the sum(+,-) of its digits from right to left, like this way(for example): the number is 56894, the sum is 4-9+8-6+5=2.
Another example, the number is 7762348, the sum is 8-4+3-2+6-7+7=11.
Does my solution below is correct? I tried compiling it with a lot of numbers and it seems to be correct, but need to be sure.
Here is my recursive solution:
int func(int num){
if(num/10 ==0)
return num;
return (num%10) - func(num/10);
}

Your solution seems to be correct -- the problem asks you to do:
ABCD -> D - C + B - A
But your code does:
ABCD -> (D - (C - (B - A)))
Though it's not hard to show that:
(D - (C - (B - A))) == (D + -1 * (C + -1 * (B - A)) == D - C + B - A
Or some similar informal proof. But is the code considered correct if it computes num/10 twice instead of using a local variable to store the quotient:
int func(int number) {
int quotient = number / 10;
if (quotient == 0) {
return number;
}
return number % 10 - func(quotient);
}
Alternatively, this seems like an opportunity to play with div() and div_t:
#include <stdlib.h> // where div() and div_t are found
int func(int number) {
div_t result = div(number, 10);
if (result.quot == 0) {
return number;
}
return result.rem - func(result.quot);
}
Possibly avoiding yet another division on each iteration.

Related

increment digits of natural number recursively

I wanna make a funcion that will take a natural number and make a new number so every digit in the old number will be incremented and if the digit is 9 it will become zero, but not to check specificly if the digit is 9.
example:
930 will return 41
9999 will return 0
879021 will return 980132.
This is what i got so far:
int newNumber(int n)
{
int dig;
if (n < 9)
return n + 1;
dig = n % 10;
dig++;
n = n / 10;
n = n * 10 + dig;
return newNumber(n/10);
}
There are a couple of issues with your code:
It doesn't handle a single digit of 9 (which cause a stack overflow).
Adding 1 to 9 makes 10 not 0.
I've run it through the sample data you supplied and it seems to work (in C#) and it has a hard core recursive line at the end.
int newNumber(int n)
{
if (n == 9)
return 0;
if (n < 9)
return n + 1;
return (newNumber(n / 10) * 10) + newNumber(n % 10);
}
Here's to avoid the check for n == 9:
int newNumber(int n)
{
static int table[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
return (n <= 9) ? table[n] : (newNumber(n / 10) * 10) + newNumber(n % 10);
}
A lookup table seems the most appropriate and does exactly what the requirements describe. Trying to use the non-compatible arithmetic operators results in side effects (as we see in Bathsheba's answer for example), that then need to be corrected.
unsigned newNumber(unsigned n, unsigned c = 0)
{
return n ? (n + 1) % 10 + 10 * newNumber(n / 10, 1 + c) : !c;
}
is one way, and it will treat 0 as 1, via the !c branch where c counts the number of recursions. Note the tail recursion in the ternary conditional branch - some compilers will optimise a tail recursion out to a simple loop, see What is tail recursion?
Bathsheba's solution posted above is very elegant by using the ternary operator, but it will give you a wrong result if the input is zero. To avoid that you may use a stub function:
#include <stdio.h>
int incDigits(int n)
{
return n ? (n + 1) % 10 + incDigits(n / 10) * 10 : 0;
}
int newNumber(int n)
{
return n ? incDigits(n) : 1;
}
int main()
{
for(int i = 0; i <= 100; ++i)
{
int n = newNumber(i);
printf("%d -> %d\n", i, n);
}
}
EDIT: user meaning-matters also posted a way to fix the input value problem using a lookup table, but he still has to check if n equals 9, which is something you don't want. So I believe using a stub function still is the best way.
Two ternary operator has been used to take care of the two cases:
i) number equal to 9
ii) number not equal to 9 => Another ternary operator is used to take care of further two possible cases:
a) number greater than 9( return sum of num(n/10)*10 and num(n%10) ); this can be further elaborated based on the argument fed to the num function.
b)number smaller than 9(return number plus one(n+1))
Once this function is called from the main function with argument equal to the number to be transformed in the manner asked in the question, each call in line4 will undergo recursion until they pass the argument to the subsequent iteration less than or equal to 9(which leads to termination of the recursion). With basic understanding of recursion, the above para can easily be understood in context to the subroutine below.
Blockquote
int num(int n)//line1
{//line2
int t;//line3
t=(n==9?0:(n>9?num(n/10)*10+num(n%10):n+1));//line4
return t;/line5
}//line6
Blockquote

Can this weird function be directly calculated?

I'd like the calculate this function directly, but the trick has eluded me so far:
uint8_t distance(uint64_t a, uint8_t b) {
// a and b both odd, a at least as large as b
assert((a & 1) && (b & 1) && a >= b);
// really dumb, keep subtracting 2 until you hit a multiple of b
uint64_t distance = 0;
while (a % b != 0) {
distance++;
a -= 2;
}
assert(distance <= 255);
return (uint8_t)distance;
}
Basically the return value is how many times a has to be decremented by 2 to be a multiple of b. This should be true eventually (without wraparound or anything weird) since a and b are odd and a >= b.
If it was "decrement by 1" rather than by 2 the answer would be a simple %...
Performance matters in this case (so for example avoiding unpredictable branches would be nice).
If a % b is even, the result is (a % b) / 2. Otherwise, it's (a % b + b) / 2. You can microoptimize this if you want, but a straightforward implementation is
if ((a % b) % 2 == 0) {
return (a % b) / 2;
} else {
return (a % b + b) / 2;
}
I won't give you a specific microoptimized version, because that's something you should really profile yourself in the context of your application.

Program for finding nth root of the number without any external library or header like math.h

Is there any way to find nth root of the number without any external library in C? I'm working on a bare metal code so there is no OS. Also, no complete C is there.
You can write a program like this for nth root. This program is for square root.
int floorSqrt(int x)
{
// Base cases
if (x == 0 || x == 1)
return x;
// Staring from 1, try all numbers until
// i*i is greater than or equal to x.
int i = 1, result = 1;
while (result < x)
{
if (result == x)
return result;
i++;
result = i*i;
}
return i-1;
}
You can use the same approach for nth root.
Here there is a C implementation of the the nth root algorithm you can find in wikipedia. It needs an exponentiation algorithm, so I also include an implementation of a basic method for exponentiation by squaring that you can find also find in wikipedia.
double npower(double const base, int const n)
{
if (n < 0) return npower(1/base, -n)
else if (n == 0) return 1.0;
else if (n == 1) return base;
else if (n % 2) return base*npower(base*base, n/2);
else return npower(base*base, n/2);
}
double nroot(double const base, int const n)
{
if (n == 1) return base;
else if (n <= 0 || base < 0) return NAN;
else {
double delta, x = base/n;
do {
delta = (base/npower(x,n-1)-x)/n;
x += delta;
} while (fabs(delta) >= 1e-8);
return x;
}
}
Some comments on this:
The nth root algorithm in wikipedia leaves freedom for the initial guess. In this example I set it up to be base/n, but this was just a guess.
The macro NAN is usually defined in <math.h>, so you would need to define it to be suitable for your needs.
Both functions are implemented in a very rough and simple way, and their performance can be greatly improved with careful thought.
The tolerance in this example is set to 1e-8 and should be changed to something different. It should probably be proportional to the value of the base.
You can try the nth_root C function :
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = n, b, c, r = nth ? n + (n > 1) : n == 1 ;
for (; a < r; b = a + (nth - 1) * r, a = b / nth)
for (r = a, a = n, c = nth - 1; c && (a /= r); --c);
return r;
}
Source

Unexpected error for recursive collatz implementation

EDIT: When I upload the code to the automatic testing platform the program doesn't crash there - it returns the correct result, but takes too long (exceeds 5 seconds)... wtf...
For university I have to implement a function that returns the number of steps taken from the input to reach 1, by following the collatz conjecture. The conjecture is very simple - given any integer number:
1. If it is even - divide it by two (n/2)
2. If it is odd - times it by 3 and add one (n*3+1)
The conjecture is that all numbers will eventually reach 1. We don't have to prove or check this, we just need to return the steps taken for a given number.
We have done this problem before, but this time we must check much larger numbers (they specify to use long instead of int) AND use recursion. They have given us skeleton code, and asked us to implement only the function - so all of my code is contained inside
int lengthCollatz(long n) { //mycode }
The skeleton code in the main collects two input values - a and b, where a < b <100000000. It checks how many steps it takes for each number between a and b, following the collatz sequence, to reach 1, and then returns the number with the highest amount of steps taken.
The function I added seems to work perfectly fine, but at larger values (when input 2 is in the millions) it seems to crash for no reason and gives no error. I've tried changing everything to unsigned longs and even long longs to see if something is overflowing - in that case the program just gets stuck... I don't understand what's wrong, please help me diagnose the error. P.S. How can I improve the speed of these calculations? We have a limit of 5 seconds.
All of my code is inside the lengthCollatz function (and the length global variable just above it) Can you identify the problem?
#include <stdio.h>
#define MAX64 9223372036854775807L /* 2ˆ63 -1 */
int length = 0;
int lengthCollatz(long n) {
length++;
//if not 1
if(n!=1){
//if odd
if(n&1) {
lengthCollatz(n=n*3+1);
}
//if even
else {
lengthCollatz(n/=2);
}
}
//if reached n = 1
else {
//return amount of steps taken
int returnLength = length;
length = 0;
return returnLength;
}
}
int main(int argc, char *argv[])
{
int n, a, b, len=-1;
scanf ("%d %d", &a, &b);
while (a <= b) {
int l = lengthCollatz(a);
if (l > len) {
n = a;
len = l;
}
a++;
}
printf("%d\n", n);
return 0;
}
Updated function:
int lengthCollatz(long n) {
if(n==1){
//return depthRecursion;
}
else {
if(n&1) {
n=n*3+1;
}
else {
n/=2;
}
return lengthCollatz(n);
}
}
Here's one alternative version which does not segfault for the input range given by OP:
int collatz(unsigned long n)
{
if (n == 1)
return 1;
else if (n & 1)
return 1 + collatz(n * 3 + 1);
else
return 1 + collatz(n >> 1);
}
AFAICT, it works OK, but it's very slow. 29 seconds on my mediocre PC. An optimized version runs two seconds faster by not calling itself when the result can be precomputed, but that version borders on manual loop unrolling. FWIW:
int collatz(unsigned long n)
{
if (n == 1)
return 1;
if (n & 1)
return 2 + collatz((n * 3 + 1) >> 1);
// Is n dividable by 16?
if (n & 0xF == 0)
return 4 + collatz(n >> 4);
// Is n dividable by 8?
if (n & 0x7 == 0)
return 3 + collatz(n >> 3);
// Is n dividable by 4?
if (n & 0x3 == 0)
return 2 + collatz(n >> 2);
return 1 + collatz(n >> 1);
}
There are of course other ways to solve this, but to finish in five seconds? Please post the solution if you find one.

If condition on modulo, failing logical condition?

I wanted to check if a fraction 2 4 (for example) can be simplified to 1 2!!
However logical condition fails.
#include <stdio.h>
int main()
{
int a,b,live=1;
printf("\n\nInput integers for fraction:");
scanf(" %d%d",&a,&b);
while(live){
if(!(a%2 && b%2)){
a/=2;
b/=2;
}else if(!(a%3 && b%3)){
a/=3;
b/=3;
}else if(!(a%5 && b%5)){
a/=5;
b/=5;
}else if(!(a%7 && b%7)){
a/=7;
b/=7;
}else live--;
}
printf("Simplified Fraction is %d/%d",a,b);
}
The condition a%2 is equivalent to a%2 != 0, i.e. it tests if a is not divisible by 2. From De Morgan's Laws, the condition if(!(a%2 && b%2)) is equivalent to if(!(a%2) || !(b%2)) or if((a%2 == 0) || (b%2 == 0)), which is not what you want.
You really want to test if((a%2 == 0) && (b%2 == 0)) -- that is, if both are divisible by 2, not if either is divisible by 2. Writing it this way is also much less confusing.
And it should also be obvious that in order to simplify any fraction, you need to test for all possible prime factors, which is impossible to do with a finite number of if statements. The recommended way of doing this is to use the Euclidean algorithm to determined the greatest common divisor of the numerator and denominator, and then you divide both by the GCD to get the fraction in reduced form.
(!(a%2 && b%2)) will yield true even if only one of a%2 or b%2 holds.
Have a look at the following example:
3/4 -> a%2 == 0, b%2 == 1 -> (a%2 && b%2) == 0 -> (!(a%2 && b%2)) == 1
You are looking for (a%2 == 0 && b%2 == 0) instead of your condition, and similarly for other conditions.
An "after an accepted answer" answer.
This does not detail the issues with OP's code nicely like #Adam Rosenfield, but does address the larger OP desire of "I wanted to check if a fraction 2 4 (for example) can be simplified to 1 2!!" in a general way.
Use the Euclidean Algorithm to find the greatest-common-denominator, then divide a,b by it. No need to generate prime number list. Very fast.
// Euclidean Algorithm
unsigned gcd(unsigned a, unsigned b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
#include <stdio.h>
int main() {
int a, b;
for (;;) {
printf("\nInput positive fraction like 12/30: ");
if (scanf("%u/%u", &a, &b) != 2)
break;
unsigned g = gcd(a, b);
a /= g;
b /= g;
printf("Simplified Fraction is %u/%u", a, b);
}
return 0;
}
In addition to the logical or issue identified by others, you also have an infinite loop with your while condition. You don't need (or want) to loop with your current code. Try this
#include <stdio.h>
int main ()
{
int a, b;
printf ("\n\nInput integers for fraction:");
scanf (" %d%d", &a, &b);
while (a % 2 == 0 && b % 2 == 0)
{
a /= 2;
b /= 2;
}
while (a % 3 == 0 && b % 3 == 0)
{
a /= 3;
b /= 3;
}
while (a % 5 == 0 && b % 5 == 0)
{
a /= 5;
b /= 5;
}
while (a % 7 == 0 && b % 7 == 0)
{
a /= 7;
b /= 7;
}
printf ("Simplified Fraction is %d/%d", a, b);
}
Output(s) with your given input(s)
Input integers for fraction:2 4
Simplified Fraction is 1/2
Input integers for fraction:8 24
Simplified Fraction is 1/3

Resources