Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

cyclic values

 [1/11] from: rebol665::ifrance::com at: 29-Sep-2002 10:50


Hi List, I want to get values in order from a block, the first value coming again after the last, and this forever. Is there a better way than the one I am using now ? colors: [red green blue] ; I want color to be red, then green, then blue, then red again forever ; the first value is duplicated color: first colors append colors color ; then forever color: select colors color Patrick

 [2/11] from: anton:lexicon at: 29-Sep-2002 19:55


That's a bit unclear what you want. What do you want it for? If you have an increasing number n, then you can do this: colors: [red green blue] n: 1 loop 200 [ color: pick colors either n > length? colors [n][1] n: n + 1 ] Anton.

 [3/11] from: carl:cybercraft at: 29-Sep-2002 23:38


On 29-Sep-02, pat665 wrote:
> Hi List, > I want to get values in order from a block, the first value coming > again after the last, and this forever. Is there a better way than > the one I am using now ?
There may be, but it's pretty nice as it is. That said, if the colors block was very long it might give variable performance between finding color near the beginning and near the end of the block.
> colors: [red green blue] > ; I want color to be red, then green, then blue, then red again
<<quoted lines omitted: 3>>
> ; then forever > color: select colors color
-- Carl Read

 [4/11] from: gscottjones:mchsi at: 29-Sep-2002 7:09


From: "Patrick"
> I want to get values in order from a block, the first value > coming again after the last, and this forever. Is there a
<<quoted lines omitted: 6>>
> ; then forever > color: select colors color
Hi, Patrick, This is just a slight variation: colors: [red green blue] color: first colors loop 100 [ if not color: select colors color [color: first colors] print color ] Of course, 'forever is substituted in place of 'loop. --Scott Jones

 [5/11] from: ingo:2b1 at: 29-Sep-2002 15:18


Hi Patrick, Am Son, 2002-09-29 um 10.50 schrieb pat665: <...>
> colors: [red green blue] > ; I want color to be red, then green, then blue, then red again forever
<<quoted lines omitted: 3>>
> ; then forever > color: select colors color
That looks like a pretty clever use of select to me. My ideas would have been: for i 1 10 1 [ print colors/1 colors: next colors if tail? colors [colors: head colors] ] or i: 1 for j 1 10 1 [ print pick colors i i: i // (length? colors) + 1 ] But I like your version much more. Kind regards, Ingo

 [6/11] from: joel:neely:fedex at: 29-Sep-2002 7:52


Hi, Pat, Ingeneous!!! (...of course, with me, there's always a "but"... ;-) pat665 wrote:
> I want to get values in order from a block, the first value > coming again after the last, and this forever. Is there a
<<quoted lines omitted: 7>>
> ; then forever > color: select colors color
That's a nice compact way to accomplish your stated result, but under two constraints: 1) the number of values in the block is very small, and 2) the values are all distinct. SMALL NUMBER OF VALUES ---------------------- Given REBOL 1-origin indexing, the fastest/simplest way I've found for cycling an integer counter through the range of values 1..N is cnt: 0 ;; initialization cnt: cnt // N + 1 which means we could get your "forever" case above by using color: pick colors cnt: cnt // + 1 The alternative to using the modulus operator is explicit logic, as in color: pick colors counter: either counter < length? colors [counter + 1] [1] but that is very sub-optimal... In any case, the time complexity of modifying the integer index is O(1) -- constant -- while the time complexity of SELECT on an ordinary block is O(N) -- linear on the size of the block. A little quick benchmarking shows that this adds up very quickly. On my old slow benchmarking box (200 MHz Pentium, w95) the timings are (in microseconds) SELECT modulus EITHER... 3 elements 13.94 14.28 18.73 10 elements 16.76 14.72 19.33 (As you can see from the second column, there's still some statistical variability...) The above times were taken using function evaluations, so after removing that overhead, we get the following ratios: SELECT EITHER... vs vs modulus modulus 3 elements 0.97 1.41 10 elements 1.18 1.41 With only three elements, the SELECT approach saves 3% over the modulus approach, but the EITHER strategy costs 41% extra. But with ten elements, SELECT is now 18% slower than modulus, while EITHER is still 41% slower. CONCLUSION: The SELECT strategy doesn't scale well. DISTINCT VALUES --------------- Suppose you wanted to simulate a monitor which was cycling between the primary colors (e.g. using your original COLORS data), but went off in between each color (e.g. interspersed black displays). If we change our block to contain: colors: [red black green black blue black] color: first colors and then try color: select colors color We'll find that we're stuck in a green/black cycle, since the first occurrence of black is always the one that's found by SELECT. CONCLUSION: The SELECT strategy doesn't handle cases with values that occur more than once in the block. HOWEVER... With all of the above said, for small blocks with distinct values, your approach is quite elegant. Thanks for posting it! -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]

 [7/11] from: rebol665:ifrance at: 29-Sep-2002 18:14


Hi Joel Amazing! When will you write a full book about Rebol ? Great post! Thanks Patrick

 [8/11] from: tomc:darkwing:uoregon at: 29-Sep-2002 11:22


Hi Pat,
>> colors: [red green blue]
== [red green blue]
>> forever [append colors colors]
== [red green blue red green blue] == [red green blue red green blue red green blue red green blue] ... will get you to forever quickly ;) On Sun, 29 Sep 2002, pat665 wrote:

 [9/11] from: carl:cybercraft at: 30-Sep-2002 9:01


On 30-Sep-02, Tom Conlin wrote:
> Hi Pat, >>> colors: [red green blue]
<<quoted lines omitted: 4>>
> ... > will get you to forever quickly ;)
Indeed. But it suggests a way I haven't seen posted...
>> colors: [red green blue]
== [red green blue]
>> forever [print color: colors/1 remove append colors color]
red green blue red green blue red green blue red green blue red green blue red (escape) Has the advantage of no extra words being needed. The disadvantages being the contents of the colors block is cycling, (might or might not matter), and it may be slower than Joel's best effort. It should have a consistant speed though. Comments Joel? -- Carl Read

 [10/11] from: tomc:darkwing:uoregon at: 29-Sep-2002 15:17


hmmm! alonge the same line how about a _pseudo_ monty carlo method
>> forever[random/seed 13 print pick colors: random colors 1]
red green blue red green blue red green blue red green blue red green blue red (escape) On Mon, 30 Sep 2002, Carl Read wrote:

 [11/11] from: joel:neely:fedex at: 29-Sep-2002 21:26


Hi, Carl Carl Read wrote:
> > ... > Indeed. But it suggests a way I haven't seen posted...
<<quoted lines omitted: 22>>
> cycling, (might or might not matter), and it may be slower... > It should have a consistant speed though. Comments Joel?
Don't try this at home kids! ;-) Cycling the values within the block does matter; there's much more memory management overhead. Using the same benchmarks as in the earlier comparison, the block-cycling version takes 4 to 5 times as long as the modulus approach for 3-10 elements. In addition the overhead grows with the length of the block being cycled: bruteforce: func [n [integer!] c [integer!] /local t b v] [ b: make block! n repeat i n [insert tail b i] t: now/time/precise loop c [ remove append b v: b/1 ] t: to-decimal now/time/precise - t ] behaves as:
>> for i 10 200 10 [print [i bruteforce i 500000]]
10 24.99 20 22.91 30 29.49 40 25.27 50 23.45 60 27.19 70 25.76 80 29.22 90 25.98 100 29.6 110 26.75 120 30.05 130 27.24 140 28.89 150 29.83 160 30.71 170 30.97 180 31.2 190 33.18 200 32.9 The raggedness likely indicates intermittent gc operations; the trend is definitely upward as the block length grows. -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted