{ 3 buckets, capacity 8, 5, 3 pints; 8 pints of water, to be halved See Robert Matthews, UK Sunday Telegraph, 1999-10-03 p.19 col 2 foot. If no command line characters, does default case [3 8 5 3 8 0 0 4 9] ; else command line is PailCount PailSizes PailStarts Target Seek-Depth. } program BUCKETS ; function Min(X, Y : word) : word ; begin if X0 then begin Writeln(' Param err @ #', K) ; HALT end ; GetP := G end {GetP} ; procedure GetParams ; var J : word ; begin Pails := GetP ; for J := One to Pails do Size[J] := GetP ; for J := One to Pails do Start[J] := GetP ; Target := GetP ; Depth := GetP ; end {GetParams} ; var List : TList ; procedure ReportSuccess(const Deep : word) ; var D, Pail : word ; begin Write(^M^J' Capacity :', '':20) ; for Pail := One to Pails do Write(Size[Pail]:3) ; Writeln ; Write( ' Start :', '':20) ; for Pail := One to Pails do Write(Start[Pail]:3) ; Writeln ; Writeln(' Move From To Amount New State') ; for D := 1 to Deep do with List[D] do begin Write(D:5, From:7, ' ->', Into:2, ',', Amt:5, ' -> ') ; for Pail := One to Pails do Write(State[Pail]:3) ; Writeln end ; Write(Deep:5, ' moves OK ') ; Readln end ; procedure Search(const Deep : word) ; var Src, Dst, Move, Pail, D, DP : word ; Loop : boolean ; begin if Deep0 then begin { Pour from ? } for Dst := One to Pails do if Dst<>Src then begin { Pour into ? } Move := Min(State[Src], Size[Dst]-State[Dst]) { Amount pourable } ; if Move=0 then CONTINUE ; if (Src=Into) and (Dst=From) then CONTINUE { Don't reverse } ; with List[DP] do begin State := List[Deep].State { Record for later } ; From := Src ; Amt := Move ; Into := Dst { Record for later } ; Dec(State[Src], Move) ; Inc(State[Dst], Move) ; { Actually pour } Loop := true ; for D := 0 to Deep do for Pail := One to Pails do if State[Pail]<>List[D].State[Pail] then Loop := false ; if Loop then CONTINUE { Skip if this state seen before } ; if (State[Src]<>Target) and (State[Dst]<>Target) then Search(DP) else ReportSuccess(DP) ; end {List[DP]} ; end {Dst} ; end {Src} ; end end {Search} ; {N.B. CONTINUE is a GoTo to just before the end of the current repetition } BEGIN ; Writeln('BUCKETS.PAS J R Stockton www.merlyn.dcu >= 1999-10-08') ; if ParamCount>0 then GetParams ; FillChar(List, SizeOf(List), 0) ; List[0].State := Start ; Search(0) ; Write(^M^J' Done. ') ; Readln ; END.