Re: Missing in misc.e
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
|
Not Categorized, Please Help
|
|