ยง Delta debugging

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