I am supposed to implement a MIRRORED_REPEAT for my raytracing textures. I looked at how it's defined in OpenGL https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf page 260 and then I tried it myself, first with a 1-dimesional array. The behaviour should be:
Basically it repeats the index into the array ( modulo ) but mirrors the input based on wether or not the offset is even or odd. ( 2nd image below )
#include <iostream>
int main() {
int values[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const auto mod = [](const int a, const int n) noexcept
{
return (a % n + n) % n;
};
const auto mirror = [](const int a) noexcept
{
return a >= 0.f ? a : -(1 + a);
};
const auto mirrored_repeat = [&](const int x) noexcept {
return (10 - 1) - mirror(mod(x, 2 * 10)) - 10;
};
for(int i = -5; i < 6; ++i) {
std::cout << values[mirrored_repeat(i)] << std::endl;
}
}
This doesn't work however, but gives me nice undefined-behaviourish output instead x) Can someone tell me how I can do it properly?
If you replace the line
std::cout << values[mirrored_repeat(i)] << std::endl;
with
std::cout << mirrored_repeat(i) << std::endl;
you'll see that the indices returned by mirrored_repeat are clearly wrong (they are negative, to begin with).
I believe the formula in the spec is a bit wrong, for it has one mismatched bracket. If we rewrite the line
return (10 - 1) - mirror(mod(x, 2 * 10)) - 10;
like this
return (10 - 1) - mirror(mod(x, 2 * 10) - 10);
the code starts producing something more reasonable.
For anyone interested, I derived a shorter solution while working on Blender:
C++
#include <iostream>
int main() {
const auto mirrored_repeat = [&](int x, const int size) noexcept {
x = std::abs(x + (x < 0)) % (2 * size);
return x >= size ? 2 * size - x - 1 : x;
};
for (int i = -6; i < 5; ++i) {
std::cout << mirrored_repeat(i, 10) << std::endl;
}
}
JavaScript demo
function mirrored_repeat(x, size) {
x = Math.abs(x + (x < 0)) % (2 * size);
return x >= size ? 2 * size - x - 1 : x;
}
for (let i = -6; i < 5; ++i) {
console.log(mirrored_repeat(i, 10));
}
I wanted to reduce the number of modulo calls, so I used the symmetry of C++ modulo for odd sections and the if statement for even sections.
For information on how I derived it, see my explanation here.
Related
I recently finished making an algorithm for a project I'm working on.
Briefly, a part of my project needs to fill a matrix, the requirements of how to do it are these:
- Fill the matrix in form of spiral, from the center.
- The size of the matrix must be dynamic, so the spiral can be large or small.
- Every two times a cell of the matrix is filled, //DO STUFF must be executed.
In the end, the code that I made works, it was my best effort and I am not able to optimize it more, it bothers me a bit having had to use so many ifs, and I was wondering if someone could take a look at my code to see if it is possible to optimize it further or some constructive comment (it works well, but it would be great if it was faster, since this algorithm will be executed several times in my project). Also so that other people can use it!
#include <stdio.h>
typedef unsigned short u16_t;
const u16_t size = 7; //<-- CHANGE HERE!!! just odd numbers and bigger than 3
const u16_t maxTimes = 2;
u16_t array_cont[size][size] = { 0 };
u16_t counter = 3, curr = 0;
u16_t endColumn = (size - 1) / 2, endRow = endColumn;
u16_t startColumn = endColumn + 1, startRow = endColumn + 1;
u16_t posLoop = 2, buffer = startColumn, i = 0;
void fillArray() {
if (curr < maxTimes) {
if (posLoop == 0) { //Top
for (i = buffer; i <= startColumn && curr < maxTimes; i++, curr++)
array_cont[endRow][i] = counter++;
if (curr == maxTimes) {
if (i <= startColumn) {
buffer = i;
} else {
buffer = endRow;
startColumn++;
posLoop++;
}
} else {
buffer = endRow;
startColumn++;
posLoop++;
fillArray();
}
} else if (posLoop == 1) { //Right
for (i = buffer; i <= startRow && curr < maxTimes; i++, curr++)
array_cont[i][startColumn] = counter++;
if (curr == maxTimes) {
if (i <= startRow) {
buffer = i;
} else {
buffer = startColumn;
startRow++;
posLoop++;
}
} else {
buffer = startColumn;
startRow++;
posLoop++;
fillArray();
}
} else if (posLoop == 2) { //Bottom
for (i = buffer; i >= endColumn && curr < maxTimes; i--, curr++)
array_cont[startRow][i] = counter++;
if (curr == maxTimes) {
if (i >= endColumn) {
buffer = i;
} else {
buffer = startRow;
endColumn--;
posLoop++;
}
} else {
buffer = startRow;
endColumn--;
posLoop++;
fillArray();
}
} else if (posLoop == 3) { //Left
for (i = buffer; i >= endRow && curr < maxTimes; i--, curr++)
array_cont[i][endColumn] = counter++;
if (curr == maxTimes) {
if (i >= endRow) {
buffer = i;
} else {
buffer = endColumn;
endRow--;
posLoop = 0;
}
} else {
buffer = endColumn;
endRow--;
posLoop = 0;
fillArray();
}
}
}
}
int main(void) {
array_cont[endColumn][endColumn] = 1;
array_cont[endColumn][endColumn + 1] = 2;
//DO STUFF
u16_t max = ((size * size) - 1) / maxTimes;
for (u16_t j = 0; j < max; j++) {
fillArray();
curr = 0;
//DO STUFF
}
//Demostration
for (u16_t x = 0; x < size; x++) {
for (u16_t y = 0; y < size; y++)
printf("%-4d ", array_cont[x][y]);
printf("\n");
}
return 0;
}
Notice that the numbers along the diagonal (1, 9, 25, 49) are the squares of the odd numbers. That's an important clue, since it suggests that the 1 in the center of the matrix should be treated as the end of a spiral.
From the end of each spiral, the x,y coordinates should be adjusted up and to the right by 1. Then the next layer of the spiral can be constructed by moving down, left, up, and right by the same amount.
For example, starting from the position of the 1, move up and to the right (to the position of the 9), and then form a loop with the following procedure:
move down, and place the 2
move down, and place the 3
move left, and place the 4
move left, and place the 5
etc.
Thus the code looks something like this:
int size = 7;
int matrix[size][size];
int dy[] = { 1, 0, -1, 0 };
int dx[] = { 0, -1, 0, 1 };
int directionCount = 4;
int ringCount = (size - 1) / 2;
int y = ringCount;
int x = ringCount;
int repeatCount = 0;
int value = 1;
matrix[y][x] = value++;
for (int ring = 0; ring < ringCount; ring++)
{
y--;
x++;
repeatCount += 2;
for (int direction = 0; direction < directionCount; direction++)
for (int repeat = 0; repeat < repeatCount; repeat++)
{
y += dy[direction];
x += dx[direction];
matrix[y][x] = value++;
}
}
I saw already many approaches for doing a spiral. All a basically drawing it, by following a path.
BUT, you can also come up with an analytical calculation formula for a spiral.
So, no recursion or iterative solution by following a path or such. We can directly calculate the indices in the matrix, if we have the running number.
I will start with the spiral in mathematical positive direction (counter clockwise) in a cartesian coordinate system. We will concentrate on X and Y coordinates.
I made a short Excel and derived some formulas from that. Here is a short picture:
From the requirements we know that the matrix will be quadratic. That makes things easier. A little bit trickier is, to get the matrix data symmetrical. But with some simple formulas, derived from the prictures, this is not really a problem.
And then we can calculate x and y coordinates with some simple statements. See the below example program with long variable names for better understanding. The code is made using some step by step approach to illustrate the implementation. Of course it can be made more compact easily. Anyway. Let's have a look.
#include <iostream>
#include <cmath>
#include <iomanip>
int main() {
// Show some example values
for (long step{}; step < 81; ++step) {
// Calculate result
const long roundedSquareRoot = std::lround(std::sqrt(step));
const long roundedSquare = roundedSquareRoot * roundedSquareRoot;
const long distance = std::abs(roundedSquare - step) - roundedSquareRoot;
const long rsrIsOdd = (roundedSquareRoot % 2);
const long x = (distance + roundedSquare - step - rsrIsOdd) / (rsrIsOdd ? -2 : 2);
const long y = (-distance + roundedSquare - step - rsrIsOdd) / (rsrIsOdd ? -2 : 2);
// Show ouput
std::cout << "Step:" << std::setw(4) << step << std::setw(3) << x << ' ' << std::setw(3) << y << '\n';
}
}
So, you see that we really have an analytical solution. Given any number we can calculate the x and y coordinate using a formula. Cool.
Getting indices in a matrix is just adding some offset.
With that gained know how, we can now easily calculate the complete matrix. And, since there is no runtime activity needed at all, we can let the compiler do the work. We will simply use constexpr functions for everything.
Then the compiler will create this matrix at compile time. At runtime, nothing will happen.
Please see a very compact solution:
#include <iostream>
#include <iomanip>
#include <array>
constexpr size_t MatrixSize = 15u;
using MyType = long;
static_assert(MatrixSize > 0 && MatrixSize%2, "Matrix size must be odd and > 0");
constexpr MyType MatrixHalf = MatrixSize / 2;
using Matrix = std::array<std::array<MyType, MatrixSize>, MatrixSize >;
// Some constexpr simple mathematical functions ------------------------------------------------------------------------------
// No need for <cmath>
constexpr MyType myAbs(MyType v) { return v < 0 ? -v : v; }
constexpr double mySqrtRecursive(double x, double c, double p) {return c == p? c: mySqrtRecursive(x, 0.5 * (c + x / c), c); }
constexpr MyType mySqrt(MyType x) {return (MyType)(mySqrtRecursive((double)x,(double)x,0.0)+0.5); }
// Main constexpr function will fill the matrix with a spiral pattern during compile time -------------------------------------
constexpr Matrix fillMatrix() {
Matrix matrix{};
for (int i{}; i < (MatrixSize * MatrixSize); ++i) {
const MyType rsr{ mySqrt(i) }, rs{ rsr * rsr }, d{ myAbs(rs - i) - rsr }, o{ rsr % 2 };
const size_t col{ (size_t)(MatrixHalf +((d + rs - i - o) / (o ? -2 : 2)))};
const size_t row{ (size_t)(MatrixHalf -((-d + rs - i - o) / (o ? -2 : 2)))};
matrix[row][col] = i;
}
return matrix;
}
// This is a compile time constant!
constexpr Matrix matrix = fillMatrix();
// All the above has been done during compile time! -----------------------------------------
int main() {
// Nothing to do. All has beend done at compile time already!
// The matrix is already filled with a spiral pattern
// Just output
for (const auto& row : matrix) {
for (const auto& col : row) std::cout << std::setw(5) << col << ' '; std::cout << '\n';
}
}
Different coordinate systems or other spiral direction can be adapted easily.
Happy coding.
For 2 numbers x and n entered by the user, my code needs to find Hn(x) defined recursively by the following formulas:
I am trying to implement a recursive version and and iterative version of that function. But I think I am getting the wrong concept of it, since my code doesn't compile due to errors on H(n) and H[n]:
#include "pch.h"
#include <iostream>
int H(int n, int x) //function for recursion
{
if (n < 0) return -1;
else if (n == 0) return 1;
else if (n == 1) return 2 * x;
return 2 * x * H(n) * x - 2 * n * H(n - 1) * x;
}
int H1(int n, int x) //function for Iterator
{
int *H1 = new int[n + 1];
H[0] * x = 1;
H[1] * x = 2 * x;
for (int i = 0; i <= n; i++)
{
H[i] * x = 2 * x * H[n] * x - 2 * n * H[n - 1] * x;
}
return H1(n) * x;
}
int main()
{
int n, x;
std::cout << "Enter the number n: ";
std::cin >> n;
std::cout << "Enter the number x: ";
std::cin >> x;
std::cout << "Rec = " << H[n] * x std::endl;
std::cout << "Iter = " << H1[n] * x std::endl;
}
It is confusing, I apologize for that as I am completely new to functions.
I already managed to do this with fibonacci sequence. And there I used only one parameter for function f(x) that is f(int n){... }, but here I am a bit confused with two parameters in function H(int n, int x) , where n is the index of H while x is an integer.
Yes, you need to translate your matematically indexed function into a function with 2 parameters.
The recursive version is almost ok, except for some shifts in the indexes:
int H(int n, int x) // recursive version
{
if (n <= 0)
return -1;
else if (n == 1)
return 1;
else if (n == 2)
return 2 * x;
else
return 2 * x * H(n-1, x) - 2 * n * H(n - 2, x); // shift n+1, n n-1 to n, n-1 n-2
}
Your iterative version needs rework, since you should write it as a loop, if possible without cashing the values that you no longer need. For example:
int Hi(int n, int x) //iterative version
{
if (n <= 0)
return -1;
else if (n == 1)
return 1;
int am2 = 1; // start for for n-2
int am1 = 2*x; // start for n-1
if (n == 2)
return am1;
int am;
for (int i=3; i<=n; i++) {
am = 2*x*am1 - 2*i*am2; // calculate Hn from Hn-1 and Hn-2
//prepare next interation
am2=am1;
am1=am;
}
return am;
}
Online demo
You wrote:
int H(int n, int x) //function for recursion
{
if (n < 0) return -1;
else if (n == 0) return 1;
else if (n == 1) return 2 * x;
return 2 * x * H(n) * x - 2 * n * H(n - 1) * x;
}
You're not far from a working program. Drop that H1 function. Let's see:
int H(int n, int x)
{
switch(n)
{
// H_0(x) = 1
case 0: return 1;
// H_1(x) = 2x
case 1: return 2 * x;
// H_{n+1}(x) = 2x H_n(x) - 2n H_{n - 1}(x)
default:
return 2*x*H(n-1, x) - 2*(n-1)*H(n-2, x);
}
}
The trick part is realizing than the n in H_{n+1}(x) = 2x H_n(x) - 2n H_{n - 1}(x) and in return 2*x*H(n-1, x) - 2*(n-1)*H(n-2, x);are not the same, they differ by one.
Now, you only need to handle user I/O and calling your H function with user input.
I made up my mind to write a little piece of code that gets two integers, lets say M and N ( M <= N ) and sum the digits of all the integers between them, inclusive. So for example if M = 1 and N = 9, DigitSum will equal to 45. If M = 10 and N = 11 the sum will be (1 + 0 (10) + 1 + 1 (11) = 3).
Here is my code so far (Done the for loop instead of the return):
#include <iostream>
#include <vector>
using namespace std;
// the partial digits sums digitSum[i] = the sum of the digits between 0 and i
int digitSum[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45};
int pow_of_ten[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
// the sums of all the digits in the numbers from 1 to (10^(i) - 1) where i is the index in the array
long subsums[] = {0, 45, 20 * 45, 300 * 45, 4000 * 45, 50000 * 45, 600000 * 45, 7000000 * 45, 80000000 * 45,
900000000 * 45};
//Calculates the sum of all digits between 0 and M inclusive
long Digit_Sum(int M) {
if (M < 10) {
return digitSum[M];
}
long result = 0;
int same = M;
int counter = 0;
int lastdigit = 0;
while (same > 0) {
if (same < 10) {
lastdigit = same;
break;
}
same /= 10;
counter ++;
}
for(;counter >= 0; counter --) {
result += (subsums[counter] + M % pow_of_ten[counter] + 1) * lastdigit;
result += digitSum[lastdigit - 1] * pow_of_ten[counter];
if (counter == 0) {
break;
}
lastdigit = (M / pow_of_ten[counter - 1]) % 10;
}
return result;
}
int main() {
int M;
int N;
vector<long> sums;
while (true) {
cin >> M >> N;
if (M == 0 && N == 0) {
break;
}
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
}
for (vector<long>::iterator it = sums.begin(); it != sums.end(); ++it) {
cout << *it << endl;
}
}
For most cases this works well but an Online judge says it is wrong. I looked at other solutions that work but no one hard-coded the values in arrays the way I did. May this cause a partial problem, any ideas?
You can easily just create a for-loop to greatly simplify this code.
There is no need to go through all that effort.
for (Initialization Action, Boolean Expression, Update_Action)
Re deletion below: sorry, I have a bit influenza and mizread N as M. :(
I think a main error is M-1 in
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
Also noting that <when corrected that formula will only work for single-digit numbers. My comment earlier about using a simple formula was based on misunderstanding your problem description, in view of that formula and your examples. Both indicated single digit numbers only.
However, the complexity of the code appears unreasonably high. Consider this, assuming non-negative integers as input, and assuming m is always less than or equal to n:
#include <iostream>
#include <stdexcept>
using namespace std;
bool throwX() { throw std::runtime_error( "Ouch." ); }
auto main() -> int
{
for( ;; )
{
int m, n;
cin >> m >> n || throwX();
if( m == 0 && n == 0 ) { break; }
int sum = 0;
for( int i = m; i <= n; ++i )
{
for( int v = i; v != 0; v /= 10 )
{
sum += v % 10;
}
}
cout << sum << endl;
}
}
It needs not be more complicated than that.
Tested and working to spec, sans console input:
#include <iostream>
#include <string>
using namespace std;
void sum_a_to_b(const int & a, const int & b)
{
if (a <= b && a >= 0)
{
long long sum = 0;
for (int i = a; i <= b; i++)
{
sum += i;
}
cout << "Sum of digits from " << a << " through " << b << " is " << sum << ".\n";
}
}
int main()
{
sum_a_to_b(5, 6);
sum_a_to_b(1, 9);
}
How to create all possible numbers, starting from a given one, where all digits of the new ones are moved one slot to the right? For example if we have 1234. I want to generate 4123, 3412 and 2341.
What I have come out with so far is this:
int move_digits(int a)
{
int aux = 0;
aux = a % 10;
for(int i=pow(10, (number_digits(a) - 1)); i>0; i=i/10)
aux = aux * 10 + ((a % i) / (i/10));
return aux;
}
But it doesn't work.
The subprogram number_digits looks like this (it just counts how many digits the given number has):
int number_digits(int a)
{
int ct = 0;
while(a != 0)
{
a = a/10;
ct++;
}
return ct;
}
I think there is no need to write separate function number_digits.
I would write function move_digits simpler
#include <iostream>
#include <cmath>
int move_digits( int x )
{
int y = x;
double n = 0.0;
while ( y /= 10 ) ++n;
return ( x / 10 + x % 10 * std::pow( 10.0, n ) );
}
int main()
{
int x = 1234;
std::cout << x << std::endl;
std::cout << move_digits( x ) << std::endl;
}
Retrieving the last digit of n: n % 10.
To "cut off" the last digit, you could use number / 10.
Say you have a three-digit number n, then you can prepend a new digit d using 1000 * d + n
That said, you probably want to compute
aux = pow(10, number_digits - 1) * (aux % 10) + (aux / 10)
Calculatea/(number_digits(a) - 1) and a%(number_digits(a) - 1)
And your answer is (a%(number_digits(a) - 1))*10 + a/(number_digits(a) - 1)
int i =0 ;
int len = number_digits(a);
while(i < len){
cout << (a%(len - 1))*10 + a/(len - 1) <<endl;
a = (a%(len - 1))*10 + a/(len - 1);
}
void move_digits(int a)
{
int digits = 0;
int b = a;
while(b / 10 ){
digits++;
b = b / 10;
}
for (int i = 0; i < digits; ++i)
{
int c = a / 10;
int d = a % 10;
int res = c + pow(10, digits) * d;
printf("%d\n", res);
a = res;
}
printf("\n");
}
int main()
{
move_digits(12345);
}
How can I convert this recursive function to an iterative function?
#include <cmath>
int M(int H, int T){
if (H == 0) return T;
if (H + 1 >= T) return pow(2, T) - 1;
return M(H - 1, T - 1) + M(H, T - 1) + 1;
}
Well it's a 3-line code but it's very hard for me to convert this to an iterative function. Because it has 2 variables. And I don't know anything about Stacks so I couldn't convert that.
My purpose for doing this is speed of the function. This function is too slow. I wanted to use map to make this faster but I have 3 variables M, H and T so I couldn't use map
you could use dynamic programming - start from the bottom up when H == 0 and T == 0 calculate M and iterate them. here is a link explaining how to do this for Fibonacci numbers, which are quite similar to your problem.
Check this,recursive and not recursive versions gave equal results for all inputs i gave so far. The idea is to keep intermediate results in matrix, where H is row index, T is col index, and the value is M(H,T). By the way, you can calculate it once and later just obtain the result from the matrix, so you will have performance O(1)
int array[10][10]={{0}};
int MNR(int H, int T)
{
if(array[H][T])
return array[H][T];
for(int i =0; i<= H;++i)
{
for(int j = 0; j<= T;++j)
{
if(i == 0)
array[i][j] = j;
else if( i+1 > j)
array[i][j] = pow(2,j) -1;
else
array[i][j] = array[i-1][j-1] + array[i][j-1] + 1;
}
}
return array[H][T];
}
int M(int H, int T)
{
if (H == 0) return T;
if (H + 1 >= T) return pow(2, T) - 1;
return M(H - 1, T - 1) + M(H, T - 1) + 1;
}
int main()
{
printf("%d\n", M(6,3));
printf("%d\n", MNR(6,3));
}
Unless you know the formula for n-th (in your case, (m,n)-th) element of the sequence, the easiest way is to simulate the recursion using a stack.
The code should look like the following:
#include <cmath>
#include <stack>
struct Data
{
public:
Data(int newH, int newT)
: T(newT), H(newH)
{
}
int H;
int T;
};
int M(int H, int T)
{
std::stack<Data> st;
st.push(Data(H, T));
int sum = 0;
while (st.size() > 0)
{
Data top = st.top();
st.pop();
if (top.H == 0)
sum += top.T;
else if (top.H + 1 >= top.T)
sum += pow(2, top.T) - 1;
else
{
st.push(Data(top.H - 1, top.T - 1));
st.push(Data(top.H, top.T - 1));
sum += 1;
}
}
return sum;
}
The main reason why this function is slow is because it has exponential complexity, and it keeps recalculating the same members again and again. One possible cure is memoize pattern (handily explained with examples in C++ here). The idea is to store every result in a structure with a quick access (e.g. an array) and every time you need it again, retrieve already precomputed result. Of course, this approach is limited by the size of your memory, so it won't work for extremely big numbers...
In your case, we could do something like that (keeping the recursion but memoizing the results):
#include <cmath>
#include <map>
#include <utility>
std::map<std::pair<int,int>,int> MM;
int M(int H, int T){
std::pair<int,int> key = std::make_pair(H,T);
std::map<std::pair<int,int>,int>::iterator found = MM.find(key);
if (found!=MM.end()) return found->second; // skip the calculations if we can
int result = 0;
if (H == 0) result = T;
else if (H + 1 >= T) result = pow(2, T) - 1;
else result = M(H - 1, T - 1) + M(H, T - 1) + 1;
MM[key] = result;
return result;
}
Regarding time complexity, C++ maps are tree maps, so searching there is of the order of N*log(N) where N is the size of the map (number of results which have been already computed). There are also hash maps for C++ which are part of the STL but not part of the standard library, as was already mentioned on SO. Hash map promises constant search time (the value of the constant is not specified though :) ), so you might also give them a try.
You may calculate using one demintional array. Little theory,
Let F(a,b) == M(H,T)
1. F(0,b) = b
2. F(a,b) = 2^b - 1, when a+1 >= b
3. F(a,b) = F(a-1,b-1) + F(a,b-1) + 1
Let G(x,y) = F(y,x) ,then
1. G(x,0) = x // RULE (1)
2. G(x,y) = 2^x - 1, when y+1 >= x // RULE (2)
3. G(x,y) = G(x-1,y-1) + G(x-1,y) + 1 // RULE(3) --> this is useful,
// because for G(x,y) need only G(x-1,?), i.e if G - is two deminsions array, then
// for calculating G[x][?] need only previous row G[x-1][?],
// so we need only last two rows of array.
// Here some values of G(x,y)
4. G(0,y) = 2^0 - 1 = 0 from (2) rule.
5. G(1,0) = 1 from (1) rule.
6. G(1,y) = 2^1 - 1 = 1, when y > 0, from (2) rule.
G(0,0) = 0, G(0,1) = 0, G(0,2) = 0, G(0,3) = 0 ...
G(1,0) = 1, G(1,1) = 1, G(1,2) = 1, G(1,3) = 1 ...
7. G(2,0) = 2 from (1) rule
8. G(2,1) = 2^2 - 1 = 3 from (2) rule
9. G(2,y) = 2^2 - 1 = 3 when y > 0, from (2) rule.
G(2,0) = 2, G(2,1) = 3, G(2,2) = 3, G(2,3) = 3, ....
10. G(3,0) = 3 from (1) rule
11. G(3,1) = G(2,0) + G(2,1) + 1 = 2 + 3 + 1 = 6 from (3) rule
12. G(3,2) = 2^3 - 1 = 7, from (2) rule
Now, how to calculate this G(x,y)
int M(int H, int T ) { return G(T,H); }
int G(int x, int y)
{
const int MAX_Y = 100; // or something else
int arr[2][MAX_Y] = {0} ;
int icurr = 0, inext = 1;
for(int xi = 0; xi < x; ++xi)
{
for( int yi = 0; yi <= y ;++yi)
{
if ( yi == 0 )
arr[inext][yi] = xi; // rule (1);
else if ( yi + 1 >= xi )
arr[inext][yi] = (1 << xi) - 1; // rule ( 2 )
else arr[inext][yi] =
arr[icurr][yi-1] + arr[icurr][yi] + 1; // rule (3)
}
icurr ^= 1; inext ^= 1; //swap(i1,i2);
}
return arr[icurr][y];
}
// Or some optimizing
int G(int x, int y)
{
const int MAX_Y = 100;
int arr[2][MAX_Y] = {0};
int icurr = 0, inext = 1;
for(int ix = 0; ix < x; ++ix)
{
arr[inext][0] = ix; // rule (1)
for(int iy = 1; iy < ix - 1; ++ iy)
arr[inext][iy] = arr[icurr][iy-1] + arr[icurr][iy] + 1; // rule (3)
for(int iy = max(0,ix-1); iy <= y; ++iy)
arr[inext][iy] = (1 << ix ) - 1; // rule(2)
icurr ^= 1 ; inext ^= 1;
}
return arr[icurr][y];
}