from collections import deque
from itertools import count
def new_states( state, jug1, jug2) :
j1, j2 = state
states = [ ( jug1, j2) , ( j1, jug2) , ( j1, 0 ) , ( 0 , j2) ]
fill = min ( jug1 - j1, j2)
states.append ( ( j1 + fill, j2 - fill) ) # fill 1 from 2
fill = min ( jug2 - j2, j1)
states.append ( ( j1 - fill, j2 + fill) ) # fill 2 from 1
return [ s for s in states if s != state]
def solve( jug1, jug2, target) :
Q = deque( [ ( 0 , 0 ) ] ) # BFS
parent = { }
while Q:
state = Q.popleft ( )
states = new_states( state, jug1, jug2)
for s in states:
if s in parent:
continue
parent[ s] = state
if target in s or target == sum ( s) :
return s, parent
Q.append ( s)
def path( state, parents) :
path = [ state]
while True :
state = parents[ state]
path.append ( state)
if state == ( 0 , 0 ) :
break
return path[ ::-1 ]
def description( statea, stateb) :
sa1, sa2 = statea
sb1, sb2 = stateb
if sa1 == sb1:
return "fill 2 from tap" if sb2 else "empty 2"
elif sa2 == sb2:
return "fill 1 from tap" if sb1 else "empty 1"
else :
return "fill 1 from 2" if sa1 < sb1 else "fill 2 from 1"
jug1, jug2 = 13 , 23
target = 4
solution = solve( jug1, jug2, target)
print ( "jug1: {} jug2: {} target: {}" .format ( jug1, jug2, target) )
if solution:
s, parent = solution
pat = path( s, parent)
for step, s1, s2 in zip ( count( 1 ) , pat, pat[ 1 :] ) :
print ( step, s2, description( s1, s2) )
else :
print ( "No solution" )
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVxdWUKZnJvbSBpdGVydG9vbHMgaW1wb3J0IGNvdW50CgoKZGVmIG5ld19zdGF0ZXMoc3RhdGUsIGp1ZzEsIGp1ZzIpOgogICAgajEsIGoyID0gc3RhdGUKICAgIHN0YXRlcyA9IFsoanVnMSwgajIpLCAoajEsIGp1ZzIpLCAoajEsIDApLCAoMCwgajIpXQogICAgZmlsbCA9IG1pbihqdWcxIC0gajEsIGoyKQogICAgc3RhdGVzLmFwcGVuZCgoajEgKyBmaWxsLCBqMiAtIGZpbGwpKSAgIyBmaWxsIDEgZnJvbSAyCiAgICBmaWxsID0gbWluKGp1ZzIgLSBqMiwgajEpCiAgICBzdGF0ZXMuYXBwZW5kKChqMSAtIGZpbGwsIGoyICsgZmlsbCkpICAjIGZpbGwgMiBmcm9tIDEKICAgIHJldHVybiBbcyBmb3IgcyBpbiBzdGF0ZXMgaWYgcyAhPSBzdGF0ZV0KCgpkZWYgc29sdmUoanVnMSwganVnMiwgdGFyZ2V0KToKICAgIFEgPSBkZXF1ZShbKDAsIDApXSkgICMgQkZTCiAgICBwYXJlbnQgPSB7fQogICAgd2hpbGUgUToKICAgICAgICBzdGF0ZSA9IFEucG9wbGVmdCgpCiAgICAgICAgc3RhdGVzID0gbmV3X3N0YXRlcyhzdGF0ZSwganVnMSwganVnMikKICAgICAgICBmb3IgcyBpbiBzdGF0ZXM6CiAgICAgICAgICAgIGlmIHMgaW4gcGFyZW50OgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgcGFyZW50W3NdID0gc3RhdGUKICAgICAgICAgICAgaWYgdGFyZ2V0IGluIHMgb3IgdGFyZ2V0ID09IHN1bShzKToKICAgICAgICAgICAgICAgIHJldHVybiBzLCBwYXJlbnQKICAgICAgICAgICAgUS5hcHBlbmQocykKCgpkZWYgcGF0aChzdGF0ZSwgcGFyZW50cyk6CiAgICBwYXRoID0gW3N0YXRlXQogICAgd2hpbGUgVHJ1ZToKICAgICAgICBzdGF0ZSA9IHBhcmVudHNbc3RhdGVdCiAgICAgICAgcGF0aC5hcHBlbmQoc3RhdGUpCiAgICAgICAgaWYgc3RhdGUgPT0gKDAsIDApOgogICAgICAgICAgICBicmVhawogICAgcmV0dXJuIHBhdGhbOjotMV0KCgpkZWYgZGVzY3JpcHRpb24oc3RhdGVhLCBzdGF0ZWIpOgogICAgc2ExLCBzYTIgPSBzdGF0ZWEKICAgIHNiMSwgc2IyID0gc3RhdGViCiAgICBpZiBzYTEgPT0gc2IxOgogICAgICAgIHJldHVybiAiZmlsbCAyIGZyb20gdGFwIiBpZiBzYjIgZWxzZSAiZW1wdHkgMiIKICAgIGVsaWYgc2EyID09IHNiMjoKICAgICAgICByZXR1cm4gImZpbGwgMSBmcm9tIHRhcCIgaWYgc2IxIGVsc2UgImVtcHR5IDEiCiAgICBlbHNlOgogICAgICAgIHJldHVybiAiZmlsbCAxIGZyb20gMiIgaWYgc2ExIDwgc2IxIGVsc2UgImZpbGwgMiBmcm9tIDEiCgoKanVnMSwganVnMiA9IDEzLCAyMwp0YXJnZXQgPSA0CnNvbHV0aW9uID0gc29sdmUoanVnMSwganVnMiwgdGFyZ2V0KQpwcmludCgianVnMToge30gIGp1ZzI6IHt9ICAgICB0YXJnZXQ6IHt9Ii5mb3JtYXQoanVnMSwganVnMiwgdGFyZ2V0KSkKaWYgc29sdXRpb246CiAgICBzLCBwYXJlbnQgPSBzb2x1dGlvbgogICAgcGF0ID0gcGF0aChzLCBwYXJlbnQpCiAgICBmb3Igc3RlcCwgczEsIHMyIGluIHppcChjb3VudCgxKSwgcGF0LCBwYXRbMTpdKToKICAgICAgICBwcmludChzdGVwLCBzMiwgZGVzY3JpcHRpb24oczEsIHMyKSkKZWxzZToKICAgIHByaW50KCJObyBzb2x1dGlvbiIpCg==