% $Id: HailstoneBB.oz,v 1.2 2008/01/05 20:23:33 leavens Exp leavens $ \insert 'Hailstone.oz' \insert 'HailstoneMax.oz' \insert 'BufferDD.oz' declare %% The following is based on DGenerate from page 262 of CTM %% It puts its outputs on X|Xr proc {DDCount N X|Xr} X=N {DDCount N+1 Xr} 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 {BufferDD 4 NumbersIn NumbersOut} end thread OutStream = {DDTake NumbersOut NumberSought} end OutStream end %% DDGraph puts demands on List and puts outputs on P|Pr proc {DDGraph ?List P|Pr F} Arg|Args = List in P=Arg#{F Arg} {DDGraph Args Pr F} end %% DDPeaks puts demands on List and puts outputs on P|Pr proc {DDPeaks ?List P|Pr MaxSoFar} (Arg#Val)|Lr = List in if Val > MaxSoFar then P = (Arg#Val) {DDPeaks Lr Pr Val} else {DDPeaks Lr P|Pr MaxSoFar} end end fun {DDGraphHailstoneMax NumberSought} NumbersIn NumbersOut InStreamIn InStreamOut OutStream in thread {DDCount 1 NumbersIn} end thread {BufferDD 4 NumbersIn NumbersOut} end thread {DDGraph NumbersOut InStreamIn HailstoneMax} end thread {BufferDD 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 {BufferDD 4 NumbersIn NumbersOut} end thread {DDGraph NumbersOut InStreamIn HailstoneMax} end thread {BufferDD 4 InStreamIn InStreamOut} end thread {DDPeaks InStreamOut PeakStreamIn 0} end thread {BufferDD 4 PeakStreamIn PeakStreamOut} end thread OutStream = {DDTake PeakStreamOut NumberSought} end OutStream end