How to start an interval from the second list in the first list?

143 views Asked by At
wells = [
    [
        [0, 0.4, 'pop'],
        [0.4, 0.8, 'sup'],
        [0.8, 1.2, 'muka'],
        [1.2, 2, 'sand'],
        [2, 2.4, 'buz']
    ],
    [
        [0, 0.4, 'pop'],
        [0.4, 1.6, 'sand'],
        [1.6, 2, 'graviy'],
        [2, 3.2, 'galka'],
        [3.2, 3.6, 'buz']
    ]
]

def find_matching_points_all(*lists):
    matching_points = []

    for i in range(len(lists) - 1):
        list1 = lists[i]
        list2 = lists[i + 1]

        prev_point = None

        for point1 in list1:
            found_match = False
            for point2 in list2:
                if point1[2] == point2[2]:
                    matching_points.append((point1[1], point2[1]))
                    prev_point = point2
                    found_match = True
                    break

            if not found_match and prev_point is not None:
                matching_points.append((point1[1], prev_point[1]))

    return matching_points

matching_points = find_matching_points_all(wells[0], wells[1])

for pair in matching_points:
    print(f"{pair[0]} connects with {pair[1]}")
print()

Each list list in wells is in this format - [interval from, interval to, interval description].

My code connects the points from the first and second list. The first condition is an interval of the same description. The second condition is that if the description is different, then we connect it to the previous interval.

I need to expand the code so that the interval [1.6, 2, 'graviy'] starts on the first list. Namely, in the interval [1.2, 2, 'sand']. That is, in fact, in the first list we have a point from which the interval of the second list will begin.

In the picture, red lines mark the connections that need to be created. Green lines are lines that my code can already create

enter image description here

I tried to find the logic, but I couldn’t find it

1

There are 1 answers

0
blhsing On BEST ANSWER

You can convert the two lists of well layers into queues to efficiently dequeue a layer whose name is not shared by the two wells until a common layer is encountered, at which point switch to the other well to continue the dequeue.

from collections import deque

def well_connections(wells):
    common = set.intersection(*({name for *_, name in well} for well in wells))
    wells = list(map(deque, wells))
    this = 0
    while all(wells):
        if all(well[0][2] in common for well in wells):
            yield tuple(well[0][1] for well in wells)
            if len(wells[this]) > 1 and wells[this][1][2] in common:
                this = 1 - this
            wells[this].popleft()
        while wells[this] and wells[this][0][2] not in common:
            yield tuple(well[0][1] for well in wells)
            wells[this].popleft()
        this = 1 - this
        wells[this].popleft()

so that:

list(well_connections(wells))

returns:

[(0.4, 0.4), (0.8, 0.4), (1.2, 0.4), (2, 1.6), (2, 2), (2, 3.2), (2.4, 3.6)]

Demo: https://ideone.com/TVOFDE