Here's a solution in Python for an arbitrary number of sequences. You can use it to test your solution for 2D, 3D enclosures. He closely follows the Wikipedia algorithm :
#!/usr/bin/env python import functools from itertools import starmap @memoize def lcs(*seqs): """Find longest common subsequence of `seqs` sequences. Complexity: O(len(seqs)*min(seqs, key=len)*reduce(mul,map(len,seqs))) """ if not all(seqs): return ()
Note: without memoization, this is an exponential algorithm ( wolfram alpha ):
$ RSolve[{a[n] == K a[n-1] + K, a[0] = K}, a[n], n] a(n) = (K^(n + 1) - 1) K/(K - 1)
where K == len(seqs) and n == max(map(len, seqs))
Examples
>>> lcs("agcat", "gac") ('g', 'a') >>> lcs("banana", "atana") ('a', 'a', 'n', 'a') >>> lcs("abc", "acb") ('a', 'c') >>> lcs("XMJYAUZ", "MZJAWXU") ('M', 'J', 'A', 'U') >>> lcs("XMJYAUZ") ('X', 'M', 'J', 'Y', 'A', 'U', 'Z') >>> lcs("XMJYAUZ", "MZJAWXU", "AMBCJDEFAGHI") ('M', 'J', 'A') >>> lcs("XMJYAUZ", "MZJAWXU", "AMBCJDEFAGUHI", "ZYXJAQRU") ('J', 'A', 'U') >>> lcs() #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: >>> lcs(*"abecd acbed".split()) ('a', 'b', 'e', 'd') >>> lcs("acd", lcs("abecd", "acbed")) ('a', 'd') >>> lcs(*"abecd acbed acd".split()) ('a', 'c', 'd')