Search code examples
listalgorithmmathdata-structuresnested

How to find element with offset in nested lists?


I'm currently work on an algorithmic problem in c# (Language doesn't matter). I have 3 nested lists with that are not the same length (see the illustration below).

Problem illustration

// Elements can be anything. For example, here i used strings
List<List<List<string>>> elements = new()
{
    new() { new List<string>() { "E0", "E1" }, new List<string>() { "E2" } },
    new() { new List<string>() { "E3" }, new List<string>() { "E4", "E5" }, new List<string>() { "E6", "E7", "E8" } },
    new() { new List<string>() { "E9" } }
};

I know the i, j and k indexes for a given element (we can call it E) and I'm trying to find the indexes of another element (F) with an offset from E.

On this example, we are trying to find F indexes (1,2,1) by only knowing E indexes (0,1,0) and the offset (5 in this case).

I'm trying to find how to transform my 3 nested lists into a data structure that allows me to solve this problem easily.

Any help or idea are welcomed :)

I have tried to use if/else system but it was way to complicated. I also tried some Data Structures without any success.


Solution

  • If you decide to not change the data structure, you can still walk through the tree as follows:

    void walk(List<List<List<string>>> a, int[] indices, int distance) {
        while (indices[0] < a.Count) {
            List<List<string>> b = a[indices[0]];
            while (indices[1] < b.Count) {
                List<string> c = b[indices[1]];
                while (indices[2] < c.Count) {
                    if (distance-- <= 0) return; // Found target
                    indices[2]++;
                }
                indices[1]++;
                indices[2] = 0;
            }
            indices[0]++;
            indices[1] = 0;
        }
        // Out of range. Caller could check if `indices[0]` is within range
    }
    

    Example call:

    // Example input given in the question
    List<List<List<string>>> elements = new()
    {
        new() { new List<string>() { "E0", "E1" }, new List<string>() { "E2" } },
        new() { new List<string>() { "E3" }, new List<string>() { "E4", "E5" }, new List<string>() { "E6", "E7", "E8" } },
        new() { new List<string>() { "E9" } }
    };
    int[] indices = {0, 1, 0}; // Starting point
    walk(elements, indices, 5); // Walk 5 steps
    System.Console.WriteLine(string.Join(", ", indices));  // 1, 2, 1