[racket] Looping with look-behind and look-forward
You could consider using vectors.
#lang racket
(define (running-average-of-3-vector-edition xs)
(define n (vector-length xs))
(define (prev i) (vector-ref xs (- i 1)))
(define (next i) (vector-ref xs (+ i 1)))
(for ([(x i) (in-indexed xs)]
#:when (< 0 i (- n 1)))
(displayln (/ (+ (prev i) x (next i)) 3))))
(running-average-of-3-vector-edition #(1 2 3 4 5 6))
/Jens Axel
2012/5/27 Harry Spier <vasishtha.spier at gmail.com>:
> This is just a simple example to work on the form. In my application
> I'm not processing integers, I'm processing a list of sub-lists. Each
> sublist is of the form (number (s . e ) ...)
>
> On Sun, May 27, 2012 at 12:16 PM, Richard Cleis <rcleis at me.com> wrote:
>> If you are only using integers, efficiency matters, and your running averages are larger than two (I can't tell of you are using three for a simple example, or if that is the only requirement), then it might be better to maintain the latest sum by subtracting the oldest member and adding the newest. If the processing time for the arithmetic is much smaller than the overhead of list maintenance, then this post isn't very useful.
>>
>> rac
>>
>>
>> On May 27, 2012, at 9:54 AM, Harry Spier wrote:
>>
>>> Sorry Jens, I see I've just recreated the form you originally suggested.
>>> Thanks, Harry
>>>
>>> On Sun, May 27, 2012 at 11:46 AM, Harry Spier <vasishtha.spier at gmail.com> wrote:
>>>> I think I've come up with a simpler form to do this.
>>>>
>>>> (define (running-average-of-3 l)
>>>> (for
>>>> ( [prior (in-list l)]
>>>> [x (in-list (rest l))]
>>>> [next (in-list (rest (rest l)))])
>>>> (displayln (/ (+ x prior next) 3))))
>>>>
>>>> (running-average-of-3 '(1 2 3 4 5 6))
>>>>
>>>>
>>>> So I can do something like:
>>>>
>>>> (define (f1 l)
>>>> (for/fold ([result-list '()])
>>>> ( [prior (in-list (append '() l))]
>>>> [x (in-list l)]
>>>> [next (in-list (append (rest l) '()))])
>>>> ...
>>>> ... make new-result-element using x prior and next...
>>>> (cons new-result-element result-list))
>>>> (reverse result-list))
>>>>
>>>> The list I'm working on in my application has about 40,000 sub-lists.
>>>> Will the compiler build new lists from scratch as the sequence for
>>>> prior and next in this code or will it use pointers to and from the
>>>> existing list l to do this?
>>>>
>>>> Thanks,
>>>> Harry
>>>>
>>>> On Sun, May 27, 2012 at 10:38 AM, Jens Axel Søgaard
>>>> <jensaxel at soegaard.net> wrote:
>>>>> 2012/5/27 Harry Spier <vasishtha.spier at gmail.com>:
>>>>>> Is the "for" form a macro? And if so how difficult would it be to
>>>>>> make a new form "for-with-look-around" that had built in look-back and
>>>>>> look-ahead operators (next x) (prior x) ( next?) (prior?).
>>>>>>
>>>>>> So you could do something like:
>>>>>>
>>>>>> ((define (running-average-of-3 l)
>>>>>> (for-with-look-around
>>>>>> ([x (in-list l)])
>>>>>> (unless? (or (prior?) (next?))
>>>>>> (displayln (/ (+ x (prior x) (next x)) 3))))))
>>>>>>
>>>>>> From a functional programming perspective is building a form like this
>>>>>> a bad idea?
>>>>>
>>>>> It is a fine idea.
>>>>> Here is variation on the idea.
>>>>>
>>>>> (define (in-triples l)
>>>>> (define (sublists xs)
>>>>> (if (empty? xs)
>>>>> '()
>>>>> (cons xs (sublists (rest xs)))))
>>>>> (define (triple xs) (take xs 3))
>>>>> (sequence-map triple (drop-right (sublists l) 2)))
>>>>>
>>>>> (define (running-average-of-3 l)
>>>>> (for ([t (in-triples l)])
>>>>> (match-define (list x y z) t)
>>>>> (displayln (/ (+ x y z) 3))))
>>>>>
>>>>> (running-average-of-3 '(1 2 3 4 5 6))
>>>
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/users
>>
--
--
Jens Axel Søgaard