TCS MockVita 2019 Round 2 Question: Hop Game - c++

I am trying to solve a problem asked in TCS MockVita 2019 Round 2:
Problem Description
Dr Felix Kline, the Math teacher at Gauss School introduced the following game to teach his students problem solving. He places a series of “hopping stones” (pieces of paper) in a line with points (a positive number) marked on each of the stones.
Students start from one end and hop to the other end. One can step on a stone and add the number on the stone to their cumulative score or jump over a stone and land on the next stone. In this case, they get twice the points marked on the stone they land but do not get the points marked on the stone they jumped over.
At most once in the journey, the student is allowed (if they choose) to do a “double jump”– that is, they jump over two consecutive stones – where they would get three times the points of the stone they land on, but not the points of the stone they jump over.
The teacher expected his students to do some thinking and come up with a plan to get the maximum score possible. Given the numbers on the sequence of stones, write a program to determine the maximum score possible.
Constraints
The number of stones in the sequence< 30
Input Format
The first line contains N, the number of integers (this is a positive integer)
The next line contains the N points (each a positive integer) separated by commas. These are the points on the stones in the order the stones are placed.
Output
One integer representing the maximum score
Test Case
Explanation
Example 1
Input
3
4,2,3
Output
10
Explanation
There are 3 stones (N=3), and the points (in the order laid out) are 4,2 and 3 respectively.
If we step on the first stone and skip the second to get 4 + 2 x 3 = 10. A double jump to the third stone will get only 9. Hence the result is 10, and the double jump is not used
Example 2
Input
6
4,5,6,7,4,5
Output
35
Explanation
N=6, and the sequence of points is given.One way of getting 35 is to start with a double jump to stone 3 (3 x 6=18), go to stone 4 (7) and jump to stone 6 (10 points) for a total of 35. The double jump was used only once, and the result is 35.
I found that it's a Dynamic programming problem, but I don't know what I did wrong because my solution is not able to pass all the test cases. My code passed all the tests I created.
unordered_map<int, int> lookup;
int res(int *arr, int n, int i){
if(i == n-1){
return 0;
}
if(i == n-2){
return arr[i+1];
}
if(lookup.find(i) != lookup.end())
return lookup[i];
int maxScore = 0;
if(i< n-3 && flag == false){
flag = true;
maxScore = max(maxScore, 3 * (arr[i+3]) + res(arr, n, i+3));
flag = false;
}
maxScore = max(maxScore, (arr[i+1] + res(arr,n,i+1)));
lookup[i] = max(maxScore, 2 * (arr[i+2]) + res(arr, n, i+2));
return lookup[i];
}
cout << res(arr, n, 0) + arr[0]; // It is inside the main()
I expect you to find the mistake in my code and give the correct solution, and any test case which fails this solution. Thanks :)

You don't need any map. All you need to remember are last few maximal values. You have two options every move (except two first), end with double jump made or without it. If you don't want ot make a dj then your best joice is maximum of last stone + current and stone before last + 2 * current max(no_dj[2] + arr[i], no_dj[1] + 2 * arr[i]).
On the other hand, if you want to have dj made than you have three options, either jump one stone after some previous dj dj[2] + arr[i] or jump over last stone after some dj dj[1] + 2 * arr[i] or do double jump in current move no_dj[0] + 3 * arr[i].
int res(int *arr, int n){
int no_dj[3]{ 0, 0, arr[0]};
int dj[3]{ 0, 0, 0};
for(int i = 1; i < n; i++){
int best_nodj = max(no_dj[1] + 2 * arr[i], no_dj[2] + arr[i]);
int best_dj = 0;
if(i > 1) best_dj = max(max(dj[1] + 2 * arr[i], dj[2] + arr[i]), no_dj[0] + 3 * arr[i]);
no_dj[0] = no_dj[1];
no_dj[1] = no_dj[2];
no_dj[2] = best_nodj;
dj[0] = dj[1];
dj[1] = dj[2];
dj[2] = best_dj;
}
return max(no_dj[2], dj[2]);
}
All you have to remember are two arrays of three elements. Last three maximum values after double jump and last three maximum values without double jump.

Related

How to make the computation faster?

Here is short code which computes sum of all square numbers(not actually sum of squares) till n,where n can be upto 10 pow 20.
long long res=0;
long long sm=0;
for (long long i = 1; res <=n; i=i+2)
{
res = (res+i);
sm = sm+(res*(n/res));
}
How do we make the above code work faster? Here, the computation of sm is taking time for very large n like 10 pow 20.
Is there any way that the computation of sm can be made faster?
Here res computes all the square numbers like 1,4,9,16,25....
Lets say n=10, then the squares are 1,4,9 and then by the above code the sm is (1)(10/4)+(4)(10/4)+(9)(10/9)=27.
1*10+4*2+9*1=27.
Here the division is integer division.
edit1:
i need to compute sm mentioned in above code.
here sm is summation ( i2 * floor(n/(i2)) ) where i=1 to sqrt(n)
we can find the sum of all square number till n using the formaula :
n * (n + 1) * (2*n + 1) / 6
long summation(long n)
{
return (n * (n + 1) *
(2 * n + 1)) / 6;
}
Is there any way that the computation of sm can be made faster?
If you notice the pattern plus apply some mathematics, yes.
The next perfect square after your very first perfect square (1 in all cases except for n==0) will be the square of ceil(sqrt(first number)).
In other words, the square root of say the nth number, in correspondence to your first number will be given by pow(ceil(sqrt(L)), n).
Now, notice the pattern between squares: 0 1 4 9 16 25...
Difference between 0 and 1 is 1
Difference between 1 and 4 is 3
Difference between 4 and 9 is 5
Difference between 9 and 16 is 7
Difference between 16 and 25 is 9, and so on.
This makes it clear that the difference between two perfect squares is always an odd number.
Proceeding with this knowledge, you'll need to know what must be added to get the next number, the answer to which is (sqrt(square) * 2) + 1).
i.e., current_square + (sqrt(current_square)*2+1) = next_square.
For instance and to prove this equation, consider the perfect square 25. Applying this logic, the next perfect square will be 25 + (sqrt(25) * 2 + 1) = 36, which is correct. Here 11 is added to 25, which is an odd number.
Similarly if you follow this trend, you'll observe all these numbers are odd, with a difference of +2. For finding the next square of 2, you'll need to add (sqrt(22)+1) = 5 to it (4+5=9); for finding the next square (i.e. for 3) you'll need to add (sqrt(32+1) = 7 to it (9+7=16). The difference is always +2.
Moreover, summing the odd number or applying addition is computationally less expensive than performing multiplication or finding square roots of every number, so your complexity should be fine.
Following that, do this:
Collect the first square. (which ideally should be 1, but if n>0 condition is not mentioned, apply the condition if(n!=0) to my logic)
Assign the next term's difference as first_square*2+1. You'll need to add the first square though, as this is not the next square, but the difference between next square and current square. Add the term in a loop like I did below.
Run a loop upto your required number. Collect your required sum given by (square*floor(n/square) in a variable within the loop.
Follow the approach I mentioned above, i.e. add the current square to the next term (difference between current and next square) and increment next square by 2.
A working example for the above logic:
#include <iostream>
#include <cmath>
#define ll long long
int main()
{
ll int n;
std::cin>>n;
// Start from 1: (add case for 0 if input is not >0)
// you can also start from any other square or define a range.
ll int first = 1;
// Square it:
ll int first_square = first * first;
// Find next square:
ll int next = (first_square * 2) + 1;
// Initialize variable to collect your required sum:
ll int sum = 0;
ll int square = first_square;
while ((square >= 0 && square <= n))
{
sum += (square *floor(n/square));
// Add the perfect square:
square += next;
// Next odd number to be added:
next += 2;
}
std::cout<<sum;
return 0;
}

Find Maximum amount of Coins and Selected Coins

I'm doing Coin Row Problem. And i got a small problem.
There is a row of n coins whose values are some positive integers c1, c2, . . . , cn, not necessarily distinct.
The goal is to pick up the maximum amount of money subject to the constraint that you cannot pick up any two adjacent coins. For instance, in the example below, once you pick up 10, you cannot take either 6 or the left-hand 2.
Example:
enter the number of coins: 6
enter the value of all coins : 5 1 2 10 6 2
The maximum amount of coin : 17
The selected coins to get maximum value : C1 , C4 , C6
I wanna get Selected coins (C1, C4, C6 in ex).
Here is my function code
I just can get only maximum amount in this code.
int getanswer(int array[],int len)
{
int C[20];
for (int j = 0; j < len; j++)
{
C[j + 1] = array[j];
}
int F[20];
F[0] = 0;
F[1] = C[1];
for (int j = 2; j < len+1; j++)
{
F[j] = max(C[j] + F[j - 2], F[j - 1]);
printf("temp :%d\n", C[j]);
}
return F[len];
}
How can i get Selected coins with my code?
A good solution would involve recursion, backtracking, and memoization (dynamic programming). Write a recursive routine that tries each of the available choices from the left end, and then recurs on the remaining list. Your current algorithm has a blind spot for unbalanced values just over its visible horizon (2 elements out).
Here's some pseudo-code to help you start.
int pickup(coin[])
{
// base case: <= 2 coins left
if size(coin) == 0 // return 0 for an empty list
return 0
if size(coin) <= 2 // if only 1 or 2 coins left, return the larger
return max(coin)
// Otherwise, experiment:
// pick *each* of the first two coins, solve the remaining problem,
// and compare results.
pick1 = coin[0] + pickup(coin[2:]) // pick 1st coin; recur on rest of list
pick2 = coin[1] + pickup(coin[3:]) // pick 2nd coin; recur on rest of list
return max(pick1, pick2)
That's the general attack. You can speed up the solution a lot with memoization. Also, you'll need to convert this to your preferred implementation language and add tracking to this so you get the indices you want. If all you need is to return the coin values in order, it's a simple to accumulate an array of those values, pre-pending one on each return.

How exactly can I handle the following condition while applying dijkstra's algorithm to this?

So, I was solving the following question: http://www.spoj.com/problems/ROADS/en/
N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it: the road length and the toll that needs to be paid for the road (expressed in the number of coins). Bob and Alice used to live in the city 1. After noticing that Alice was cheating in the card game they liked to play, Bob broke up with her and decided to move away - to the city N. He wants to get there as quickly as possible, but he is short on cash. We want to help Bob to find the shortest path from the city 1 to the city N that he can afford with the amount of money he has.
Input
The input begins with the number t of test cases. Then t test cases follow. The first line of the each test case contains the integer K, 0 <= K <= 10000, maximum number of coins that Bob can spend on his way. The second line contains the integer N, 2 <= N <= 100, the total number of cities. The third line contains the integer R, 1 <= R <= 10000, the total number of roads. Each of the following R lines describes one road by specifying integers S, D, L and T separated by single blank characters : S is the source city, 1 <= S <= N D is the destination city, 1 <= D <= N L is the road length, 1 <= L <= 100. T is the toll (expressed in the number of coins), 0 <= T <= 100 Notice that different roads may have the same source and destination cities.
Output
For each test case, output a single line contain the total length of the shortest path from the city 1 to the city N whose total toll is less than or equal K coins. If such path does not exist, output -1.
Now, what I did was, I tried to use the djikstra's algorithm for this which is as follows:
Instead of only having a single node as the state, I take
node and coins as one state and then apply dijkstra.
length is the weight between the states.
and I minimize the length without exceeding the total coins.
My code is as follows:
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
class node
{
public:
int vertex;
int roadlength;
int toll;
};
int dist[101][101]; // for storing roadlength
bool visited[101][10001];
int cost[101][101]; // for storing cost
int ans[101][10001]; // actual distance being stored here
void djikstra(int totalcoins, int n);
bool operator < (node a, node b)
{
if (a.roadlength != b.roadlength)
return a.roadlength < b.roadlength;
else if (a.toll != b.toll)
return a.toll < b.toll;
return a.vertex < b.vertex;
}
int main (void)
{
int a,b,c,d;
int r,t,k,n,i,j;
cin>>t;
while (t != 0)
{
cin>>k>>n>>r;
for (i = 1; i <= 101; i++)
for (j = 1; j <= 101; j++)
dist[i][j] = INT_MAX;
for (i = 0; i <= n; i++)
for (j = 0; j <= k; j++)
ans[i][j] = INT_MAX;
for ( i = 0; i <= n; i++ )
for (j = 0; j <= k; j++ )
visited[i][j] = false;
for (i = 0; i < r; i++)
{
cin>>a>>b>>c>>d;
if (a != b)
{
dist[a][b] = c;
cost[a][b] = d;
}
}
djikstra(k,n);
int minlength = INT_MAX;
for (i = 1; i <= k; i++)
{
if (ans[n][i] < minlength)
minlength = ans[n][i];
}
if (minlength == INT_MAX)
cout<<"-1\n";
else
cout<<minlength<<"\n";
t--;
}
cout<<"\n";
return 0;
}
void djikstra(int totalcoins, int n)
{
set<node> myset;
myset.insert((node){1,0,0});
ans[1][0] = 0;
while (!myset.empty())
{
auto it = myset.begin();
myset.erase(it);
int curvertex = it->vertex;
int a = it->roadlength;
int b = it->toll;
if (visited[curvertex][b] == true)
continue;
else
{
visited[curvertex][b] = true;
for (int i = 1; i <= n; i++)
{
if (dist[curvertex][i] != INT_MAX)
{
int foo = b + cost[curvertex][i];
if (foo <= totalcoins)
{
if (ans[i][foo] >= ans[curvertex][b] + cost[curvertex][i])
{
ans[i][foo] = ans[curvertex][b] + cost[curvertex][i];
myset.insert((node){i,ans[i][foo],foo});
}
}
}
}
}
}
}
Now, I have two doubts:
Firstly, my output is not coming correct for the first given test case of the question, i.e.
Sample Input:
2
5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2
0
4
4
1 4 5 2
1 2 1 0
2 3 1 1
3 4 1 0
Sample Output:
11
-1
My output is coming out to be, 4 -1 which is wrong for the first test case. Where am I going wrong in this?
How do I handle the condition of having multiple edges? That is, question mentions, Notice that different roads may have the same source and destination cities. How do I handle this condition?
The simple way to store the roads is as a vector of vectors. For each origin city, you want to have a vector of all roads leading from that city.
So when you are processing a discovered "best" path to a city, you would iterate through all roads from that city to see if they might be "best" paths to some other city.
As before you have two interacting definitions of "best" than cannot be simply combined into one definition. Shortest is more important, so the main definition of "best" is shortest considering cheapest only in case of ties. But you also need the alternate definition of "best" considering only cheapest.
As I suggested for the other problem, you can sort on the main definition of "best" so you always process paths that are better in that definition before paths that are worse. Then you need to track the best seen so far for the second definition of "best" such that you only prune paths from processing when they are not better in the second definition from what you already processed prioritized by the first definition.
I haven't read your code, however I can tell you the problem cannot be solved with an unmodified version of Dijkstra's algorithm.
The problem is at least as hard as the binary knapsack problem. How? The idea is to construct the knapsack problem within the stated problem. Since the knapsack problem is known to be not solvable within polynomial time, neither is the stated problem's. Since Dijkstra's algorithm is a polynomial algorithm, it therefore could not apply.
Consider a binary knapsack problem with a set of D many values X and a maximum value m = max(X). Now construct the proposed problem as such:
Let there be D + 1 cities where city n is connected to city n + 1 by two roads. Let cities 1 through D uniquely correspond to a value v in X. Let only two roads from such a city n go only to city n + 1, one costing v with distance m - v + 1, and the other costing 0 with a distance of m + 1.
In essence, "you get exactly what you pay for" -- for every coin you spend, your trip will be one unit of distance shorter.
This reframes the problem to be "what's the maximum Bob can spend by only spending money either no or one time on each toll?" And that's the same as the binary knapsack problem we started with.
Hence, if we solve the stated problem, we also can solve the binary knapsack problem, and therefore the stated problem cannot be any more "efficient" to solve than the binary knapsack problem -- with Dijkstra's algorithm is.

How do I solve this making it more efficient?

So, I am trying to solve the following question: https://www.codechef.com/TSTAM15/problems/ACM14AM3
The Mars Orbiter Mission probe lifted-off from the First Launch Pad at Satish Dhawan Space Centre (Sriharikota Range SHAR), Andhra
Pradesh, using a Polar Satellite Launch Vehicle (PSLV) rocket C25 at
09:08 UTC (14:38 IST) on 5 November 2013.
The secret behind this successful launch was the launch pad that ISRO
used. An important part of the launch pad is the launch tower. It is
the long vertical structure which supports the rocket.
ISRO now wants to build a better launch pad for their next mission.
For this, ISRO has acquired a long steel bar, and the launch tower can
be made by cutting a segment from the bar. As part of saving the cost,
the bar they have acquired is not homogeneous.
The bar is made up of several blocks, where the ith block has
durability S[i], which is a number between 0 and 9. A segment is
defined as any contiguous group of one or more blocks.
If they cut out a segment of the bar from ith block to jth block
(i<=j), then the durability of the resultant segment is given by (S[i]*10(j-i) + S[i+1]*10(j-i-1) + S[i+2]*10(j-i-2) + … + S[j] * 10(0)) % M. In other words, if W(i,j) is the base-10 number formed by
concatenating the digits S[i], S[i+1], S[i+2], …, S[j], then
the durability of the segment (i,j) is W(i,j) % M.
For technical reasons that ISRO will not disclose, the durability of
the segment used for building the launch tower should be exactly L.
Given S and M, find the number of ways ISRO can cut out a segment from
the steel bar whose durability is L. Input
The first line contains a string S. The ith character of this string
represents the durability of ith segment. The next line contains a
single integer Q, denoting the number of queries. Each of the next Q
lines contain two space separated integers, denoting M and L. Output
For each query, output the number of ways of cutting the bar on a
separate line. Constraints
1 ≤ |S| ≤ 2 * 10^4
Q ≤ 5
0 < M < 500
0 ≤ L < M
Example
Input:
23128765
3
7 2
9 3
15 5
Output:
9
4
5
Explanation
For M=9, L=3, the substrings whose remainder is 3 when divided by
9 are: 3, 31287, 12 and 876.
Now, what I did was, I initially generate all possible substrings of numbers of the given length, and tried to divide it by the given number to check if it is divisible and added it to the answer. Therefore, my code for the same was,
string s;
cin>>s;
int m,l,ans=0;
for ( i = 0; i < s.length(); i++ )
{
for ( j = i+1; j < s.length(); j++ )
{
string p = s.substr(i,j);
long long num = stoi(p);
if (num%m == l)
ans++;
}
}
cout<<ans<<"\n";
return 0;
But obviously since the input length is upto 10^4, this doesn't work in required time. How can I make it more optimal?
A little advice I can give you is to initialize a variable to s.length() to avoid calling the function each time for each for block.
Ok, here goes, with a working program at the bottom
Major optimization #1
Do not (ever) work with strings when it comes to integer arithmetic. You're converting string => integer over and over and over again (this is an O(n^2) problem), which is painstakingly slow. Besides, it also misses the point.
Solution: first convert your array-of-characters (string) to array-of-numbers. Integer arithmetic is fast.
Major optimization #2
Use a smart conversion from "substring" to number. After transforming the characters to actual integers, they become the factors in the the polynomial a_n * 10^n. To convert a substring of n segments into a number, it is enough to compute sum(a_i * 10^i) for 0 <= i < n.
And nicely enough, if the coefficients a_i are arranged the way they are in the problem's statement, you can use Horner's method (https://en.wikipedia.org/wiki/Horner%27s_method) to very quickly evaluate the numerical value of the substring.
In short: keep a running value of the current substring and growing it by one element is just * 10 + new element
Example: string "128472373".
First substring = "1", value = 1.
For the second substring we need to
add the digit "2" as follows: value = value * 10 + "2", thus: value = 1 * 10 + 2 = 12.
For 3rd substring need to add digit "8": value = value * 10 + "8", thus: value = 12 * 10 + 8 = 128.
Etcetera.
I had some issues with formatting the C++ code inline so I stuck it in IDEone: https://ideone.com/TbJiqK
The gist of the program:
In main loop, loop over all possible start points:
// For all startpoints in the segments array ...
for(int* f=segments; f<segments+n_segments; f++)
// add up the substrings that fullfill the question
n += count_segments(f, segments+n_segments, m, l);
// Output the answer for this question
cout << n << endl;
Implementation of the count_segments() function:
// Find all substrings that % m == l
// Use Horner's algorithm to quickly evaluate sum(a_n*10^n) where
// a_n are the segments' durabilities
int count_segments(int* first, int* last, int m, int l) {
int n = 0, number = 0;
while( first<last ) {
number = number * 10 + *first; // This is Horner's method
if( (number % m)==l ) {
n++;
// If you don't believe - enable this line of output and
// see the numbers matching the combinations of the
//cout << "[" << m << ", " << l << "]: " << number << endl;
}
first++;
}
return n;
}

Finding how many turns are in a grid of AxB

So, basically, check the picture below:
This is a grid of 4x5 explained, however the actual challenge requires you to input the grid dimensions. So, my job is to write a program that calculates the amount of turns you make (red dots in this case). The starting position is always in the bottom left corner. The guy is moving by the arrows of the clock ("right").
The program input / output is:
you input the grid dimensions:
4 5 (for example)
you output the amount of changes of direction.
7
So, I have absolutely no idea how it's done. The solution I have seen only is the following:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
long long n, i,pom,m;
int k,br=0;
cin>>n>>m;
if(n>m) {
int pom=n;
n=m;
m=n;
}
if(n+1>=m)
cout<<(n-1)+(m-1);
else
cout<<(n-1) +(n-1)+1;
return 0;
}
But I don't understand the following example... could anyone explain what's going? Or any other way of solving this problem is always welcome.
int res = 0;
if(height == width)
res = height * 2 - 2;//when height is odd than you will have 2 rows with single red dot
//when height is even you will have one row without red dot (all the rest have 2 red dots.
else if (width > height)
res = height * 2 - 1;//one rows with 1 red dot the rest with 2 red dots.
else //height > width
res = width * 2 - 2// 2 columns with one red dot and the rest with 2 red dots.
I am not a C++ guy so can't help in understanding the code. But can surely help understanding the situation here.
The situation is that the number of turns will depend only on one of the two dimensions. Which ever is less. So the number of turns depends on the smaller dimension and number of boxes on that side. Because here in picture when you take a 4X5 array, no matter how many you increase the width to. as long as the height is 4, the number of turns will remain 7 only.
But if you decrease the width from 4 to 3, number of turns depends on width now.
Now about the number of dots. If both dimensions are same and odd, then assume dimension to be 2A+1, then the number of turns will be 4*A.
If one dimension is smaller, then if the dimensions are same and even, then assume dimension to be 2*A ,then the number of turns will be 4A-2.
If the smaller dimension is even, then assume the dimension to be 2*A, then the number of turns will be 4A-1.
If the smaller dimension is odd, then assume the dimension to be 2A+1, then the number of turns will be 4A+1.
See if this works with your own new code.
This code conditionally swaps n and m to make n <= m:
if(n>m) {
int pom=n;
n=m;
m=n;
}
Given that, the condition n+1>=m is equivalent to n == m || n + 1 == m.
Note that both formulas (n-1)+(m-1) and (n-1) +(n-1)+1 give the same result for n + 1 == m.
So it is not really necessary to check whether n + 1 == m; it's only the special case n == m that matters. If n == m, then you can use the formula (n-1)+(m-1), or just 2 * n - 2. Otherwise, use the formula (n-1) +(n-1)+1, or just 2 * n - 1.
To rewrite the code:
int calculate_number_of_turns(int m, int n)
{
if (m == n)
return 2 * n - 2;
else
return 2 * std::min(m, n) - 1;
}
Edit:
If you want to write your code from scratch, without knowing the math in advance, you can write a recursive function at first.
If n = 2, it's easy to see that the answer is 3 (3 turns). If m = 2, then the answer is 2. Otherwise (assuming n > 2 and m > 2), the calculation involves invoking the same function for different arguments.
int calculate_number_of_turns(int m, int n)
{
if (n == 2)
return 3;
else if (m == 2)
return 2;
else
return calculate_number_of_turns(???, ???);
}
Imagine starting the path in your picture, and stopping right after you do the second turn. If you turn the picture upside-down, it's as if you reduced with and height by 1. So calling the same function for m - 1, n - 1 will calculate the number of turns left to do, in addition to the first 2 turns.
int calculate_number_of_turns(int m, int n)
{
if (n == 2)
return 3;
else if (m == 2)
return 2;
else
return 2 + calculate_number_of_turns(m - 1, n - 1);
}
Now, converting this recursive function to any simpler form is not too complicated (just calculate the number of times the function is going to call itself, until a termination condition holds).