One more method without graphs is by using IntegerPartition.
Method in brief
For this particular problem there are 7 trips from start to end and let $t_1$ to $t_7$ represent those time. All $t_i \in \{1,3,6,8,12\}$.
Let $t_f$ be the total time. Then $t_f$ must partitions into 7 integers all of which belong to $\{1,3,6,8,12\}$.
If $t_f$ happens to be 30 then the result of
IntegerPartitions[30, {7}, {1, 3, 6, 8, 12}]
including all its Permutations will contain the time of the successful journey.
So the idea is to go over all permutations of these time and select only the ones which can fit the initial condition.
Mathematica Part
split2Bytime[list_, time_] :=
Module[{p1, p2, p3, p4, flag = 1, trip, pos, onwardPart, returnPart},
onwardPart = list[[3]];
returnPart = Last@list;
Which[Not@MemberQ[onwardPart, First@time], flag = 0, True,
Which[First@time == First@onwardPart, flag = 0, True,
pos = Flatten@Position[onwardPart, First@time];
p2 = onwardPart[[First@pos - 1 ;; First@pos]];
p3 = Reverse@TakeDrop[onwardPart, {First@pos - 1, First@pos}];
p4 = PadRight[Last@p3, Length[Last@p3] + Length@returnPart, returnPart];
trip[1] = Join[{First@p3}, {p4}];
Which[Not@DuplicateFreeQ[time],
p3 = Reverse@TakeDrop[onwardPart, {First@pos - 1}];
p4 = PadRight[Last@p3, Length[Last@p3] + Length@returnPart,returnPart];
trip[2] = Join[{First@p3}, {p4}];, True,
Which[Not@MemberQ[Last@trip[1], Last@time], flag = 0, True,
p3 = Insert[First@trip[1], Last@time, 1];
p4 = DeleteCases[Last@trip[1], Last@time];
trip[2] = Join[{p3, p4}];]]
];
];
If[flag == 1, Flatten[Array[trip, 2], 1], "failed"]
];
The function split2Bytime takes the initial list and two time values and throws the allowed configuration based on that time.
For e.g.
split2Bytime[{{}, {}, {1, 3, 6, 8, 12}, {}}, {2, 3}]
(*failed*)
will return failed because the time argument i.e. {2,3} represents the time taken for the first and second trip. But the first trip cannot take 2 units with
{{}, {}, {1, 3, 6, 8, 12}, {}} as the initial conflagration.
split2Bytime[{{}, {}, {1, 3, 6, 8, 12}, {}}, {3, 3}]
(*{{6, 8, 12}, {1, 3}, {3, 6, 8, 12}, {1}}*)
The above e.g. works because {3,3} is possible. The result is displayed as four sub-list where the first two part i.e. {6, 8, 12}, {1, 3} means {1,3} goes to the other side taking 3 seconds and the last two parts {3, 6, 8, 12}, {1} means that {3} comes back taking 3 seconds again.
splitAll[timings_] :=
Module[{flag = 1, last, trip, nlist = {{}, {}, {1, 3, 6, 8, 12}, {}}},
trip[1] = split2Bytime[nlist, timings[[1 ;; 2]]] // Quiet;
trip[2] = split2Bytime[trip[1], timings[[3 ;; 4]]] // Quiet;
trip[3] = split2Bytime[trip[2], timings[[5 ;; 6]]] // Quiet;
last = trip[3][[3]];
If[Not[Max@last == Last@timings] ||
Not[MemberQ[last, Last@timings]], flag = 0];
If[flag == 1, Array[trip, 3], "failed"]]
splitAll applies split2Bytime to all the timings 2 at a time and clubs them together at the end.
Now we can check for any total time $t_f$ whose integer partitions plus all its permutations satisfies splitAll.
check[n_] :=
Module[{sol, perms},
sol = IntegerPartitions[n, {7}, {1, 3, 6, 8, 12}];
perms =
Partition[
Flatten[Table[Permutations[sol[[i]]], {i, 1, Length[sol]}]], 7];
DeleteCases[
Table[If[
Not[ContainsAny[{splitAll[perms[[i]]]}, {"failed"}] ||
ContainsAny[splitAll[perms[[i]]], {"failed"}]], Sow[i]] //
Quiet, {i, 1, Length[perms]}], Null]]
check checks for all those Permutations which results in a failure. We can use it to see which ones are working. Lets check from 20 to 30
DeleteCases[Table[If[Not[check[n] == {}], Sow[n]], {n, 20, 30}], Null]
(*29*)
We get the correct total time $t_f=29$.
Now that we now $t_f=29$ we can display the full result of splitAll.
showResult[n_] :=
Module[{sol, result, perms, res, start = {{1, 3, 6, 8, 12}, {}}},
sol = IntegerPartitions[n, {7}, {1, 3, 6, 8, 12}];
perms =
Partition[
Flatten[Table[Permutations[sol[[i]]], {i, 1, Length[sol]}]], 7];
res = DeleteCases[
Table[If[
Not[ContainsAny[{splitAll[perms[[i]]]}, {"failed"}] ||
ContainsAny[splitAll[perms[[i]]], {"failed"}]], Sow[i]] //
Quiet, {i, 1, Length[perms]}], Null];
result[i_] :=
Partition[
Flatten[Append[Prepend[splitAll[perms[[res[[i]]]]], start],
Reverse@start], 1], 2];
Row[Table[Grid[result[i], Frame -> All], {i, 1, Length[res]}], " "]
]

MathematicaandMathematical– yode Mar 28 '16 at 12:02Mathematicato implement it. – yode Mar 28 '16 at 13:59mmabyGraph. – yode Mar 29 '16 at 04:04