import re A_UPPERCASE = ord('a') ALPHABET_SIZE = 26 def _decompose(number): """Generate digits from `number` in base alphabet, least significants bits first. Since A is 1 rather than 0 in base alphabet, we are dealing with `number - 1` at each iteration to be able to extract the proper digits. """ while number: number, remainder = divmod(number - 1, ALPHABET_SIZE) yield remainder def base_10_to_alphabet(number): """Convert a decimal number to its base alphabet representation""" return ''.join( chr(A_UPPERCASE + part) for part in _decompose(number) )[::-1] def remove_prefix(s, prefix): return s[len(prefix):] if s.startswith(prefix) else s def find_longest_path(paths): ms = 0 mp = None for path in paths: s = len(path) if s > ms: ms = s mp = path return mp def find_shortest_path(paths): ms = float('inf') mp = None for path in paths: s = len(path) if s < ms: ms = s mp = path return mp def find_common_ancestor(paths): if len(paths) == 0: return None shortest_path = find_shortest_path(paths) last_common = None for gen_i,_ in enumerate(shortest_path): common = True last_node = paths[0][gen_i] for path in paths: if last_node == path[gen_i]: common = True last_node = path[gen_i] else: common = False if common: last_common = last_node return last_common def comment_remover(text): def replacer(match): s = match.group(0) if s.startswith('/'): return "" else: return s pattern = re.compile( r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE ) return re.sub(pattern, replacer, text)