I'm writing a program that is to take a number between 1-10 and display all possible ways of arranging the numbers.
Ex
input: 3
output:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Whenever I input 9 or 10, the program gives a segmentation fault and dumps the core. I believe the issue is my recursive algorithm is being called too many times. Could someone help point out how I could limit the amount of recursive calls necessary? Here is my current code:
void rearange(int numbers[11], int index, int num, int fact) {
int temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
if (fact > 0) // If we have more sequences remaining
rearange(numbers, index, num, fact); // Do it all again! :D
}
int main() {
int num, i; // our number and a counter
printf("Enter a number less than 10: ");
scanf("%d", &num); // get the number from the user
int numbers[11]; // create an array of appropriate size
// fill array
for (i = 1; i <= num; i++) { // fill the array from 1 to num
numbers[i] = i;
}
int fact = 1; // calculate the factorial to determine
for (i = 1; i <= num; ++i) // how many possible sequences
{
fact = fact * i;
}
rearange(numbers, num, num, fact); // begin rearranging by recursion
return 0;
}
9! (362880) and 10! (3628800) are huge numbers that overflow the call stack when you do as many recursive calls. Because all the local variables and formal parameters have to be stored. You either you have to increase the stack size or convert the recursion into iteration.
On linux, you can do:
ulimit -s unlimited
to set the stack size to unlimited. The default is usually 8MB.
Calculating permutations can be done iteratively, but even if you do it recursively there is no need to have a gigantic stack (like answers suggesting to increase your system stack say). In fact you only need a tiny amount of your stack. Consider this:
0 1 <- this needs **2** stackframes
1 0 and an for-loop of size 2 in each stackframe
0 1 2 <- this needs **3** stackframes
0 2 1 and an for-loop of size 3 in each stackframe
1 0 2
1 2 0
2 1 0
2 0 1
Permuting 9 elements takes 9 stackframes and a for-loop through 9 elements in each stackframe.
EDIT: I have taken the liberty to add a recursion-counter to your rearrange-function, it now prints like this:
Enter a number less than 10: 4
depth 1 1 2 4 3
depth 2 1 4 2 3
depth 3 4 1 2 3
depth 4 4 1 3 2
depth 5 4 3 1 2
depth 6 3 4 1 2
depth 7 3 4 2 1
depth 8 3 2 4 1
depth 9 2 3 4 1
depth 10 2 3 1 4
depth 11 2 1 3 4
depth 12 1 2 3 4
depth 13 1 2 4 3
depth 14 1 4 2 3
depth 15 4 1 2 3
depth 16 4 1 3 2 which is obviously wrong even if you do it recursively.
depth 17 4 3 1 2
depth 18 3 4 1 2
depth 19 3 4 2 1
depth 20 3 2 4 1
depth 21 2 3 4 1
depth 22 2 3 1 4
depth 23 2 1 3 4
depth 24 1 2 3 4
....
The recursion-leafs should be the only ones which output so the depth should be constant and small (equal to the number you enter).
EDIT 2:
Ok, wrote the code. Try it out:
#include "stdio.h"
void betterRecursion(int depth, int elems, int* temp) {
if(depth==elems) {
int j=0;for(;j<elems;++j){
printf("%i ", temp[j]);
}
printf(" (at recursion depth %u)\n", depth);
} else {
int i=0;for(;i<elems;++i){
temp[depth] = i;
betterRecursion(depth+1, elems, temp);
}
}
}
int main() {
int temp[100];
betterRecursion(0, 11, temp); // arrange the 11 elements 0...10
return 0;
}
I'd make your rearange function iterative - do while added, and recursive call removed:
void rearange(int numbers[11], int index, int num, int fact) {
int temp;
do
{
temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
} while (fact > 0);
}
This is not a task for a deep recursion.
Try to invent some more stack-friendly algorithm.
Following code has rather troubles with speed than with stack size...
It's a bit slow e.g. for n=1000 but it works.
#include <stdio.h>
void print_arrangement(int n, int* x)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s%d", i ? " " : "", x[i]);
}
printf("\n");
}
void generate_arrangements(int n, int k, int* x)
{
int i;
int j;
int found;
if (n == k)
{
print_arrangement(n, x);
}
else
{
for(i = 1; i <= n; i++)
{
found = 0;
for(j = 0; j < k; j++)
{
if (x[j] == i)
{
found = 1;
}
}
if (!found)
{
x[k] = i;
generate_arrangements(n, k + 1, x);
}
}
}
}
int main(int argc, char **argv)
{
int x[50];
generate_arrangements(50, 0, x);
}
Your program is using too many recursions unnecessarily. It is using n! recursions when actually n would be enough.
To use only n recursions, consider this logic for the recursive function:
It receives an array nums[] of n unique numbers to arrange
The arrangements can have n different first number in them, as there are n different numbers in the array
(key step) Loop over the elements of nums[], and in each iteration create a new array but with the current element removed, and recurse into the same function passing this shorter array as parameter
As you recurse deeper, the parameter array will be smaller and smaller
When there is only one element left, that's the end of the recursion
Using this algorithm, your recursion will not be deeper than n and you will not get segmentation fault. The key is in the key step, where you build a new array of numbers that is always 1 item shorter than the input array.
As a side note, make sure to check the output of your program before you submit, for example run it through | sort | uniq | wc -l to make sure you are getting the correct number of combinations, and check that there are no duplicates with | sort | uniq -d (the output should be empty if no dups).
Spoiler alert: here's my implementation in C++ using a variation of the above algorithm:
https://gist.github.com/janosgyerik/5063197
Related
How do I make my code have an output like this:
Enter your number: 4
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
I can't seem to figure out how to make it so the last digit prints the next value iteration.
#include <stdio.h>
int main(){
int num;
int i = 1;
printf("Enter your number: ");
scanf("%d", &num);
for(i = 1; i<=num; i++){
for(int j = 0; j<num; ++j)
{
printf("%d ",i);
}
printf("\n");
}
Doing this using nested loops are simple and doesn't require any kind of special calculations, if-statements or other more or less fancy stuff. Just keep it simple.
Your task is:
for each row:
print "rowindex+1 and a space" n-1 times
print "rowindex+2 and a newline" 1 time
"for each row" is one simple loop.
"n-1 times" is another (nested) simple loop.
So keep it simple... just two ordinary for-loops like:
#include <stdio.h>
int main()
{
int n = 4;
for (int i = 0; i < n; i++) // for each row
{
for (int j = 0; j < n-1; j++) // n-1 times
{
printf("%d ", i + 1);
}
printf("%d\n", i + 2); // 1 time
}
return 0;
}
Here is something kind of from out in the left field, and off topic, leaving behind not only the requirements of the homework, but the C language. However, we will find our way back.
We can solve this problem (sort of) using text processing at the Unix prompt:
We can treat the smallest square
12
23
as an initial seed kernel, which is fed through a little command pipeline to produce a square of the next size (up to a single digit limitation):
We define this function:
next()
{
sed -e 's/\(.\).$/\1&/' | awk '1; END { print $0 | "tr \"[1-9]\" \"[2-8]\"" }'
}
Then:
$ next
12
23
[Ctrl-D][Enter]
112
223
334
Now, copy the 3x3 square and paste it into next:
$ next
112
223
334
[Ctrl-D][Enter]
1112
2223
3334
4445
Now, several steps in one go, by piping through multiple instances of next:
$ next | next | next | next | next
12
23
[Ctrl-D][Enter]
1111112
2222223
3333334
4444445
5555556
6666667
7777778
The text processing rule is:
For each line of input, repeat the second-to-last character. E.g ABC becomes ABBC, or 1112 becomes 11112. This is easily done with sed.
Add a new line at the end which is a copy of the last line, with each digit replaced by its successor. E.g. if the last line is 3334, make it 4445. The tr utility helps here
To connect this to the homework problem: a C program could be written which works in a similar way, starting with an array which holds the 1 2 2 3 square, and grows it. The requirement for nested loops would be satisfied because there would be an outer loop iterating on the number of "next" operations, and then an inner loop performing the edits on the array: replicating the next-to-last column, and adding the new row at the bottom.
#include <stdio.h>
#include <stdlib.h>
#define DIM 25
int main(int argc, char **argv)
{
if (argc != 2) {
fputs("wrong usage\n", stderr);
return EXIT_FAILURE;
}
int n = atoi(argv[1]);
if (n <= 2 || n > DIM) {
fputs("invalid n\n", stderr);
return EXIT_FAILURE;
}
int array[DIM][DIM] = {
{ 1, 2 },
{ 2, 3 }
};
/* Grow square from size 2 to size n */
for (int s = 2; s < n; s++) {
for (int r = 0; r < s; r++) {
array[r][s] = array[r][s-1];
array[r][s-1] = array[r][s-2];
}
for (int c = 0; c <= s; c++) {
array[s][c] = array[s-1][c] + 1;
}
}
/* Dump it */
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++)
printf("%3d ", array[r][c]);
putchar('\n');
}
return 0;
}
#include<stdio.h>
int main(){
int n;
printf("Enter the number: ");
scanf("%d",&n);
for(int i =1; i<=n; i++){
for(int j=1;j<=n;j++) {
if(j==n)
printf("%d\t",i+1);
else
printf("%d\t",i);
}
printf("\n");
}
return 0;}
Nested loops will drive you crazy, trying figure out their boundaries.
While I usually oppose adding more variables, in this case it seems justified to keep track of things simply.
#include <stdio.h>
int main() {
int n = 4, val = 1, cnt1 = 1, cnt2 = 0;
for( int i = 1; i < n*n+1; i++ ) { // notice the 'square' calculation
printf( "%d ", val );
if( ++cnt1 == n ) // tired of this digit? start the next digit
cnt1 = 0, val++;
if( ++cnt2 == n ) // enough columns output? start the next line
cnt2 = 0, putchar( '\n' );
}
return 0;
}
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
A single example of desired output is hard to go by, especially when the code doesn't help... Anyway, here's the output when 'n' = 5.
1 1 1 1 2
2 2 2 2 3
3 3 3 3 4
4 4 4 4 5
5 5 5 5 6
All of these kinds of assignments are to try to get you to recognize a pattern.
The pattern you are given
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
is very close to
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
which is an easy nested loop. Write a solution to the easier pattern. Once you have that you can then you can fix it.
Hint: Notice that the only thing that changes is the last item of the inner loop.
Edit
This totally breaks the spirit of the assignment, and if you, dear student, ever try to submit something like this your professor will... probably not care, but also know full well that you didn’t do it. If I were your professor you’d lose marks, even if I knew you weren’t cheating and had written something this awesome yourself.
Single loop. Stuff added to pretty print numbers wider than one digit (except the very last). Maths, yo.
#include <stdio.h>
#include <math.h>
void print_off_by_one_square( int n )
{
int width = (int)log10( n ) + 1;
for (int k = 0; k++ < n*n ;)
printf( "%*d%c", width, (k+n)/n, (k%n) ? ' ' : '\n' );
}
int main(void)
{
int n;
printf( "n? " );
fflush( stdout );
if ((scanf( "%d", &n ) != 1) || (n < 0))
fprintf( stderr, "%s\n", "Not cool, man, not cool at all." );
else
print_off_by_one_square( n );
return 0;
}
The way it works is pretty simple, actually, but I’ll leave it as an exercise for the reader to figure out on his or her own.
Here is a different concept. Some of the answers are based on the idea that we first think about
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
and then tweak the logic for the item in the last line.
But we can regard it like this also:
We have a tape which goes like this:
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4
and we are blindly cutting the tape into four-element pieces to form a 4x4 square. Suppose someone deletes the first item from the tape, and then adds 5:
1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5
Now, if we cut that tape blindly by the same process, we will get the required output:
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
Suppose we have a linear index through the tape, a position p starting at 0.
In the unshifted tape, item p is calculated using p / 4 + 1, right?
In the shifted tape, this is just (p + 1) / 4 + 1. Of course we substitute the square size for 4.
Thus:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fputs("wrong usage\n", stderr);
return EXIT_FAILURE;
}
int n = atoi(argv[1]);
int m = n * n;
if (n <= 0) {
fputs("invalid n\n", stderr);
return EXIT_FAILURE;
}
for (int p = 0; p < m; p++) {
printf("%3d ", (p + 1) / n + 1);
if (p % n == n - 1)
putchar('\n');
}
return 0;
}
$ ./square 2
1 2
2 3
$ ./square 3
1 1 2
2 2 3
3 3 4
$ ./square 4
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
I have this assignment to get and transpose a matrix using dynamic memory allocation in C
I did it by converting the linear position to (i,j) and swapping i,j
old and new element positions are perfect,
somehow the swap is not working as i intended,
might seem like i'm making others problem solve for me, but i'm blank at this point so help will be really appreciated
Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main(){
int m,n;
printf("Enter the order of matrix, m*n:\n");
scanf("%d %d",&m,&n);
int *matrix_ptr;
matrix_ptr = (int *) malloc(m*n*sizeof(int));
printf("Enter the elements of %d*%d matrix\n",m,n);
for(int i=0; i<m*n; i++){
scanf("%d", matrix_ptr+i);
}
// Transposing the matrix
for(int i=0; i<m*n; i++){
int i_index = i / n;
int j_index = i % n;
// (i_index)*n + j_index gives the linear position
int new_linear_pos = (j_index)*n + i_index;
int temp = *(matrix_ptr + new_linear_pos);
*(matrix_ptr + new_linear_pos) = *(matrix_ptr + i);
*(matrix_ptr + i) = temp;
if(i==0){
printf("\nThe transpose is:\n");
}
printf("%d ", *(matrix_ptr+i));
if((i+1)%n == 0){
printf("\n");
}
}
}
The output:
You are swapping all values twice and you are printing the ones at the beginning of the line after the second swap. The first swap happened with i equal 1 and 2
Let's say you have this matrix at the begin:
1 2 3
4 5 6
7 8 9
swap index 0 with 0 stays the same thing. Prints 1
swap index 1 with 3: prints 4
1 4 3
2 5 6
7 8 9
swap index 2 with 6: prints 7\n
1 4 7
2 5 6
3 8 9
swap index 3 with 1: prints 4
1 2 7
4 5 6
3 8 9
etc...
The solution would be to swap elements only once.
The easiest fix would be a if (i > new_linear_pos) continue; //already swapped
I want to generate all possible increasing subsequences of numbers (repetition allowed) from 1 to n, but of length k.
Ex. n=3, k=2
Output:
1 1
1 2
1 3
2 2
2 3
3 3
This is my code:
#include <stdio.h>
int s[100];
int n=6;
int k=4;
void subk(int prev,int index)
{
int i;
if (index==k)
{
for(int i=0; i<k; i++)
printf("%d ",s[i]);
printf("\n");
return;
}
s[index]=prev;
for (i=prev; i<=n; ++i)
{
subk(i,index+1);//,s,n,k);
}
}
int main()
{
int j;
for (j = 1; j<=n ; ++j)
{
subk(j,0);
}
return 0;
}
But this generates some unwanted repetitions. How do I eliminate those?
I have tested your code with n = 3 and k = 2 and got the following result:
1 1
1 1
1 1
1 2
1 2
1 3
2 2
2 2
2 3
3 3
This is obviously incorrect, as there are several identical numbers like 1 1 or 1 2.
But what exactly went wrong?
Let's write down the right results if n = 3 and k = 3. Now compare those to the result we got from the program when n = 3 and k = 2.
correct program (incorrect)
k = 3 k = 2
1 1 1 1 1
1 1 2 1 1
1 1 3 1 1
1 2 2 1 2
1 2 3 1 2
1 3 3 1 3
2 2 2 2 2
2 2 3 2 2
2 3 3 2 3
3 3 3 3 3
Now we can see that the incorrect output of the program is the same as the first two columns of the correct answer when we set k = 3. This means that the program solves the problem for 3 columns if we set k = 2, but only displays the first two columns.
You need to stop the program from writing the same number several times.
Solution 1
One way to do this is to execute the for-loop in the subk-function only once when it writes the last number (index == (k - 1)) into the buffer s.
In order to achieve this, you need to add the following two lines to the end of your for-loop.
if (index == (k - 1))
break;
(Instead of the break you could also use return)
After you added these two lines the function should look like this:
void subk(int prev, int index)
{
int i;
if (index == k)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
s[index] = prev;
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
if (index + 1 == k)
break;
}
}
Solution 2
Another way to solve the problem is to move the line s[index] = prev; to the beginning of the function and change the k in the if-statement to k - 1.
Now the function should look like this:
void subk(int prev, int index)
{
int i;
s[index] = prev;
if (index == k - 1)
{
for (int i = 0; i<k; i++)
printf("%d ", s[i]);
printf("\n");
return;
}
for (i = prev; i <= n; ++i)
{
subk(i, index + 1);//,s,n,k);
}
}
With this solution, the for-loop is never executed when the index shows that the program is at the last 'sub-number'. It just displays the number and exits the function because of the return.
You get the right result with both solutions, but I personally like the second solution better, because there is no additional if-statement that is executed every iteration of the for-loop and the program is (slightly) faster.
I tried to sort arr by excluding those who were already selected as the largest numbers but it didn't work.
The result is this:
As I intended, at first cycle, the store is {9, 0, 0, 0, 0 ... } and when arr[i] becomes 9, the rest of process should be skipped. I have to sort it without additional functions and it's too difficult to me. What is the problem?
int i = 0;
int j = 0;
int num = 0;
int sign = 0;
int arr[10] = { 1,5,3,4,8,7,5,9,8,0 };
int max = arr[0];
int store[10] = { 0 };
int k = 0;
for (j = 0; j < 10; j++) {
printf("store: ");
for (int n = 0; n < 10; on++)
printf("%d ", store[n]);
printf("\n");
for (i = 0; i < 10; i++) {
sign = 0;
k = 0;
while (k < 10) {
if (arr[i] == store[k]) {
sign = 1;
break;
}
k++;
}
if (sign == 1) {
continue;
}
if (arr[i] > max) {
max = arr[i];
}
}
store[j] = max;
}
You have several errors here:
The array store has a size of 10, but in the jth pass through the outer loop, only j values have been filled in; the rest is still zero. So whenever you iterate over store, you should use j as upper limit.
You are looking for the max in each iteration. Therefore, it is not enough to initialise max once outside the outer loop. You do that, and it will stay 9 ever after. You should reset max for every j.
Finally, your idea to go through the array to see whether you have already processed a certain value does not work. Your array has duplicates, two 8's and two 5's. You will only place one eight and one five with your strategy and re-use the last value of max for the last two elements. (Plus, that idea lead to O(n³) code, which is very wasteful.
You can work around that by keeping an extra array where you store whether (1) or not (0) you have already processed a value at a certain index or by setting processed entries in the array to a very low value.
What you want to implement is selection sort: Find the maximum value in the whole list and move it to the front. Then find the maximum in the whole list except the first item and move it to the second slot and so on:
* 1 5 3 4 8 7 5 9 8 0
9 * 5 3 4 8 7 5 1 8 0
9 8 * 3 4 5 7 5 1 8 0
9 8 8 * 4 5 7 5 1 3 0
9 8 8 7 * 5 4 5 1 3 0
9 8 8 7 5 * 4 5 1 3 0
9 8 8 7 5 5 * 4 1 3 0
9 8 8 7 5 5 4 * 1 3 0
9 8 8 7 5 5 4 3 * 1 0
9 8 8 7 5 5 4 3 1 * 0
9 8 8 7 5 5 4 3 1 0 *
Here, all items to the left of the asterisk have been sorted and everything to the right of the asterisk is still unsorted. When the * (at position j) has moved to the right, the whole array is sorted.
This sort is in-place: It destroys the original order of the array. That is useful, because the position of an element tells us whether it has been processed or not. In the third iteration, the algorithm can distinguish between the 8 that has been sorted and the 8 that hasn't been sorted yet. (This sort is often described as sorting a hand of cards: Look fo the lowest, put it to the left and so on. If you must sort into a second array, copy the original array and sort the copy in place.)
Here's the code that sorts your array and prints out the diagram above:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int arr[10] = {1, 5, 3, 4, 8, 7, 5, 9, 8, 0};
int i = 0;
int j = 0;
for (j = 0; j < 10; j++) {
int imax = j;
int swap = arr[j];
// print array
for (i = 0; i < 10; i++) {
if (i == j) printf("* ");
printf("%d ", arr[i]);
}
printf("\n");
// find index of maximum item
for (i = j + 1; i < 10; i++) {
if (arr[i] > arr[imax]) {
imax = i;
}
}
// swap first unsorted item and maximum item
arr[j] = arr[imax];
arr[imax] = swap;
}
// print fully sorted array
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("*\n");
return 0;
}
Use i and j.
N is 10 and the data consists of shuffled numbers 0 to N-1.
j goes from 0 to N-1. At each step, you want to fill it with
the maximum of the unprocessed input.
So i goes from j+1 to N-1, in the inner loop. If arr[j] < arr[i],
swap arr[i] and arr[j].
It speeds up considerably as you get towards the end.
I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29