Home > Enterprise >  Sum a list of lists in Racket
Sum a list of lists in Racket

Time:08-17

What is an elegant or idiomatic way to get the sum of a list of lists in Racket? (I am new to Racket).

Here's what I put together but it requires two functions, ideally it would only need one:

(define (count-reps-per-round lst)
  #| a partial solution with recursion, 
  only adds the subtotal
  of each list and returns a new list
  |#
  (cond
    [(empty? lst) empty]
    [else (cons (apply   (first lst))
          (count-reps-per-round (rest lst)))]))


(define (reps-per-workout lst)  ; would be nice to combine with above into one function
  (apply   (count-reps-per-round lst)))

(define results `(
                  (28 25 34 18)
                  (22 21 30 20)
                  (19 16 24 16)
                  (18 17 20 19)))

(display(count-reps-per-round results))  ; (105 93 75 74)
(= (reps-per-workout results) 347)  ; #t

I would also be interested in any solution that doesn't require nested lists.

CodePudding user response:

Not sure this is "idiomatic" or that it's the most efficient implementation -- but seems like a simple solution:

(define (nested-sum lst)
   (cond
      [(empty? lst) 0 ]
      [(list? lst) (  (nested-sum (first lst)) (nested-sum (rest lst)))]
      [else lst]))
   
(writeln (nested-sum `((1 2 3) (4 5 6))))   ; 21
(writeln (nested-sum 10))   ; 10
(writeln (nested-sum `()))  ; 0
 
 ; and even deeply nested:
(writeln (nested-sum `((1 2 3) (4 5 6) ((10 20)))))   ; 51

CodePudding user response:

There's nothing wrong with splitting a complex problem in multiple helper functions, in fact this is encouraged when doing functional programming. But also we're encouraged to reuse built-in procedures whenever possible, for example we can write the solution to your problem in a single line by carefully combining map and apply:

(define (reps-per-workout lst)
  (apply   (map (lambda (l) (apply   l)) lst)))

It works as expected:

(define results
  '((28 25 34 18)
    (22 21 30 20)
    (19 16 24 16)
    (18 17 20 19)))

(reps-per-workout results)
=> 347
  • Related