*! 1.1.0 Jan 03, 1997 Jeroen Weesie/ICS STB-35 ip14 * -- added -sort- * -- added -format- * 1.0.0 Apr 96, Jeroen Weesie/ICS program define numlist version 5.0 * ------------------------------------------------------------------------ * parse off and check options * ------------------------------------------------------------------------ parse "`*'", p(",") local terms "`1'" if "`2'" != "" & "`2'" != "," { exit 198 } local options "Display MIn(str) MAx(str) Real Sort Format(str)" parse ",`3'" * type of numbers if "`real'" == "" { local nmbtype "integer" } else local nmbtype * restrictions on number of terms if "`min'" != "" { confirm integer number `min' } if "`max'" != "" { confirm integer number `max' } if "`min'" != "" & "`max'" != "" { if `min' > `max' { di in re "numlist: invalid (min, max)" exit 198 } } if "`format'" != "" { capture local f : display `format' 1 if _rc { di in re "invalid format `format'" exit 120 } } * ------------------------------------------------------------------------ * parse the terms * ------------------------------------------------------------------------ global nlist parse "`terms'", p(" ") while "`1'" != "" { local term `1' local inc local rng2 * term = number * = number-number * = number-number/number * split [term] in [term / inc] local pinc = index("`term'","/") if `pinc' > 0 { local inc = substr("`term'",`pinc'+1,.) confirm `nmbtype' number `inc' if `inc' == 0 { di in re "numlist: Increment is zero!" exit 198 } local term = substr("`term'", 1, `pinc'-1) } * check if range is specified * beware of trailing - local prng = index(substr("`term'",2,.),"-")+1 if `prng' > 1 { local rng1 = substr("`term'",1,`prng'-1) local rng2 = substr("`term'",`prng'+1,.) confirm `nmbtype' number `rng1' confirm `nmbtype' number `rng2' if "`inc'" == "" { local inc 1 } local nincr = 1 + /* */ int((float(`rng2')-float(`rng1')+1E-6) / float(`inc')) if `nincr' <= 0 { di in re "range n-m/incr should imply > 0 terms" exit 198 } * loop rng1-rng2/inc while `nincr' > 0 { if "`format'" != "" { local f : display `format' `rng1' local nlist "`nlist'`f' " } else { local nlist "`nlist'`rng1' " } local rng1 = `rng1' + `inc' local nincr = `nincr' - 1 } } else { * no increment expected at this point if "`inc'" != "" { di in re "numlist : invalid /" exit 198 } confirm `nmbtype' number `term' local nlist "`nlist'`term' " } mac shift } * ------------------------------------------------------------------------ * sort list in ascending order * ------------------------------------------------------------------------ if "`sort'" != "" { capture sortlist "`nlist'", a if _rc { di in re "error in sorting. Was -sortlist- installed?" exit 198 } local nlist "$S_1" } * ------------------------------------------------------------------------ * check min <= #terms <= max * ------------------------------------------------------------------------ local nnl : word count `nlist' if "`min'" != "" { if `nnl' < `min' { di in re "numlist: at least `min' values required, `nnl' specified" exit 198 } } if "`max'" != "" { if `nnl' > `max' { di in re "numlist: at most `max' values allowed, `nnl' specified" exit 198 } } if "`display'" != "" { di in gr "numlist: " in ye "`nlist'" } global S_1 "`nlist'" global S_2 "`nnl'" end program define sortlist version 5.0 if "`*'" == "" { global S_1 global S_2 exit } local key "`1'" /* list to be sorted */ local v "`2'" /* list to-be-permuted just like key */ if "`v'" == "," { local v mac shift 1 } else mac shift 2 local options "Ascending Descending DIsplay" parse "`*'" local k : word count `key' if "`v'" != "" { local nv : word count `v' if `nv' != `k' { exit 198 } * simulate array access local i 1 while `i' <= `k' { local v`i' : word `i' of `v' local key`i' : word `i' of `key' confirm number `key`i'' local i = `i'+1 } } else { * simulate array access with v = 1,2,3,4... local i 1 while `i' <= `k' { local key`i' : word `i' of `key' confirm number `key`i'' local v`i' `i' local v "`v'`v`i'' " local i = `i'+1 } } * insert-sort sorting order direct if "`descend'" != "" & "`ascendi'" == "" { local direct ">" } else local direct "<" local i 1 while `i' <= `k' { * search mj (index of maximum/minimum of key) among i..k local j `i' local mj `j' local mkey `key`j'' while `j' <= `k' { if `key`j'' `direct' `mkey' { local mj `j' local mkey `key`j'' } local j = `j'+1 } * swap i and mj if `i' != `mj' { local tmp `key`i'' local key`i' `key`mj'' local key`mj' `tmp' local tmp `v`i'' local v`i' `v`mj'' local v`mj' `tmp' } local i = `i'+1 } * re-assemble -key- into S_1 and -v- into S_2 global S_1 global S_2 local i 1 while `i' <= `k' { global S_1 "$S_1`key`i'' " global S_2 "$S_2`v`i'' " local i = `i'+1 } if "`display'" != "" { di in gr "keys " in ye "`key'" in gr " -> " in ye "$S_1" di in gr "values " in ye "`v'" in gr " -> " in ye "$S_2" } end exit