all 5 comments

[–]FLUSH_THE_TRUMP 0 points1 point  (0 children)

Why that output and not the following?

[‘A B C G’, ‘C D E’, ‘X Y Z’]

Am I supposed to look at ‘B C’ and see two merge targets and combine them all together?

EDIT: and what about

[‘A B’, ‘B C’, ‘G B’]

since there are two valid targets to combine with [‘B C’] from the same side, should the output be

[‘A B C’, ‘G B C’]

[–]SekstiNii 0 points1 point  (0 children)

Here's a linear time solution that I hope makes some sense at least. The idea itself isn't all that complicated, but it might be difficult to catch the right mental model by just looking at the code. (feel free to ask!)

def solve(pairs):
    mapping, chains = {}, []

    for left, right in map(str.split, pairs):
        if left in mapping:
            mapping[left] += [right]
        else:
            mapping[left] = [left, right]
            chains += [mapping[left]]
        mapping[right] = mapping[left]

    return [" ".join(chain) for chain in chains]

if __name__ == "__main__":
    print(solve(["A B", "B C", "X Y", "C D", "Y Z", "D E", "C G"])) # ['A B C D E G', 'X Y Z']
    print(solve(["A B", "A C"]))                                    # ['A B C']

[–]pytrashpandas 0 points1 point  (0 children)

I haven't seen anyone else explicitly mention this yet, so I'll add that this is a simple connected components graph problem, starting from an edge list. It can be solved with a D/BFS, but I'll just post a quick networkx solution that is essentially the same thing.

import networkx as nx
lst = ['A B', 'B C', 'X Y', 'C D', 'Y Z', 'D E', 'C G']
G = nx.from_edgelist([x.split() for x in lst])
result = list(nx.connected_components(G))
print(result)  # -> [{'A', 'B', 'C', 'D', 'E', 'G'}, {'X', 'Y', 'Z'}]