A little confused on this recursion example - c++

int gcd (int a, int b)
{
if (b == 0)
return a;
if (a == 0)
return b;
return gcd (b, a % b);
}
What is the result of gcd (5, 15)?
I ended up getting 15 but I'm not sure if it's correct, all the loops are confusing me.

Here are the recursive calls that are made in order
gcd(5, 15)
gcd(5, 5) # Because 5 % 15 = 5
gcd(5, 0)
So the return value of gcd(5, 15) is 5

Let a = 5 and b = 15;
In the first loop we check if either of a and b are 0 , they are not so we call
gcd(15,0); because 5%15 = 5.
So a = 15 , b = 5.
we call gcd(5,15%5) i.e gcd(5,0).
The answer is 5;

See the recursive calls in this way:
gcd(5, 15)
|
gcd(15, 5 (as 5 % 15) ) // 'b' simply takes position of 'a'
|
gcd(5, 0 (as 15 % 5) )
|
if (b == 0) return a; // a is 5, so returned value is 5.
return 5;
return 5;
return 5;

gcd (5, 15) returns gcd (15, 5 % 15) == gcd (15, 5), which in turn returns gcd (5, 5 % 15) == gcd (5, 5), which returns gcd (5, 5 % 5) == gcd (5, 0) == 5. So you should be returning 5.
A good way to see what's happening is to insert printf statements at the beginning of the function and at the two final return points showing what happens:
gcd(5,15)
gcd(15,5)
gcd(5,0)
5
An example Python implementation:
def gcd (a, b):
print("gcd({0},{1})".format(a, b))
if b == 0:
print(a)
return a
if a == 0:
print(b)
return b
return gcd (b, a % b)
gcd(5,15)

Related

Functionality of a recursion function in C++

I found a recursion function in GeeksforGeeks website. Can someone explain how this function works?
int fun1(int x, int y)
{
if(x == 0)
return y;
else
return fun1(x - 1, x + y);
}
It says it will return y+(x+x-1+x-2+x-3+...2+1). I appreciate if someone can explain why. I thought it should return y+1 as when x becomes 1 on stack memory, it will return y+1 (since x-1 becomes 0), and eventually it will return the other functions on stack as y+1 until the early first function.
You're right that when x == 1, this returns y+1. But for the other cases, remember that y is also different between the calls. For example, when x==2, it calls fun1(2 - 1, 2 + y), so for the next invocation y is two more than it was before. This next invocation has x == 1, so it ends up returning one more than the y it has, which itself is 2 more than the original value, so the call to fun1(2, y) returns y + 2 + 1.
An illustration of the call stack might be more helpful. Let's say we call fun1(5, 7).
fun1(5, 7) returns the value of fun1(5 - 1, 5 + 7)
fun1(4, 12) returns the value of fun1(4 - 1, 4 + 12)
fun1(3, 16) returns the value of fun1(3 - 1, 3 + 16)
fun1(2, 19) returns the value of fun1(2 - 1, 2 + 19)
fun1(1, 21) returns the value of fun1(1 - 1, 1 + 21)
fun1(0, 22) returns 22.
Thus, all together (and rearranging slightly), the fun1(5, 7) call returned 7 + (5 + 4 + 3 + 2 + 1), as the documentation said.
The function fun() calculates and returns ((1 + 2 … + x-1 + x) +y) which is x(x+1)/2 + y. For example if x is 5 and y is 2, then fun() should return 15 + 2 = 17.

rand() produces 1 number too high?

It is my understanding that rand() % a + b will return numbers between a and b including both a and b. I must be misunderstanding this though, because when I run the code below int r will return 2, 3, or 4. I, of course, am expecting it to return 2 or 3. I'm calling srand(time(NULL)); in main and I'm using
#include <time.h> and #include <stdlib.h>
Am I missing something?
int r = (rand() % 3) + 2;
if (r ==2)
g_fan.draw(r); // skin == 2
else
g_fan.draw(1 + r); //skin == 4
It is my understanding that rand() % a + b will return numbers between a and b including both a and b.
No. It will result in a number between b and (a+b-1), both including.
Range of values of rand() % a is 0 and a-1, both including.
Hence, the range of values of rand() % a + b is b and (a-1+b), both including.
To get random values between a and b, both including, use:
auto interval = (b-a+1);
auto result = a + rand() % interval;
let num be any number you get by calling rand() and if you do % with 3 , there is a possibility of getting one of these number 0, 1, 2.
therefore you are getting 2 ,3, 4 for :
int r = (rand() % 3) + 2;
int r = (rand() % 3) + 2;
The rand() % 3 will return a number between 0 and 2. When you add t2 to each number, that means it will return 2 to 4. The rand() % afunction in general returns a value form 0 to a - 1. When you do rand() % a + b, then the resulting value will range from 0 + b to a - 1 + b.
To get a value between 2 and 3, use:
int r = (rand() % 2) + 2;
The folloing rand() function gives a number from 0 to 2 - 1, which is 1. When you add 2 to each number, you get a range of 0 + 2, which is 2, to 2 - 1 + 2, which is 3.

(3^n + 2^n) % 10 for large n

So I have a number N that has maximum 9 digits and I have to get the last digit of 3^n + 2^n. Is there a rule for this kind of problem? The code I have so far:
#include <fstream>
#include <algorithm>
#include <math.h>
using namespace std;
ifstream fin("input.in");
ofstream fout("input.out");
int main(){
int n;
fin>>n;
fout<<fmod(pow(3,n)+pow(2,n),10);
}
However, If I use this and n is greater than 1000 it displays nan.
My question is: Is there a rule to such a problem?
Well, we know that (3^n + 2^n) % 10 = ((3^n % 10) + (2^n % 10)) % 10, so we can use Modular Exponentation to quickly solve this.
The basic premise is that 3^n % 10 = (3 * (3^(n-1) % 10)) % 10
Well, the easiest answer is the following:
3^0 === 1;
3^1 === 3;
3^2 === 9;
3^3 === 7;
3^4 === 1;
3^5 === 3;
So, 3^n has last digit of 3, 9, 7 or 1, based on N. So,
N%4 == 0 => last digit of 3^n is 1, == 1 =>3, == 2 => 9, == 3 => 7.
You can write out the same for 2^n:
1, 2, 4, 8, 6, 2, ...
This cycle can be repeated all the time, ruling out the primary rule: last digit for 2^n is:
N == 0 => 1
N > 0 =>
(N - 1) % 4 == 0 => 2
(N - 1) % 4 == 1 => 4
(N - 1) % 4 == 2 => 8
(N - 1) % 4 == 3 => 6
After you calculated the last digit for both 3^n and 2^n, just add them together.
You can solve it mathematically. Let's look at the sequence un = 3^n % 10: u0 = 1, and then 3, 9, 7, and 1 again. It gives immediately:
u4k = 1, u4k+1 = 3, u4k+2 = 9, u4k+3 = 7
Now look at vn = 2n % 10: v0= 1 and then 2,4,8,6, and 2 again. It gives that for k > 0:
v4k = 6, v4k+1 = 2, v4k+2 = 4, v4k+3 = 8
You immediately have the result: for N > 1 just look at N' = N%4, and the results are respectively 7, 5, 3, 5
In C++, it will give:
#include <fstream>
using namespace std;
ifstream fin("input.in");
ofstream fout("input.out");
int main(){
int n;
fin>>n;
int result[] = { 7,5,3,5};
fout<<(n == 0) ? 2 : result[n%4];
return 0;
}

Can't finish a mathematical project

I am new to coding and I am finding this site really helpful. So I have been trying to solve this problem and I am getting erroneous results, so I would be really grateful if you could help me out here.
The Problem: Find the sum of all the multiples of 3 or 5 below 1000. (For example, if we list all the positive integers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9, which sum is 23.)
My code:
count = 0
count1 = 0
for x in range(1000):
if x % 5 == 0:
count = count + x
if x % 3 == 0:
count1 = count1 + x
print count1 + count
What am I doing wrong?
Thanks in advance!
You want an elif in your code so you don't count the same x twice but a simpler way is to use an or with a single count variable:
count = 0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
count += x
Which can be done using sum:
print(sum(x for x in range(3, 1000) if not x % 5 or not x % 3))
For completeness, a working version using your own code:
count = 0
count1 = 0
for x in range(1000):
if x % 5 == 0:
count += x
elif x % 3 == 0:
count1 += x
print count1 + count
ifs are always evaluated; so, for instance, when x is 15 it is evenly divisible by 5 and 3 so you count 15 twice, an elif is only evaluated if the previous if/elif evaluates to False so using elif only one occurrence of x will be added to the total.
Below 10 there is no number being multiple of both 5 and 3. But below 1000 there are several numbers divided exactly by 3 and 5 also (15, 45 ...).
So you need:
count=0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
count=count + x
print count

Partitioning arrays by index

I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.