Question

How to write a function in scheme that sums the numbers in embedded lists?

i.e. ((1) (2 3) (4) (5 6))

I wrote this to sum the regular list:

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

but I'm not sure how to do the embedded one.

Was it helpful?

Solution

You have 3 cases:

(define (my-sum lst)
  (cond
    ; 1. the list is empty, so finish of by adding 0
    ([empty? lst]        0)
    ; 2. the first element is a list, so recurse down on the sublist, then do the rest
    ([list? (car lst)]   (+ (my-sum (car lst)) (my-sum (cdr lst))))
    ; 3. add the first element to the sum, then do the rest
    (else                (+ (car lst)          (my-sum (cdr lst))))))

so you were just missing the middle case.

This will work regardless of the nesting depth:

(my-sum '((1) (2 3) (4) (5 6)))
=> 21

(my-sum '((1) (2 3) (4) (5 6 (7 8 (9)))))
=> 45

Please note that you should not use the names "sum" and "list" in order not to shadow the build-in procedures.

OTHER TIPS

Here is the simplest answer.

(define (sum list-of-lists)
  (apply + (apply append list-of-lists)))

and the 'proof':

> (sum '((1) (2 3) (4) (5 6)))
21

In a more functional way

; this sums the elements of a not-embedded list
(define (sum-list* l)
  (foldl + 0 l))

; this sums the elements of an embedded list
(define (sum-embedded-list* el)
  (foldl + 0 (map sum-list* el)))

It covers the case of a list so formed: ((a1...an) (b1...bn)...), where ai and bj are atoms. Foldl and map are two important functions in scheme (and other languages). If you don't know how to use them you should learn. Take a look here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top