Untitled
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 ansEditor is loading...
Leave a Comment