Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import collections
- def jugPuzzle(jugs, goal, start=None):
- '''Given n jugs of specified capacities, use BFS to try to find a sequence
- of fillings, emptyings and transferings of water that will produce the goal
- amount from the start state. Otherwise return empty list.'''
- if not start:
- start = (0,) * len(jugs)
- if not (0 <= goal <= max(jugs)):
- return []
- if goal in start:
- return [('start', start)]
- paths = collections.deque([[('start', start)]])
- seen = set([start])
- while paths:
- path = paths.popleft()
- lastAction, lastState = path[-1]
- for action, state in successors(jugs, lastState):
- if state not in seen:
- currPath = path + [(action, state)]
- # goal reached
- if goal in state:
- return currPath
- paths.append(currPath)
- seen.add(state)
- # no path found
- return []
- def successors(jugs, levels):
- '''Compute all non-trivial successor states. Return as a list of (action, state) tuples.'''
- result = []
- L = len(jugs)
- for i in range(L):
- if levels[i] < jugs[i]:
- action = 'fill %d' % i
- state = tuple(jugs[j] if j == i else levels[j] for j in range(L))
- result.append((action, state))
- if levels[i] > 0:
- action = 'empty %d' % i
- state = tuple(0 if j == i else levels[j] for j in range(L))
- result.append((action, state))
- for j in range(L):
- if j != i and levels[j] < jugs[j]:
- action = '%d -> %d' % (i, j)
- total = levels[i] + levels[j]
- iLevel = max(0, total - jugs[j])
- jLevel = min(jugs[j], total)
- state = tuple(iLevel if k == i else jLevel if k == j
- else levels[k] for k in range(L))
- result.append((action, state))
- return result
- # demo
- print(*jugPuzzle([100, 13, 43], 98), sep='\n')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement