# 이런 클래스를 만들면..
class MySeq:
def __getitem__(self, x):
return x
def f(x: int) -> bool:
...
def g(x: int) -> int
...
# 그냥 이렇게 쓸수 있잖아?
answer = bisect.bisect_left(MySeq(), x, lo, hi) # [lo,hi] 에서 x를 찾기
answer = bisect.bisect_left(MySeq(), 1, lo, hi, key=f) # [lo,hi] 에서 f(x)가 True인 최소의 x를 찾기
answer = bisect.bisect_left(MySeq(), b, lo, hi, key=g) # [lo,hi] 에서 g(x)>=b인 최소의 x를 찾기
def g(x: int) -> int
...
class G:
def __getitem__(self, x):
return g(x)
answer = bisect.bisect_left(G(), b, lo, hi) # [lo,hi] 에서 g(x)>=b인 최소의 x를 찾기
[업데이트]
def minimum_valid_integer(
beg: int, end: int, is_valid_func: Callable[[int], bool]
) -> int:
seq = type('X', (), {'__getitem__': lambda self, x: is_valid_func(x)})()
return bisect.bisect_left(seq, True, beg, end - 1)
함수 | CPython | Pypy |
---|---|---|
minimum_valid_integer | 1072ms | 4788ms |
binary_search | 616ms | 264ms |
minimum_valid_integer2 | 668ms | 304ms |
minimum_valid_integer3 | 648ms | 348ms |
def binary_search(beg, end, predicate):
while beg < end:
mid = (beg + end) >> 1
if predicate(mid):
end = mid
else:
beg = mid + 1
return beg
class Seq:
def __init__(self, is_valid_func):
self._is_valid_func = is_valid_func
def __getitem__(self, x):
return self._is_valid_func(x)
def minimum_valid_integer2(
beg: int, end: int, is_valid_func: Callable[[int], bool]
) -> int:
return bisect.bisect_left(Seq(is_valid_func), True, beg, end - 1)
_SEQ = type('_X', (), {'__getitem__': lambda self, x: x})()
def minimum_valid_integer3(
beg: int, end: int, is_valid_func: Callable[[int], bool]
) -> int:
return bisect.bisect_left(_SEQ, True, beg, end - 1, key=is_valid_func)