schemeracketfoldalternating

Alternating Sum Using Foldr/Foldl (Racket)


Back again with another Racket question. New to higher order functions in general, so give me some leeway.

Currently trying to find the alternating sum using the foldr/foldl functions and not recursion.

e.g. (altsum '(1 3 5 7)) should equal 1 - 3 + 5 - 7, which totals to -4.

I've thought about a few possible ways to tackle this problem:

  1. Get the numbers to add in one list and the numbers to subtract in another list and fold them together.
  2. Somehow use the list length to determine whether to subtract or add.
  3. Maybe generate some sort of '(1 -1 1 -1) mask, multiply respectively, then fold add everything.

However, I have no clue where to start with foldl/foldr when every operation is not the same for every item in the list, so I'm having trouble implementing any of my ideas. Additionally, whenever I try to add more than 2 variables in my foldl's anonymous class, I have no idea what variables afterward refer to what variables in the anonymous class either.

Any help or pointers would be greatly appreciated.


Solution

  • We can leverage two higher-order procedures here: foldr for processing the list and build-list for generating a list of alternating operations to perform. Notice that foldr can accept more than one input list, in this case we take a list of numbers and a list of operations and iterate over them element-wise, accumulating the result:

    (define (altsum lst)
      (foldr (lambda (ele op acc) (op acc ele))
             0
             lst
             (build-list (length lst)
                         (lambda (i) (if (even? i) + -)))))
    

    It works as expected:

    (altsum '(1 3 5 7))
    => -4