Mailing List Archive: 49091 messages

[REBOL] cycling

From: joel:neely:fedex at: 5-Jul-2001 12:58

Given a set of M "index" values, what's the simplest way to cycle through them, both forward and backward? In the two commonest cases, the M values might occupy either the range 0 thru M - 1 or the range 1 thru M. Let N0F, N0B, N1F, and N1B hold the current counters for all combinations of ranges and directions. ------ range of ------ direction 0 .. m - 1 1 .. m --------- ---------- -------- forward n0f n1f backward n0b n1b The simplest possibilities I've found for putting these variables through their paces are: Pure Arithmetic: n0f: (n0f + 1) // m n0b: (n0b + m - 1) // m n1f: (n1f // m) + 1 n1b: (n1b + m - 2) // m + 1 Expressional: n0f: either m - 1 = n0f  [n0f + 1] n0b: either 0 = n0b [m - 1] [n0b - 1] n1f: either m = n1f  [n1f + 1] n1b: either 1 = n1b [m] [n1b - 1] Imperative: n0f: n0f + 1 if n0f = m [n0f: 0] if n0b = 0 [n0b: m] n0b: n0b - 1 n1f: n1f + 1 if n1f > m [n1f: 1] n1b: n1b - 1 if n1b = 0 [n1b: m] For example, using the pure arithmetic version:
>> n0f: n0b: n1f: n1b: 1
== 1
>> m: 5
== 5
>> loop 15 [
[ print [n0f n0b n1f n1b] [ set [n0f n0b n1f n1b] reduce [ [ (n0f + 1) // m (n0b + m - 1) // m [ (n1f // m) + 1 (n1b + m - 2) // m + 1 [ ] [ ] 1 1 1 1 2 0 2 5 3 4 3 4 4 3 4 3 0 2 5 2 1 1 1 1 2 0 2 5 3 4 3 4 4 3 4 3 0 2 5 2 1 1 1 1 2 0 2 5 3 4 3 4 4 3 4 3 0 2 5 2 = [1 1 1 1] A comparison of these options, along with relative timings based on a 3,000,000 cycle benchmark, includes the following observations: Option Time Pro Con --------------- ---- ---------------- ------------------ Pure Arithmetic 1.00 * Fastest * Least obvious to * Most compact casual reader Expressional 1.31 * Most obvious * Slowest Imperative 1.15 * Somewhat obvious * Can't be used as subexpressions Other observations or alternative calculations are welcomed. -jn- -- ------------------------------------------------------------ Programming languages: compact, powerful, simple ... Pick any two! joel'dot'neely'at'fedex'dot'com