Re: Missing in misc.e
- Posted by CChris <christian.cuvier at agric?lture?gouv.fr> Jul 20, 2007
- 703 views
Pete Lomax wrote: > > > OK, here's a single min() function that does the three things it ought to. > CChris may need medical assistance after seeing how many tests I just put in. > }}} <eucode> > constant GREATER = 1, > LESS = -1 > > sequence s -- non empty sequence to find min/max in. > object sfrom, sto -- as passed or 1 & length(s). > integer relation -- GREATER or LESS required from compare(). > integer return_idx -- if non-0 return idx, else return value. > > function min_or_max() > -- internal routine > object x > integer index > > x = s[sfrom] > index = sfrom > for i = sfrom+1 to sto do > if compare(s[i], x) = relation then > x = s[i] > index = i > end if > end for > if return_idx then > return index > end if > return x > end function > > constant MM_SEQ = #01, > MM_VAL = 0, > MM_IDX = #02 > > global constant MM_PAIR = 0, > MM_SEQVAL = MM_SEQ, > MM_SEQIDX = MM_SEQ+MM_IDX > > procedure Abort(sequence msg) puts(1,msg) ?9/0 end procedure > > global function min(object a, object b, object mode) > -- returns the minimum of a pair of values, or the minimum in a sequence. > -- mode must be one of: > -- MM_PAIR (=0) - return the minimum of two values passed in a & b > -- (if mode is not 0 then parameter b is unused and must be 0) > -- MM_SEQVAL - return the minimum value in sequence a > -- MM_SEQIDX - return the index of "" > -- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX, > -- and the second and third elements indicate the start and end points. > -- > -- examples: > -- ?min(3.5,5.5,0) -- prints 3.5 > -- ?min(13.5,5.5,0) -- prints 5.5 > -- ?max(13.5,5.5,0) -- prints 13.5 > -- ?max(3.5,5.5,0) -- prints 5.5 > -- ?min({1,3,5,7},0,MM_SEQVAL) -- prints 1 > -- ?min({1,3,5,7},0,{MM_SEQVAL,2,3}) -- prints 3 > -- ?max({1,3,5,7},0,{MM_SEQVAL,2,3}) -- prints 5 > -- ?max({1,3,5,7},0,MM_SEQVAL) -- prints 7 > -- ?min({1,3,5,7},0,MM_SEQIDX) -- prints 1 > -- ?min({1,3,5,7},0,{MM_SEQIDX,2,3}) -- prints 2 > -- ?max({1,3,5,7},0,{MM_SEQIDX,2,3}) -- prints 3 > -- ?max({1,3,5,7},0,MM_SEQIDX) -- prints 4 > > if equal(mode,MM_PAIR) then > if compare(a,b)<0 then return a end if return b > elsif not equal(b,0) then > Abort("parameter b must be 0 for mode MM_SEQ") > elsif compare(a,{})<1 then > Abort("parameter a must be sequence of length >=1 for mode MM_SEQ") > end if > if sequence(mode) then > if length(mode)!=3 then > Abort("third parameter to min() must be a sequence of length 3") > end if > sfrom = mode[2] > if not integer(sfrom) or sfrom<1 or sfrom>length(a) then > Abort("start point parameter out of bounds") > end if > sto = mode[3] > if not integer(sto) or sto<sfrom then > Abort("end point parameter out of bounds") > end if > mode = mode[1] > else > sfrom = 1 > sto = length(a) > end if > if not and_bits(mode,MM_SEQ) then > Abort("mode MM_SEQ expected") > end if > return_idx = and_bits(mode,MM_IDX) > relation = LESS > s = a > return min_or_max() > end function > > global function max(object a, object b, object mode) > -- returns the maximum of a pair of values, or the maximum in a sequence. > -- mode must be one of: > -- MM_PAIR (=0) - return the maximum of two values passed in a & b > -- (if mode is not 0 then parameter b is unused and must be 0) > -- MM_SEQVAL - return the maximum value in sequence a > -- MM_SEQIDX - return the index of "" > -- if mode is a sequence of length 3, the first must be MM_SEQVAL/IDX, > -- and the second and third elements indicate the start and end points. > -- > -- examples: > -- ?min(3.5,5.5,0) -- prints 3.5 > -- ?min(13.5,5.5,0) -- prints 5.5 > -- ?max(13.5,5.5,0) -- prints 13.5 > -- ?max(3.5,5.5,0) -- prints 5.5 > -- ?min({1,3,5,7},0,MM_SEQVAL) -- prints 1 > -- ?min({1,3,5,7},0,{MM_SEQVAL,2,3}) -- prints 3 > -- ?max({1,3,5,7},0,{MM_SEQVAL,2,3}) -- prints 5 > -- ?max({1,3,5,7},0,MM_SEQVAL) -- prints 7 > -- ?min({1,3,5,7},0,MM_SEQIDX) -- prints 1 > -- ?min({1,3,5,7},0,{MM_SEQIDX,2,3}) -- prints 2 > -- ?max({1,3,5,7},0,{MM_SEQIDX,2,3}) -- prints 3 > -- ?max({1,3,5,7},0,MM_SEQIDX) -- prints 4 > > if equal(mode,MM_PAIR) then > if compare(a,b)>0 then return a end if return b > elsif not equal(b,0) then > Abort("parameter b must be 0 for mode MM_SEQ") > elsif compare(a,{})<1 then > Abort("parameter a must be sequence of length >=1 for mode MM_SEQ") > end if > if sequence(mode) then > if length(mode)!=3 then > Abort("third parameter to max() must be a sequence of length 3") > end if > sfrom = mode[2] > if not integer(sfrom) or sfrom<1 or sfrom>length(a) then > Abort("start point parameter out of bounds") > end if > sto = mode[3] > if not integer(sto) or sto<sfrom then > Abort("end point parameter out of bounds") > end if > mode = mode[1] > else > sfrom = 1 > sto = length(a) > end if > if not and_bits(mode,MM_SEQ) then > Abort("mode MM_SEQ expected") > end if > return_idx = and_bits(mode,MM_IDX) > relation = GREATER > s = a > return min_or_max() > end function > </eucode> {{{ > > Regards, > Pete I don't know if you ever heard about the Shadoks, a "new look" (for the time) french cartoon of the late 60s. One of their great thoughts was "Why make it simple since we can make it more complicated?". CChris