You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.1 KiB
51 lines
1.1 KiB
1 year ago
|
import typing
|
||
|
|
||
|
|
||
|
def yep(s: str) -> bool:
|
||
|
return s.strip().lower().startswith("y")
|
||
|
|
||
|
|
||
|
def guess_bisect_repl(lower: int, upper: int) -> int:
|
||
|
mid = lower + ((upper - lower) // 2)
|
||
|
|
||
|
if yep(input(f"is it {mid}? ")):
|
||
|
return mid
|
||
|
|
||
|
if yep(input(f"higher than {mid}? ")):
|
||
|
return guess_bisect_repl(mid, upper)
|
||
|
|
||
|
return guess_bisect_repl(lower, mid)
|
||
|
|
||
|
|
||
|
def find_sqrt_ish(n: int) -> int:
|
||
|
return int(find_bisect(0, n, gen_sqrt_check(n)))
|
||
|
|
||
|
|
||
|
def gen_sqrt_check(n: int) -> typing.Callable[[float], int]:
|
||
|
def check(mid: float) -> int:
|
||
|
mid_sq: float = mid * mid
|
||
|
|
||
|
if mid_sq == n:
|
||
|
return 0
|
||
|
|
||
|
if mid_sq < n:
|
||
|
return 1
|
||
|
|
||
|
return -1
|
||
|
|
||
|
return check
|
||
|
|
||
|
|
||
|
def find_bisect(lower: float, upper: float, check: typing.Callable[[float], int]) -> float:
|
||
|
mid: float = lower + ((upper - lower) / 2)
|
||
|
|
||
|
print(f"lower={lower} mid={mid} upper={upper}")
|
||
|
|
||
|
if mid == lower or mid == upper or check(mid) == 0:
|
||
|
return mid
|
||
|
|
||
|
if check(mid) == 1:
|
||
|
return find_bisect(mid, upper, check)
|
||
|
|
||
|
return find_bisect(lower, mid, check)
|