def reduce(inp: str, test: str -> bool):  assert test(inp) == False  # v remove 1/2 of the lines.  n = 2 # Initial granularity  while len(inp) >= 2:    ix = 0    found_failure = False    skiplen = len(inp) / n    while ix < len(inp):      inp_noix = inp[:ix] +inp[ix+skiplen:]      if not self.test(inp_noix):          inp = inp_noix # use smaller input          n = max(n - 1, 2) # decrease granularity by 1          found_failure = True; break      else:        ix += skiplen    if not found_failure:      if n == len(inp): break      n = min(n * 2, len(inp)) # double  return inp