# Decanting Problems and Dijkstra's Algorithm (II)

In the previous post, Decanting Problems and Dijkstra’s Algorithm, we presented some `scipy`

hackery to solve the *Die Hard* puzzle:

Two men have a full eight-gallon jug of wine, and also two empty jugs of five and three gallons capacity, respectively. Is it possible (within the restrictions of our problem) to divide the wine equally so each men can have four gallons of wine?

In this post we replicate the same technique, but this time using Julia’s `Graphs`

package. First of all, make sure you have the package installed. If this is not the case, issue in an `Ijulia`

session the command `Pkg.add("Graphs")`

. Once installed, the functions of the package can be readily called.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

using Graphs

states = filter(x->x[1]+x[2]+x[3]==8 &&

(x[1]==0 || x[1]==8 || x[2]==0 || x[2]==5 || x[3]==0 || x[3]==3) ,

[(a,b,c) for a in 0:8, b in 0:5, c in 0:3])

G = graph(states, [], is_directed=true)

for node1 in G.vertices

for node2 in G.vertices

total_change = ((node1[1]-node2[1]), node1[2]-node2[2], node1[3]-node2[3])

# Check 1: one of the jugs is not affected

check1 = (total_change[1]*total_change[2]*total_change[3]==0)

# Check 2: one of the jugs gets full

check2 = (node2[1]==8 && total_change[1]!=0) ||

(node2[2]==5 && total_change[2]!=0) ||

(node2[3]==3 && total_change[3]!=0)

# Check 3: one of the jugs gets empty

check3 = (node2[1]==0 && total_change[1]!=0) ||

(node2[2]==0 && total_change[2]!=0) ||

(node2[3]==0 && total_change[3]!=0)

is_adjacent = check1 && (check2 || check3)

if is_adjacent

add_edge!(G, node1, node2)

end

end

end

We are ready to fire Dijkstra’s algorithm on this graph now.

1

2

3

4

5

6

7

8

9

10

11

r = dijkstra_shortest_paths(G, ones(Int64,num_edges(G)), (8,0,0))

source = (4,4,0)

source_index = findfirst(G.vertices, (4,4,0))

while source!=(8,0,0)

print(source)

source = r.parents[source_index]

source_index = r.parent_indices[source_index]

end

print(sourc)

As in the previous solution, we found that the simplest way to divide the wine equally is in 7 steps as follows:

- Pour 5 gallons of wine into the second jug. \( (3,5,0) \)
- Pour 3 gallons from the second jug to the third. \( (3,2,3) \)
- Pour 3 gallons from the third to the first. \( (6,2,0) \)
- Pour all 2 gallons from the second to the third jug. \( (6,0,2) \)
- Pour five gallons from the first to the second jug. \( (1,5,2) \)
- Pour one gallon from the second to the third jug. \( (1,4,3) \)
- We are technically done, but we may pour now all three gallons from the third jug to the first, for a convenient transportation of the wine. \( (4,4,0) \)