Tracing simple recursive function - c++

I am getting closer to debunking this recursive mystery, there is only one thing left that I can not trace in this line of the code, and that is the final return value wich is 243 if i call rec() passing it the value 5. this should be the trace:
n: 4 *3: 12
n: 3 *3: 9
n: 2 *3: 6
n: 1 *3: 3
n: 0 *3: 0
n: 1 *3: 3
result: 243
Correct? how does it get the result of 243?
int rec(int n)
{
if (n == 0)
return 1;
return 3 * rec(n-1);
}

Your function computes : 3^n.
The number 3 is multiplied with the result of the n-1 calls.
f(n) = 3 * f(n-1);
f(0) = 1;
f(1) = 3 * f(0) = 3 * 1 = 3;
f(2) = 3 * f(1) = 3 * 3 = 9;
f(3) = 3 * f(2) = 3 * 3 * f(1) = 3 * 3 * 3 = 27
.
.
.
f(5) = 3 * 3 * 3 *3 * 3 = 243

This function computes
3^n where n >= 0
If you pass 5 it computes 3 * 3 * 3 * 3 * 3 * (1) = 243

It does only multipling on 3, four times:
return 3 * rec(n-1);
I think you wanted something like this:
return n * rec(n-1);

Related

A many-to-one mapping in the natural domain using discrete input variables?

I would like to find a mapping f:X --> N, with multiple discrete natural variables X of varying dimension, where f produces a unique number between 0 to the multiplication of all dimensions. For example. Assume X = {a,b,c}, with dimensions |a| = 2, |b| = 3, |c| = 2. f should produce 0 to 12 (2*3*2).
a b c | f(X)
0 0 0 | 0
0 0 1 | 1
0 1 0 | 2
0 1 1 | 3
0 2 0 | 4
0 2 1 | 5
1 0 0 | 6
1 0 1 | 7
1 1 0 | 8
1 1 1 | 9
1 2 0 | 10
1 2 1 | 11
This is easy when all dimensions are equal. Assume binary for example:
f(a=1,b=0,c=1) = 1*2^2 + 0*2^1 + 1*2^0 = 5
Using this naively with varying dimensions we would get overlapping values:
f(a=0,b=1,c=1) = 0*2^2 + 1*3^1 + 1*2^2 = 4
f(a=1,b=0,c=0) = 1*2^2 + 0*3^1 + 0*2^2 = 4
A computationally fast function is preferred as I intend to use/implement it in C++. Any help is appreciated!
Ok, the most important part here is math and algorythmics. You have variable dimensions of size (from least order to most one) d0, d1, ... ,dn. A tuple (x0, x1, ... , xn) with xi < di will represent the following number: x0 + d0 * x1 + ... + d0 * d1 * ... * dn-1 * xn
In pseudo-code, I would write:
result = 0
loop for i=n to 0 step -1
result = result * d[i] + x[i]
To implement it in C++, my advice would be to create a class where the constructor would take the number of dimensions and the dimensions itself (or simply a vector<int> containing the dimensions), and a method that would accept an array or a vector of same size containing the values. Optionaly, you could control that no input value is greater than its dimension.
A possible C++ implementation could be:
class F {
vector<int> dims;
public:
F(vector<int> d) : dims(d) {}
int to_int(vector<int> x) {
if (x.size() != dims.size()) {
throw std::invalid_argument("Wrong size");
}
int result = 0;
for (int i = dims.size() - 1; i >= 0; i--) {
if (x[i] >= dims[i]) {
throw std::invalid_argument("Value >= dimension");
}
result = result * dims[i] + x[i];
}
return result;
}
};

How modulus operation works in C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Why do I get this output: 0 1 2 3 0 1 2 3 0 1 after running the code below? Doesn't the modulus operation finds the remainder after division of one number by another?
#include <iostream>
using namespace std;
int main ()
{
for (int i=0; i< 10; ++i)
cout << i % 4 << " ";
}
The answer is correct. '%' mean "reminder". The % operator is remainder operator. The A % B operator actually answer the question “If I divided A by B using integer arithmetic, what would the remainder be?”
dividend = quotient * divisor + remainder
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
.....
etc..
For negative number...
1 % (-4) = 1
(-2) % 4 = -2
(-3) % (-4) = -3
With a remainder operator, the sign of the result is the same as the sign of the dividend
you can read more at What's the difference between “mod” and “remainder”?
Yes, that's how modulus works. The output is correct.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
Take the number, remove as many 4's as you can. Whatever is left over is the modulus.
It does.0 / 4 = 0 remainder 01 / 4 = 0 remainder 1and so on.
Modulus operator returns the remainder after dividing the first number with the second one.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
6 % 4 = 2
7 % 4 = 3
8 % 4 = 0
9 % 4 = 1

Understanding recursion in c++

I think I'm understanding the principle behind recursion, for example the stack like behaviour and the way the program "yo-yo's" back through the function calls, I seem to be having trouble figuring out why certain functions return the values that they do though, the code below returns 160, is this due to the return 5 playing a part, I think I'm right in saying it will go 4*2 + 8*2 + 12*2 etc.. I'm really doubting that when changing my values though.
Would anybody be able to offer a brief explanation as to which values are being multiplied?
cout << mysteryFunction(20);
int mysteryFunction (int n)
{
if(n > 2)
{
return mysteryFunction(n - 4)*2;
}
else return 5;
}
If you are interested in actual call stack:
mysteryFunction(20):
[n > 2] -> mysteryFunction(16) * 2
[n > 2] -> mysteryFunction(12) * 2
[n > 2] -> mysteryFunction(8) * 2
[n > 2] -> mysteryFunction(4) * 2
[n > 2] -> mysteryFunction(0) * 2
[n <= 2] -> 5
5 * 2 = 10
10 * 2 = 20
20 * 2 = 40
40 * 2 = 80
80 * 2 = 160
More generally: 20 = 4*5, so 5 * 2^5 = 5 * 32 = 160.
mysteryFunction(20) => 80 * 2 = 160
mysteryFunction(16) => 40 * 2 = 80
mysteryFunction(12) => 20 * 2 = 40
mysteryFunction(8) => 10 * 2 = 20
mysteryFunction(4) => 5 * 2 = 10
mysteryFunction(0) => 5
Recursion doesn't yo-yo, it just nests deeply.
In you case, the if statement results in either a) the function being called from within the function, or b) a return value... let's look at it running...
A- mysteryFunction(20)
B-- mysteryFunction(16)
C--- mysteryFunction(12)
D---- mysteryFunction(8)
E----- mysteryFunction(4)
F------ mysteryFunction(0) <-- this is the first time (n > 2) is false
Line F is the first time n > 2 is false, which means it returns a 5.
Line F was called by line E, and the value line E gets (5) is multiplied by 2 and returned. So line E returns 10.
Line E was called by line D... and the value it gets (10) is multiplied by 2 and returned, so line D return 20.
... and so on.
Quick version... let's order these to match the order they act on the value...
F: 5
E: F * 2 = 10
D: E * 2 = 20
C: D * 2 = 40
B: C * 2 = 80
A: B * 2 = 160
I will suggest you to read this article on Wikipedia about recursion: http://en.wikipedia.org/wiki/Recursion
In a nutshell a recursive function is one that calls itself until you reach a base case(this is the key). If you don't reach the base case your function will run forever(infinite loop). In the case of your function, get a piece of paper a follow its path picking any number as example, it is the best way to figure out how it works. The factorial is a good example:
the factorial of a number, let's say 5 is !5 = 5 * 4 * 3 * 2 * 1 which is 120. Try it, the principles for recursion is the same regardless the problem.
Here's an example for a factorial function.
Recursion in c++ Factorial Program
Just go through the code and substitute the values.
mysteryFunction(20) -> mysteryFunction(16) * 2
mysteryFunction(16) * 2 -> mysteryFunction(12) * 2 * 2
mysteryFunction(12) * 2 * 2 -> mysteryFunction(8) * 2 * 2 * 2
mysteryFunction(8) * 2 * 2 * 2 -> mysteryFunction(4) * 2 * 2 * 2 * 2
mysteryFunction(4) * 2 * 2 * 2 * 2 -> mysteryFunction(0) * 2 * 2 * 2 * 2 * 2
mysteryFunction(0) * 2 * 2 * 2 * 2 * 2 -> 5 * 2 * 2 * 2 * 2 * 2 -> 160

Histogram of the distribution of dice rolls

I saw a question on careercup, but I do not get the answer I want there. I wrote an answer myself and want your comment on my analysis of time complexity and comment on the algorithm and code. Or you could provide a better algorithm in terms of time. Thanks.
You are given d > 0 fair dice with n > 0 "sides", write an function that returns a histogram of the frequency of the result of dice rolls.
For example, for 2 dice, each with 3 sides, the results are:
(1, 1) -> 2
(1, 2) -> 3
(1, 3) -> 4
(2, 1) -> 3
(2, 2) -> 4
(2, 3) -> 5
(3, 1) -> 4
(3, 2) -> 5
(3, 3) -> 6
And the function should return:
2: 1
3: 2
4: 3
5: 2
6: 1
(my sol). The time complexity if you use a brute force depth first search is O(n^d). However, you can use the DP idea to solve this problem. For example, d=3 and n=3. You can use the result of d==1 when computing d==2:
d==1
num #
1 1
2 1
3 1
d==2
first roll second roll is 1
num # num #
1 1 2 1
2 1 -> 3 1
3 1 4 1
first roll second roll is 2
num # num #
1 1 3 1
2 1 -> 4 1
3 1 5 1
first roll second roll is 3
num # num #
1 1 4 1
2 1 -> 5 1
3 1 6 1
Therefore,
second roll
num #
2 1
3 2
4 3
5 2
6 1
The time complexity of this DP algorithm is
SUM_i(1:d) {n*[n(d-1)-(d-1)+1]} ~ O(n^2*d^2)
~~~~~~~~~~~~~~~ <--eg. d=2, n=3, range from 2~6
The code is written in C++ as follows
vector<pair<int,long long>> diceHisto(int numSide, int numDice) {
int n = numSide*numDice;
vector<long long> cur(n+1,0), nxt(n+1,0);
for(int i=1; i<=numSide; i++) cur[i]=1;
for(int i=2; i<=numDice; i++) {
int start = i-1, end = (i-1)*numSide; // range of previous sum of rolls
//cout<<"start="<<start<<" end="<<end<<endl;
for(int j=1; j<=numSide; j++) {
for(int k=start; k<=end; k++)
nxt[k+j] += cur[k];
}
swap(cur,nxt);
for(int j=start; j<=end; j++) nxt[j]=0;
}
vector<pair<int,long long>> result;
for(int i=numDice; i<=numSide*numDice; i++)
result.push_back({i,cur[i]});
return result;
}
You can do it in O(n*d^2). First, note that the generating function for an n-sided dice is p(n) = x+x^2+x^3+...+x^n, and that the distribution for d throws has generating function p(n)^d. Representing the polynomials as arrays, you need O(nd) coefficients, and multiplying by p(n) can be done in a single pass in O(nd) time by keeping a rolling sum.
Here's some python code that implements this. It has one non-obvious optimisation: it throws out a factor x from each p(n) (or equivalently, it treats the dice as having faces 0,1,2,...,n-1 rather than 1,2,3,...,n) which is why d is added back in when showing the distribution.
def dice(n, d):
r = [1] + [0] * (n-1) * d
nr = [0] * len(r)
for k in xrange(d):
t = 0
for i in xrange(len(r)):
t += r[i]
if i >= n:
t -= r[i-n]
nr[i] = t
r, nr = nr, r
return r
def show_dist(n, d):
for i, k in enumerate(dice(n, d)):
if k: print i + d, k
show_dist(6, 3)
The time and space complexity are easy to see: there's nested loops with d and (n-1)*d iterations so the time complexity is O(n.d^2), and there's two arrays of size O(nd) and no other allocation, so the space complexity is O(nd).
Just in case, here a simple example in Python using the OpenTurns platform.
import openturns as ot
d = 2 # number of dice
n = 6 # number of sides per die
# possible values
dice_distribution = ot.UserDefined([[i] for i in range(1, n + 1)])
# create the sum distribution d times the sum
sum_distribution = sum([dice_distribution] * d)
That's it!
print(sum_distribution)
will show you all the possible values and their corresponding probabilities:
>>> UserDefined(
{x = [2], p = 0.0277778},
{x = [3], p = 0.0555556},
{x = [4], p = 0.0833333},
{x = [5], p = 0.111111},
{x = [6], p = 0.138889},
{x = [7], p = 0.166667},
{x = [8], p = 0.138889},
{x = [9], p = 0.111111},
{x = [10], p = 0.0833333},
{x = [11], p = 0.0555556},
{x = [12], p = 0.0277778}
)
You can also draw the probability distribution function:
sum_distribution.drawPDF()

FIFO Page Replacement Algorithm - Counting Page Faults

I'm currently reading about Page Replacement Algorithms, and have been looking at a couple of examples with regards to the FIFO (First In, First Out) method.
My question is as follows; how do you count the number of page faults, as I have seen different practices.
For instance:
Example 1 (on page 9) and Example 2 take the exact same sequence. The first counts the number of page faults to be 12, whereas the second states the number is 15. They are using the same number of frames, 3.
The sequence is:
Sequence: 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
-----------------------------------------
7 7 7 0 0 1 2 3 0 4 2 2 2 3 0 0 0 1 2 7
0 0 1 1 2 3 0 4 2 3 3 3 0 1 1 1 2 7 0
1 2 2 3 0 4 2 3 0 0 0 1 2 2 2 7 0 1
-----------------------------------------
PF (1): * * * * * * * * * * * * Total = 12 page faults
PF (2): * * * * * * * * * * * * * * * Total = 15 page faults
Hence, my question is; which method is the correct method? Do you count the first three instances as page faults?
If so, given the sequence:
Sequence: A B C D A E F G H I A J
-------------------------
A A A A A B C D E F G H
B B B B C D E F G H I
C C C D E F G H I A
D D E F G H I A J
-------------------------
PF (1): * * * * * * * * * * * Total = 11 page faults
PF (2): * * * * * * * Total = 7 page faults
Any help would be highly appreciated. Thank you guys!
"Hence, my question is; which method is the correct method? Do you count the first three instances as page faults?"
Yes. Page Fault occurs when you don't fined the referenced page in the frames. Therefore, the first entries are always PFs.