• Re: walk through list and add all n'th item

    From B. Pym@21:1/5 to B. Pym on Wed Aug 14 23:38:04 2024
    B. Pym wrote:

    Wow: loop macro rulez, somehow..
    just one correction:
    (loop for (a b c d) on (list 1 2 3 4 5 6 7 8) by #'cddddr
    sum a into a-sum
    sum b into b-sum
    sum c into c-sum
    sum d into d-sum
    finally (return (list a-sum b-sum c-sum d-sum)))
    Yeah, i might consider this code as beautiful
    olivier

    Gauche Scheme

    (use gauche.lazy)
    (use util.match)

    (define data (lrange 1 57))

    (match (lslices data 4)
    [((a b c d) ...)
    (map (cut fold + 0 <>)
    (list a b c d))])

    (378 392 406 420)


    newLISP

    (define data (sequence 1 56))

    (map (curry apply +) (transpose (explode data 4)))

    ===>
    (378 392 406 420)


    Another way.

    ;; Using "apply" for "reduce". The 3rd argument tells
    ;; apply how many items to process at a time.
    (apply
    (fn (sums) (map + sums $args))
    (cons '(0 0 0 0) data)
    5)

    --->
    (378 392 406 420)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to B. Pym on Fri Aug 30 17:02:59 2024
    On 2024-08-30, B. Pym <Nobody447095@here-nor-there.org> wrote:
    I'm just wondering if there is a lispier way to scan once through a
    list and add each n'th item with n+constant.
    Like kind of apply a list through a vector..
    In my approach i just used the loop macro:
    (defparameter vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))
    ...
    CL-USER> (sum-values vals)
    (4 8 12 16 20 24 28 32)

    Can you do better? (i hope you do and I am prepared to bear the shame)

    I see that you ask to "scan once" but still feel awfully
    tempted to reblock the data

    CL-USER> (defun batch (list size)
    (if (endp list)
    '()
    (cons (subseq list 0 size)
    (batch (nthcdr size list) size))))
    BATCH

    CL-USER> (batch vals 8)

    ((1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8))

    CL-USER> (defun add (list)
    (reduce (lambda(u v)(mapcar #'+ u v)) list))
    ADD

    CL-USER> (add (batch vals 8))
    (4 8 12 16 20 24 28 32)

    Mark Wooding wrote:

    Or you could just do it the easy way:

    (defun sum-every-softcore (period list)
    (loop with sums = (make-array period :initial-element 0)
    for item in list
    for i = 0 then (mod (1+ i) period)
    do (incf (aref sums i) item)
    finally (return (coerce sums 'list))))

    Gauche Scheme

    (use srfi-42) ;; do-ec

    (define (sum-every-nth n nlist)
    (rlet1 result (make-vector n 0)
    (do-ec (:list x (index i) nlist)
    (inc! (vector-ref result (mod i n)) x))))

    (define vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))

    (sum-every-nth 8 vals)

    #(4 8 12 16 20 24 28 32)

    This is the TXR Lisp interactive listener of TXR 296.
    Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
    TXR Lisp environments use genuine Saskatchewan sealskin bindings.
    (flow '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8)
    (tuples 8)
    transpose
    (mapcar sum))
    (4 8 12 16 20 24 28 32)

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Mark Wooding on Fri Aug 30 16:42:30 2024
    I'm just wondering if there is a lispier way to scan once through a
    list and add each n'th item with n+constant.
    Like kind of apply a list through a vector..
    In my approach i just used the loop macro:
    (defparameter vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))
    ...
    CL-USER> (sum-values vals)
    (4 8 12 16 20 24 28 32)

    Can you do better? (i hope you do and I am prepared to bear the shame)

    I see that you ask to "scan once" but still feel awfully
    tempted to reblock the data

    CL-USER> (defun batch (list size)
    (if (endp list)
    '()
    (cons (subseq list 0 size)
    (batch (nthcdr size list) size))))
    BATCH

    CL-USER> (batch vals 8)

    ((1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8))

    CL-USER> (defun add (list)
    (reduce (lambda(u v)(mapcar #'+ u v)) list))
    ADD

    CL-USER> (add (batch vals 8))
    (4 8 12 16 20 24 28 32)

    Mark Wooding wrote:

    Or you could just do it the easy way:

    (defun sum-every-softcore (period list)
    (loop with sums = (make-array period :initial-element 0)
    for item in list
    for i = 0 then (mod (1+ i) period)
    do (incf (aref sums i) item)
    finally (return (coerce sums 'list))))

    Gauche Scheme

    (use srfi-42) ;; do-ec

    (define (sum-every-nth n nlist)
    (rlet1 result (make-vector n 0)
    (do-ec (:list x (index i) nlist)
    (inc! (vector-ref result (mod i n)) x))))

    (define vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))

    (sum-every-nth 8 vals)

    #(4 8 12 16 20 24 28 32)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)