CompNoob
CompNoob

Reputation: 57

Recursively adding to list returns null

I want to take a list of smaller lists and add a copy of the first element of each small list to the end of each small list. If that didn't make any sense, I'll give you an example:

f({(0, 0, 1), (1, 0, 0), (0, 1, 0), ...}) = {(0, 0, 1, 0), (1, 0, 0, 1), (0, 1, 0, 0), ...}

This is what I've got so far:

(define (add-end n set)
  (cond
    ((null? set) '())
    (cons (append (first set) (first (first set)))
          (add-end n (rest set)))))

This keeps giving me a null result, and I don't exactly know why.

Upvotes: 2

Views: 47

Answers (1)

Óscar López
Óscar López

Reputation: 235994

Your code fails because you forgot the else part in the cond expression, also the way you're appending a single element to the end of a list is incorrect. This should fix the problems:

(define (add-end set)
  (cond ((null? set)
         '())
        (else
         (cons (append (first set) (list (first (first set))))
               (add-end (rest set))))))

But wait, there's a simpler solution if we use existing procedures:

(define (add-end set)
  (map (lambda (lst)
         (append lst (list (first lst))))
       set))

Explanation:

  • We don't need an n parameter - for processing a list, we rarely have to know its length in advance
  • Notice that we have to process each element of the input list to create a new output list, using map is the way to go in these cases
  • Now it's a simple matter of appending the first element of each list
  • To build a proper list, remember that append requires that both of its arguments are lists, that explains the bit with the (list (first lst))

Either way, it works as expected:

(add-end '((0 0 1) (1 0 0) (0 1 0)))
=> '((0 0 1 0) (1 0 0 1) (0 1 0 0))

Upvotes: 1

Related Questions