0

I have already asked a question here. And I achieved the answer. Actually, this is a kind of different path, i.e., I have two options for each level, up(1) or down(-1), and I have the n level. Therefore I have 2^n path.

Now in this current question, I want to select some desired paths. My desired paths have two conditions as follows.

  1. The end of a given path reaches, let say, 1. Thus, I want to select those paths which finally reach 1i.e., the sum of a given path with n level is 1.

  2. I want to bound those paths in #1 between, let say, 9 and -9. For example, I want to avoid the sum of 9 up or 9 down in sequence, which is bigger than 9 and less than -9.

Here is my attempt:

int popcount(unsigned x){
    int c = 0;
    for (; x != 0; x >>= 1)
        if (x & 1)
            c++;
    return c;
}
void selected_path(vector<int> &d, int n){
    d.clear();
    int size = 1<<n;
    d.resize(size);
    for (int i = 0; i  < size; ++i) {
            d[i] = n-2.0*popcount(i);
    }
}

In the above code, d[] gives me all possible paths, i.e. 2^n. But I want to select those paths with the above 2 conditions.

Edit: the answer but not efficient!

#include <iostream> 
#include <vector> 
#include <algorithm>
using namespace std; 

struct node{ 
    int data; 
    node *left, *right; 
}; 

struct node *create(int x, int n, int limit){
    struct node *newnode;
    newnode = new node();
    n++;
    if(n==(limit+2)) return 0;
    newnode->data = x;
    x =  newnode->data + 1;
    newnode->left = create(x,n,limit);
    x =  newnode->data -1 ;
    newnode->right = create(x, n,limit);
    return newnode;
}

void inorder(std::vector<int> &d, node *root, vector<int> &stack, int uplimit, int downlimit){ //uplimit,downlimit
    if(root == NULL) return;
    stack.push_back(root->data);
    
    inorder(d,root->left,stack,uplimit,downlimit);
    if(root->left == 0 and root->right ==0){
        if(stack[stack.size() -1] == 1){
            int max=*max_element(stack.begin(), stack.end());
            int min=*min_element(stack.begin(), stack.end());
            if(max < uplimit and min > downlimit){
                for(int i = 1; i < stack.size(); i++){
                    d.push_back(stack[i]);
                }
            }
        }
    }
    inorder(d,root->right,stack,uplimit,downlimit);
    stack.pop_back(); 
}
int main(){
    
    int limit = 7;
    struct node *root;
    root = create(0,0,limit);

    std::vector<int> stack;
    std::vector<int>  d;
    int uplimit = 9;
    int downlimit = -9;
    
    inorder(d,root, stack,uplimit,downlimit);
    stack.clear();
    int n_path = int(d.size()/(limit));
    for(int ip =0; ip < n_path; ip++){
        for(int i = 1; i <=limit; i++){
            cout << d[ip*(limit)+(i-1)] << "\t";
        }
        cout << endl;
    }
}

A possible answer can be as above code. Here d[] is a two-dimension array, which is the first one is the number of the paths, and the second dimension is the value of nodes during the path.

But the problem is that it is not efficient in terms of memory (if limit > 20) due to the root-> data saves all possible nodes, which is unnecessary.

I would highly appreciate it if one could give some idea to make it efficient

Ghoti
  • 43
  • 8
  • 2
    It's not clear; please post a [mcve] showing your attempt and make each question self-contained. – Richard Critten Feb 01 '21 at 13:12
  • 1
    I think you should answer this yourself. It involves thinking hard about logic and strategies to achieve your goal. – Paul Ogilvie Feb 01 '21 at 13:22
  • @PaulOgilvie, yes It involves thinking hard. I was thinking for a long time, and I decided to post it as a question, maybe someone has some good idea – Ghoti Feb 01 '21 at 13:24
  • 1
    BTW, the `pow` function is floating point and you may run into precision or accuracy issues when converting between integer to floating point and back. Better to use `1 << n` than `pow(2, n)`. – Thomas Matthews Feb 01 '21 at 16:15
  • @ThomasMatthews, you are right. I edited it. thanks – Ghoti Feb 01 '21 at 16:44
  • 1
    You are looking for paths in a tree, not in a nested loop. It seems you are using an unsigned integer to represent a path and computing its final value. There does not seem to be any "selection" happening. If you want to compute the final value and the max/min attained during the tree walk for a path designated by the integer N, then just do that. IOW, change your `popcount` to also keep track of the max/min of the intermediate steps. – William Pursell Feb 01 '21 at 16:55
  • @WilliamPursell. I think you are right. this is a binary tree. I edited the title. thanks. Could you please explain a little more in detail, thanks? – Ghoti Feb 01 '21 at 17:08

0 Answers0