checkio (water jars)

You stand by the edge of a lake with two empty jars. You notice that both of the jars have a volume. You can fill each jar with water from the lake, pour water from one jar to other or pour water back into lake. You should measure the volume of water in either jar. The required volume of water may be in either of the jars and it does not matter which.

Each action is described as a string of two symbols: from and to. The jars are marked as 1 and 2, the lake is marked 0. If you want to take water from the lake and fill first jar, then it's "01". To pour water from second jar into the first would be "21". Dump water out of the first jar and back into the lake would be "10". When you fill a jar from the lake, that jars volume will be full. When you pour water out a jar and into the lake, that jars volume will be empty. If you pour water from one jar to another, you can only pour as much as will fill the full volume of the receiving jar.

water-jars

The function has three arguments: The volume of first jar, the volume of second jar and the goal. All arguments are positive integers (number > 0). You should return a list with action's sequence. If a solution does not exist, then return an empty list.
The solution must contain the minimum possible number of steps

Input: The volume of first jar, the volume of second jar and the goal. Positive integers.

Output: A sequence of steps. A list with strings.

Example:

?
1
2
checkio(5, 7, 6) == ['02', '21', '10', '21', '02', '21', '10', '21', '02', '21']
checkio(3, 4, 1) == ["02", "21"]

经典的倒水问题,求最少的操作序列
from collections import deque

def checkio(first_volume, second_volume, goal):
    actions = {
        "01": lambda f, s: (first_volume, s),
        "02": lambda f, s: (f, second_volume),
        "12": lambda f, s: (
            f - (second_volume - s if f > second_volume - s else f),
            second_volume if f > second_volume - s else s + f),
        "21": lambda f, s: (
            first_volume if s > first_volume - f else s + f,
            s - (first_volume - f if s > first_volume - f else s),
        ),
        "10": lambda f, s: (0, s),
        "20": lambda f, s: (f, 0)
    }

    first, second = 0, 0
    queue = deque()
    queue.append((first, second))
    visit = {(first, second):1}
    last = {}
    end = None

    while queue:
        node = queue.popleft()
        if node[0] == goal or node[1] == goal:
            end = node
            break
        for act in ['01', '02', '12', '21', '10', '20']: 
            first, second = actions[act](node[0], node[1])
            if (first, second) not in visit:
                queue.append((first, second))
                visit[(first, second)] = 1
                last[(first, second)] = node, act

    ans = []
    status = end
    while status != (0, 0):
        ans.append(last[status][1])
        status = last[status][0]
    ans.reverse()
    return ans


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值