11 result = memo.get(args, sentinel)
13 if result is sentinel:
22 def lcs(a, b, i=None, j=None):
23 if i is None and j is None:
30 if a[i - 1] == b[j - 1]:
31 return lcs(a, b, i - 1, j - 1) + (a[i - 1],)
33 x = lcs(a, b, i, j - 1)
34 y = lcs(a, b, i - 1, j)
46 while i < len(a) or j < len(b):
47 while i < len(a) and (k == len(c) or a[i] != c[k]):
51 while j < len(b) and (k == len(c) or b[j] != c[k]):
55 while i < len(a) and j < len(b) and a[i] == b[j]:
63 Block = collections.namedtuple(
73 def compress_block(b):
78 lines=tuple(ch[2] for ch in b),
82 direction = '>' if b.kind == 'a' else '<'
85 return '{} {}'.format(direction, l)
87 return '{}{},{}\n{}'.format(
91 '\n'.join(format_line(l) for l in b.lines),
100 for change in changes(a, b, c):
104 elif block[-1][0] == change[0] and block[-1][1] + 1 == change[1]:
108 yield compress_block(block)
111 yield compress_block(block)
113 before_file_path = sys.argv[1]
114 after_file_path = sys.argv[2]
116 with open(before_file_path, 'r') as before_file:
117 before = tuple(l.rstrip() for l in before_file.readlines())
119 with open(after_file_path, 'r') as after_file:
120 after = tuple(l.rstrip() for l in after_file.readlines())
122 for block in diff(before, after):
123 print(format_block(block))