====== seqtask.py ====== ===== imports and globals ===== import bisect import operator from collections.abc import Hashable, Iterable, Reversible, Sequence from typing import Any, Literal from teflib.common.types import Sortable, Index, Count ===== longest_inc_subseq_length / longest_dec_subseq_length ===== ==== 코드 ==== def longest_inc_subseq_length[T: Sortable]( seq: Iterable[T], *, strict: bool = False ) -> Count: """Compute length of LIS of given sequence.""" bisect_func = bisect.bisect_left if strict else bisect.bisect_right comp_func = operator.gt if strict else operator.ge seq_iter = iter(seq) if (first_elem := next(seq_iter, None)) is None: return 0 last_elem_by_len = [first_elem] for elem in seq_iter: if comp_func(elem, last_elem_by_len[-1]): last_elem_by_len.append(elem) else: last_elem_by_len[bisect_func(last_elem_by_len, elem)] = elem return len(last_elem_by_len) def longest_dec_subseq_length[T: Sortable]( seq: Reversible[T], *, strict: bool = False ) -> Count: """Compute length of LDS of given sequence.""" return longest_inc_subseq_length(reversed(seq), strict=strict) ==== 설명 ==== * [[ps:tutorial:lis]] 참고 ==== 이 코드를 사용하는 문제 ==== ---- struct table ---- schema: ps cols: site, prob_id, %title%, prob_level filter: teflib ~ *[seqtask.longest_inc_subseq_length]* filteror: teflib ~ *[seqtask.longest_dec_subseq_length]* csv: 0 ---- ===== longest_inc_subseq_length_by_last_elem / longest_dec_subseq_length_by_last_elem ===== ==== 코드 ==== def longest_inc_subseq_length_by_last_elem[T: Sortable]( seq: Sequence[T], *, strict: bool = False ) -> list[Count]: """Returns a list L, where L[i] is length of LIS that ends with seq[i].""" if not seq: return [] bisect_func = bisect.bisect_left if strict else bisect.bisect_right comp_func = operator.gt if strict else operator.ge seq_iter = iter(seq) last_elem_by_len, lengths, l = [next(seq_iter)], [1], 1 for elem in seq_iter: if comp_func(elem, last_elem_by_len[-1]): last_elem_by_len.append(elem) l += 1 lengths.append(l) else: ind = bisect_func(last_elem_by_len, elem) last_elem_by_len[ind] = elem lengths.append(ind + 1) return lengths def longest_dec_subseq_length_by_last_elem[T: Sortable]( seq: Sequence[T], *, strict: bool = False ) -> list[Count]: """Returns a list L, where L[i] is length of LDS that ends with seq[i].""" if not seq: return [] bisect_func = bisect.bisect_right if strict else bisect.bisect_left comp_func = operator.lt if strict else operator.le seq_iter = iter(seq) last_elems: list[Any] = [None] * len(seq) last_elems[-1] = next(seq_iter) lengths, beg, end = [1], len(seq) - 1, len(seq) for elem in seq_iter: if comp_func(elem, last_elems[beg]): beg -= 1 last_elems[beg] = elem lengths.append(end - beg) else: ind = bisect_func(last_elems, elem, beg, end) - 1 last_elems[ind] = elem lengths.append(end - ind) return lengths ==== 설명 ==== * [[ps:tutorial:lis]] 참고 ==== 이 코드를 사용하는 문제 ==== ---- struct table ---- schema: ps cols: site, prob_id, %title%, prob_level filter: teflib ~ *[seqtask.longest_inc_subseq_length_by_last_elem]* filteror: teflib ~ *[seqtask.longest_dec_subseq_length_by_last_elem]* csv: 0 ----