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

[REBOL] Re: REBOL Enhancement Proposals (REPs)

From: greggirwin:starband at: 27-Sep-2001 10:18

Hi Joel, I love a puzzle, plus I need more console time with REBOL, being a newbie. << Given a block of numbers, what's the simplest way in REBOL to write a smoothing operation that averages each interior value (i.e., all but the first and last) with the two values on either side of it? >> My first whack is a direct translation of what you posted: smooth-interior: func [blk /local i] [ for i 2 (length? blk) - 1 1 [ change at blk i divide ((pick blk i - 1) + (pick blk i) + (pick blk i + 1)) 3 ] ] The "pick" and "change at" stuff is more verbose than direct element access by index. To try and simplify things, I broke out a sub-function and tried using next and back: avg-fore-back: func [blk] [ divide ((first back blk) + (first blk) + (first next blk)) 3 ] smooth-interior: func [blk /local i] [ for i 2 (length? blk) - 1 1 [ change at blk i avg-fore-back at blk i ] ] Next I moved the change at bit to the sub-function to see how I liked that: avg-fore-back: func [blk] [ change blk divide ((first back blk) + (first blk) + (first next blk)) 3 ] smooth-interior: func [blk /local i] [ for i 2 (length? blk) - 1 1 [ avg-fore-back at blk i ] ] Finally, I added other generic functions to see what that did for me: sum: func [values[any-block!]] [ either tail? values [0][add (first values) (sum next values)] ] avg: func [values[any-block!]] [ divide (sum values) (length? values) ] smooth-interior: func [blk /local i] [ for i 2 (length? blk) - 1 1 [ change at blk i avg copy/part at blk (i - 1) 3 ] ] At first I didn't like this because the call to avg virtually disappears, becoming indistinct as a separate function. BUT, if I read it as a sentence as if it were pseudo-code it "reads" very clearly. I think the first version would be the most familiar for people coming from other mainstream languages, but I think I like the last one the best. I'll have to spend some more time with it to be sure. One other advantage to it, is that it's easy to extend for more than 3 point averaging. smooth-interior: func [blk width[integer!] /local i wd-offset] [ wd-offset: to-integer ((width - 1) / 2) ; TBD Ensure width is odd for i (1 + wd-offset) ((length? blk) - wd-offset) 1 [ change at blk i avg copy/part at blk (i - wd-offset) width ] return head blk ] I know flexibility wasn't part of your puzzle, and I'm not a numerical analyst, or number theory kinda' guy, so I don't know how valuable that is but common sense tells me it could be useful. Thanks for the prompt to learn a little more! --Gregg