Untitled

 avatar
unknown
plain_text
10 months ago
1.1 kB
13
Indexable
def min_moves(source, target):
    """
    Returns the minimum number of +1 operations needed to turn `source` into `target`,
    where an operation is: pick (index, left/right) and increment all elements from
    index to the chosen side by +1. Returns -1 if impossible.
    """
    n = len(source)
    src = tuple(source)
    tgt = tuple(target)

    def apply(state, index, left):
        a = list(state)
        if left:  # increment index -> 0
            for k in range(index, -1, -1):
                a[k] += 1
        else:     # increment index -> n-1
            for k in range(index, n):
                a[k] += 1
        return tuple(a)

    @lru_cache(maxsize=None)
    def dfs(state):
        if state == tgt:
            return 0
        # pruning: if any entry already exceeds target, this path is dead
        if any(s > t for s, t in zip(state, tgt)):
            return inf

        best = inf
        for i in range(n):
            best = min(best, 1 + dfs(apply(state, i, True)))
            best = min(best, 1 + dfs(apply(state, i, False)))
        return best

    ans = dfs(src)
    return -1 if ans == inf else ans
Editor is loading...
Leave a Comment