Two List Tasks

January 2, 2018

We have today two simple exercises on lists:

  1. Given a list of lists of integers, all the same length, return a list of the sums of the lists. For instance, given the list ((1 2 3 4) (2 3 4 5) (3 4 5 6)), return the list ((+ 1 2 3) (+ 2 3 4) (+ 3 4 5) (+ 4 5 6)), which is (6 9 12 15).
  2. Given a list of integers of length n = k × m, return a list of k items, each containing the sum of the next m integers from the original list. For instance, given the list, (1 2 3 4 2 3 4 5 3 4 5 6) and sub-list length m = 4, return the list (10 14 18).

Your task is to write programs that perform the two tasks. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Advertisements

Pages: 1 2

6 Responses to “Two List Tasks”

  1. Rutger said
    #exercise 1:
    lol = [[1,2],[3,5,4],[-1]]
    print(list(map(sum, lol)))
    
    #exercise 2:
    l = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
    print(list(map(sum, (zip(*[iter(l)]*5)))))
    
  2. chaw said

    The answer to the first exercise could be simplified (in the eye of
    this beholder) to:

    (apply map + xss)

  3. chaw said

    Another solution for the second exercise, using just R7RS Scheme.

    (define input-201 '(1 2 3 4 2 3 4 5 3 4 5 6))
    
    ;; Any trailing under-length segment is dropped.
    (define (segment-sum lst segment-length)
      (let f ((lst lst)
              (seg-len 0)
              (seg-sum 0)
              (res '()))
        (if (null? lst)
            (reverse res)
            (let ((slen (+ seg-len 1))
                  (ssum (+ seg-sum (car lst))))
              (if (< slen segment-length)
                  (f (cdr lst) slen ssum res)
                  (f (cdr lst) 0 0 (cons ssum res)))))))
    
    (write (segment-sum input-201 4))
    (newline)
    
    
  4. Globules said

    A Haskell version.

    import Data.List.Split (chunksOf)
    
    listOfSums :: Num a => [[a]] -> [a]
    listOfSums = map sum
    
    chunkSums :: Num a => Int -> [a] -> [a]
    chunkSums n = listOfSums . chunksOf n
    
    main :: IO ()
    main = do
      print $ listOfSums [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
      print $ chunkSums 4 [1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6]
    
    $ ./twolisttasks 
    [6,9,12,15]
    [10,14,18]
    
  5. Daniel said

    Here’s a solution in C.

    /* list_tasks.c */
    
    #include <stdio.h>
    
    void sum_arrays(int* arrays[],
                    size_t k,
                    size_t m,
                    int* output) {
      for (size_t i = 0; i < m; ++i) {
        output[i] = 0;
        for (size_t j = 0; j < k; ++j) {
          output[i] += arrays[j][i];
        }
      }
    }
    
    void sum_array(int* array,
                   size_t k,
                   size_t m,
                   int* output) {
      for (size_t i = 0; i < k; ++i) {
        output[i] = 0;
        for (size_t j = 0; j < m; ++j) {
          output[i] += array[i*m + j];
        }
      }
    }
    
    void print_array(int* array, int n) {
      printf("[");
      for (size_t i = 0; i < n; ++i) {
        if (i > 0) printf(", ");
        printf("%d", array[i]);
      }
      printf("]");
    }
    
    int main(int argc, char* argv[]) {
      /* Task 1 */
      {
        size_t k = 3;
        size_t m = 4;
        int array[] = {
          1, 2, 3, 4,
          2, 3, 4, 5,
          3, 4, 5, 6
        };
        int* arrays[3];
        for (size_t i = 0; i < k; ++i) {
          arrays[i] = &array[i*m];
        }
        int output[m];
        sum_arrays(arrays, k, m, output);
        printf("Task 1:\n  ");
        print_array(output, m);
        printf("\n");
      }
    
      /* Task 2 */
      {
        size_t k = 3;
        size_t m = 4;
        int array[] = {1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6};
        int output[k];
        sum_array(array, k, m, output);
        printf("Task 2:\n  ");
        print_array(output, k);
        printf("\n");
      }
    
      return 0;
    }
    

    Output:

    Task 1:
      [6, 9, 12, 15]
    Task 2:
      [10, 14, 18]
    
  6. Daniel said

    @Rutger, your solution to the first task sums elements within the sublists, as opposed to summing corresponding elements across the sublists.

    Here’s a minor update that zips the lists so that the sum is across sublists.

    # Python 3
    lol = [[1,2,3,4],[2,3,4,5],[3,4,5,6]]
    print(list(map(sum, zip(*lol))))
    
    [6, 9, 12, 15]
    

    Here’s the updated version that also supports sublists of differing lengths, padding the shorter sublists with zeros at the end.

    # Python 3
    from itertools import zip_longest
    lol = [[1,2],[3,5,4],[-1]]
    print(list(map(sum, zip_longest(*lol, fillvalue=0))))
    
    [3, 7, 4]
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: