Based on WolframH's answer, I tried the problem for sample inputs in C ++ and it seems to work. I also tried the phython solution, which worked fine with input samples. The interesting thing is that when I increased the input to larger numbers (i.e. 3 and 18), both solutions that I have in C ++ and in phython hang for an indefinite time,
Something went wrong?
Quite by accident, I just went through my Dynamic Programming last night's notes and read about The Problem of Weighted Independent Typing . Yeah! We are doing too much work than we expect! IN:
#include <math.h> #include <iomanip> #include <iostream> using namespace std; void get_tight_number(int base_max, int length) { double result = 0; int _tight_numbers = 0; double total = pow(base_max + 1, length); for (int i = 0; i <= base_max; ++i) { _tight_numbers += get_tight_number_help(base_max, length, i); } result = 100 * _tight_numbers / total; cout << fixed << setprecision(5) << result << "\n"; } int get_tight_number_help(int base_max, int length, int endwith) { cout << "Length: " << length << "endwith: " << endwith << endl; if (length < 1 || endwith < 0 || endwith > base_max) return 0; if (length == 1) { return 1; } else { return get_tight_number_help(base_max, length - 1, endwith) + get_tight_number_help(base_max, length - 1, endwith + 1) + get_tight_number_help(base_max, length - 1, endwith - 1); } } int main() { get_tight_number(8, 7); return 0; }
With a bunch of prints and the correct result is 0.10130 . If I do grep "endwith:" | wc -l grep "endwith:" | wc -l , I get 7719 , which means that an auxiliary function was called more than 7000 times for this input! To just understand how many times it is called on other inputs, I got:
Input
Not very good ... We are doing too much recount. Instead, I put together a bottom up solution for a reference array:
int** tight_number_bottom_up(int base_max, int length) { int** result = new int*[base_max + 1]; for (int i = 0; i < base_max + 1; ++i) { result[i] = new int[length]; } //Ends with i, ie, looping over them for (int j = 0; j < length + 1; ++j) { for (int i = 0; i < base_max + 1; ++i) { if (j == 0) { result[i][j] = 0; } else if (j == 1) { result[i][j] = 1; } else { int bigger = i == base_max ? 0 : result[i + 1][j - 1]; cout << "bigger: " << bigger << endl; int smaller = i == 0 ? 0 : result[i - 1][j - 1]; cout << "smaller: " << smaller << endl; result[i][j] = result[i][j - 1] + bigger + smaller; } } } return result; }
I am sure that the number of iterations when forming the bottom table is the maximum (base_max + 1) * (length + 1) , pleased that I finished writing and am happy that it gives the correct results.
Follow up question (if you are still with me)
double seems insufficient for inputs like 9, 100 or even 9, 50 , what can I do to make a long double?