\insert 'Hailstone.oz' \insert 'Buffer.oz' declare %% The following is based on DGenerate from page 262 of CTM %% It puts its outputs on Xs proc {DDCount N Xs} case Xs of X|Xr then X=N {DDCount N+1 Xr} end end %% DDTake returns Limit items from Pairs, where it puts its demands fun {DDTake ?Pairs Limit} if 0 < Limit then P|Pr = Pairs in P | {DDTake Pr Limit-1} else nil end end %% Return a list of the numbers from 1 to NumberSought fun {UpTo NumberSought} NumbersIn NumbersOut OutStream in thread {DDCount 1 NumbersIn} end thread {Buffer 4 NumbersIn NumbersOut} end thread OutStream = {DDTake NumbersOut NumberSought} end OutStream end %% DDGraph puts demands on List and puts outputs on Pairs proc {DDGraph ?List Pairs F} case Pairs of P|Pr then Arg|Args = List in P=Arg#{F Arg} {DDGraph Args Pr F} end end %% DDPeaks puts demands on List and puts outputs on Pairs proc {DDPeaks ?List Pairs MaxSoFar} case Pairs of P|Pr then (Arg#Val)|Lr = List in if Val > MaxSoFar then P = (Arg#Val) {DDPeaks Lr Pr Val} else {DDPeaks Lr Pairs MaxSoFar} end end end fun {DDGraphMaxHailstone NumberSought} NumbersIn NumbersOut InStreamIn InStreamOut OutStream in thread {DDCount 1 NumbersIn} end thread {Buffer 4 NumbersIn NumbersOut} end thread {DDGraph NumbersOut InStreamIn MaxHailstone} end thread {Buffer 4 InStreamIn InStreamOut} end thread OutStream = {DDTake InStreamOut NumberSought} end OutStream end fun {DDGraphMaxPeaks NumberSought} NumbersIn NumbersOut InStreamIn InStreamOut PeakStreamIn PeakStreamOut OutStream in thread {DDCount 1 NumbersIn} end thread {Buffer 4 NumbersIn NumbersOut} end thread {DDGraph NumbersOut InStreamIn MaxHailstone} end thread {Buffer 4 InStreamIn InStreamOut} end thread {DDPeaks InStreamOut PeakStreamIn 0} end thread {Buffer 4 PeakStreamIn PeakStreamOut} end thread OutStream = {DDTake PeakStreamOut NumberSought} end OutStream end