entry #1
written by olus2000
submitted at
0 likes
guesses
- LyricLy (by moshikoi)
- MattiDragon (by Palaiologos)
- Olivia (by MattiDragon)
- moshikoi (by Olivia)
- olus2000 (by LyricLy)
comments 0
bad.c ASCII text, with CRLF line terminators
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | from dataclasses import dataclass, field from typing import Optional @dataclass class Node: first : 'List' link : Optional['Node'] = None @dataclass class List: start : int len : int node : Optional[Node] = None next : Optional['List'] = None def make_tree(s: str) -> Node: tree = Node(List(0, -1)) cur = tree start = 0 for b in range(len(s)): cur, start = extend(cur, start, b - start, s + '\x00') return tree def find_l(node: Node, start: int, s1: str, s2: str) -> (List, bool): l = node.first while s1[l.start] != s2[start]: if l.next is None: return l, False l = l.next return l, True def extend(node: Node, start: int, len: int, s: str) -> (Node, int): if len < 0: return node, start l, flag = find_l(node, start, s, s) if not flag: assert len == 0 l.next = List(start, -1) l = l.next if l.node is None and len == l.len + 1: # 1st l.start = start l.len = len next_node, next_start, next_len = next_node_start(node, start, len) extend(next_node, next_start, next_len, s) return node, start elif len > l.len: return extend(l.node, start + l.len + 1, len - l.len - 1, s) elif s[l.start + len] == s[start + len]: # 3rd return node, start else: # 2nd new_node = Node(List(start + len, 0, None, List(l.start + len, l.len - len, l.node))) l.len = len - 1 l.node = new_node next_node, next_start, next_len = next_node_start(node, start, len) new_node.link, new_start = extend(next_node, next_start, next_len, s) return new_node, new_start def next_node_start(node: Node, start: int, len: int) -> (Node, int, int): if node.link: return node.link, start, len return node, start + 1, len - 1 def suffixes(node: Node, s: str): l = node.first while l is not None: if l.node is not None: yield from (s[l.start:l.start + l.len + 1] + i for i in suffixes(l.node, s)) else: yield s[l.start:l.start + l.len + 1] l = l.next def entry(s1, s2): node = make_tree(s1) best = '' match_len = 0 len = 0 start = 0 for i, c in enumerate(s2): len += 1 l, found = find_l(node, start, s1, s2) while start <= i and (not found or l.len < i - start or s1[l.start + i - start] != c): if not found or l.node is None or l.len >= i - start and s1[l.start + i - start] != c: node, start, _ = next_node_start(node, start, 0) len -= 1 else: node = l.node start += l.len + 1 if start > i: break l, found = find_l(node, start, s1, s2) if len > match_len: best = s2[i + 1 - len:i + 1] match_len = len return best |
post a comment