Module loda.oeis.prefix_index
Prefix index for searching integer sequences.
Expand source code
"""Prefix index for searching integer sequences."""
import copy
import functools
from .sequence import Sequence
class PrefixIndex:
class Match:
def __init__(self, size: int):
self.prefix_length = 0
self.start_index = 0
self.end_index = size # exclusive
self.finished_ids = []
def __init__(self, seqs: list):
seqs = list(filter(lambda s: len(s.terms) > 0, seqs))
max_id = functools.reduce(lambda id, s: max(id, s.id), seqs, 0)
self.__index = sorted(seqs)
self.__lookup = [0] * (max_id + 1)
for i in range(len(seqs)):
id = self.__index[i].id
self.__lookup[id] = i
def size(self) -> int:
return len(self.__index)
def get(self, id: int) -> Sequence:
return copy.copy(self.__get(id))
def __get(self, id: int) -> Sequence:
return self.__index[self.__lookup[id]]
def global_match(self) -> Match:
return PrefixIndex.Match(len(self.__index))
def refine_match(self, match: Match, term: int) -> bool:
if match.start_index >= match.end_index:
return False
arg = match.prefix_length
match.prefix_length += 1
new_start = match.start_index
while new_start < match.end_index and self.__index[new_start].terms[arg] < term:
new_start += 1
while new_start < match.end_index and self.__index[new_start].terms[arg] == term and len(self.__index[new_start].terms) == match.prefix_length:
match.finished_ids.append(self.__index[new_start].id)
new_start += 1
new_end = new_start
while new_end < match.end_index and self.__index[new_end].terms[arg] == term:
new_end += 1
match.start_index = new_start
match.end_index = new_end
return new_start < new_end
def get_match_ids(self, match: Match) -> list:
ids = [self.__index[i].id for i in range(
match.start_index, match.end_index)]
ids.extend(match.finished_ids)
return sorted(ids)
Classes
class PrefixIndex (seqs: list)
-
Expand source code
class PrefixIndex: class Match: def __init__(self, size: int): self.prefix_length = 0 self.start_index = 0 self.end_index = size # exclusive self.finished_ids = [] def __init__(self, seqs: list): seqs = list(filter(lambda s: len(s.terms) > 0, seqs)) max_id = functools.reduce(lambda id, s: max(id, s.id), seqs, 0) self.__index = sorted(seqs) self.__lookup = [0] * (max_id + 1) for i in range(len(seqs)): id = self.__index[i].id self.__lookup[id] = i def size(self) -> int: return len(self.__index) def get(self, id: int) -> Sequence: return copy.copy(self.__get(id)) def __get(self, id: int) -> Sequence: return self.__index[self.__lookup[id]] def global_match(self) -> Match: return PrefixIndex.Match(len(self.__index)) def refine_match(self, match: Match, term: int) -> bool: if match.start_index >= match.end_index: return False arg = match.prefix_length match.prefix_length += 1 new_start = match.start_index while new_start < match.end_index and self.__index[new_start].terms[arg] < term: new_start += 1 while new_start < match.end_index and self.__index[new_start].terms[arg] == term and len(self.__index[new_start].terms) == match.prefix_length: match.finished_ids.append(self.__index[new_start].id) new_start += 1 new_end = new_start while new_end < match.end_index and self.__index[new_end].terms[arg] == term: new_end += 1 match.start_index = new_start match.end_index = new_end return new_start < new_end def get_match_ids(self, match: Match) -> list: ids = [self.__index[i].id for i in range( match.start_index, match.end_index)] ids.extend(match.finished_ids) return sorted(ids)
Class variables
var Match
Methods
def get(self, id: int) ‑> Sequence
-
Expand source code
def get(self, id: int) -> Sequence: return copy.copy(self.__get(id))
def get_match_ids(self, match: PrefixIndex.Match) ‑> list
-
Expand source code
def get_match_ids(self, match: Match) -> list: ids = [self.__index[i].id for i in range( match.start_index, match.end_index)] ids.extend(match.finished_ids) return sorted(ids)
def global_match(self) ‑> PrefixIndex.Match
-
Expand source code
def global_match(self) -> Match: return PrefixIndex.Match(len(self.__index))
def refine_match(self, match: PrefixIndex.Match, term: int) ‑> bool
-
Expand source code
def refine_match(self, match: Match, term: int) -> bool: if match.start_index >= match.end_index: return False arg = match.prefix_length match.prefix_length += 1 new_start = match.start_index while new_start < match.end_index and self.__index[new_start].terms[arg] < term: new_start += 1 while new_start < match.end_index and self.__index[new_start].terms[arg] == term and len(self.__index[new_start].terms) == match.prefix_length: match.finished_ids.append(self.__index[new_start].id) new_start += 1 new_end = new_start while new_end < match.end_index and self.__index[new_end].terms[arg] == term: new_end += 1 match.start_index = new_start match.end_index = new_end return new_start < new_end
def size(self) ‑> int
-
Expand source code
def size(self) -> int: return len(self.__index)