Search code examples
listschemefilteringsingly-linked-listfold

Scheme - sum the squares of even-valued elements in a list


I want to be able to sum the squares of the even elements in the list, however my current code only sums the elements, not the squares. Does anyone know of any modifications that can be made to make this to sum the squares of the even-valued elements in the list?

(define (sum elemList)
  (if
    (null? elemList)
    0
    (+ (car elemList) (sum (cdr elemList)))
  )
)

My input would be:

(sum-evens (list 1 2 3 4))

Output would be:

20

Which is (2*2) + (4*4).

If possible, it would be good to see both a recursive and iterative solution. Any ideas?


Solution

  • There are two possibilities, either we implement the recursion from scratch:

    (define (sum elemList)
      (cond ((null? elemList) 0)
            ((even? (car elemList))
             (+ (* (car elemList) (car elemList))
                (sum (cdr elemList))))
            (else (sum (cdr elemList)))))
    

    Or we use built-in procedures, defining helpers as needed. This strategy is known as using "sequences as conventional interfaces":

    (define (square x)
      (* x x))
    
    (define (sum elemList)
      (apply +
             (map square
                  (filter even? elemList))))
    

    In Scheme, the preferred way is the second one, because we must not reinvent the wheel when we have procedures that already do the job for us. Either way, it works as expected:

    (sum '(1 2 3 4 5 6 7 8 9 10))
    => 220