# Path: memoize.py
# def memoize(f):
#     """ Memoization decorator for a function taking one or more arguments. """
#     class memodict(dict):
#         def __getitem__(self, *key, **kwkey):
#             return dict.__getitem__(self, (tuple(key), tuple((k, kwkey[k]) for k in sorted(kwkey.keys()))))
# 
#         def __missing__(self, key):
#             args, kwargs = key
#             self[key] = ret = f(*args, **dict(kwargs))
#             return ret
# 
#     return memodict().__getitem__


import subprocess, sys
from memoize import memoize
                    ret = f(arg[start:new_end])
                if mid < new_end and ret is GOOD:
                    mid = new_end
                elif new_end < end and ret is BAD:
                    end = new_end
                else:
                    new_end = orig_new_end
                    while ret is INVALID and mid < new_end:
                        new_end -= 1
                        ret = f(arg[start:new_end])
                    if mid == new_end:
                        end = new_end
                    elif ret is GOOD:
                        mid = new_end
                    elif ret is BAD:
                        end = new_end
                    else:
                        sys.stderr.write("This should be impossible\n")
                        end = mid
                        break
    while end + 1 < len(arg) and f(arg[start:end + 1]) == GOOD:
        sys.stderr.write("This should be impossible (2)\n")
        end += 1
    orig_end = end
    while end + 1 < len(arg):
        end += 1
        if f(arg[start:end]) == GOOD:
            orig_end = end
    return arg[start:orig_end]


# Path: memoize.py
# def memoize(f):
#     """ Memoization decorator for a function taking one or more arguments. """
#     class memodict(dict):
#         def __getitem__(self, *key, **kwkey):
#             return dict.__getitem__(self, (tuple(key), tuple((k, kwkey[k]) for k in sorted(kwkey.keys()))))
# 
#         def __missing__(self, key):
#             args, kwargs = key
#             self[key] = ret = f(*args, **dict(kwargs))
#             return ret
# 
#     return memodict().__getitem__


# Path: examples/prefix-grep.py
import subprocess, sys
from memoize import memoize

                    ret = f(arg[start:new_end])
                if mid < new_end and ret is GOOD:
                    mid = new_end
                elif new_end < end and ret is BAD:
                    end = new_end
                else:
                    new_end = orig_new_end
                    while ret is INVALID and mid < new_end:
                        new_end -= 1
                        ret = f(arg[start:new_end])
                    if mid == new_end:
                        end = new_end
                    elif ret is GOOD:
                        mid = new_end
                    elif ret is BAD:
                        end = new_end
                    else:
                        sys.stderr.write("This should be impossible\n")
                        end = mid
                        break
    while end + 1 < len(arg) and f(arg[start:end + 1]) == GOOD:
        sys.stderr.write("This should be impossible (2)\n")
        end += 1
    orig_end = end
    while end + 1 < len(arg):
        end += 1
        if f(arg[start:end]) == GOOD:
            orig_end = end
    return arg[start:orig_end]


@memoize