Master James
Master James

Reputation: 338

Duplicate every found element in a list in Scheme

I want to duplicate every found element in a list. I have the idea but i can't make it right. Sample input is >(pass '(1 2 3 4 4)) will have the output (1 1 2 2 3 3 4 4 4 4). Anyone out there help me. Here is my code ..

  (define duplicate
   (lambda (mylist n)
    (cond ((null? mylist) "Not found")
      ((< n 2) (cons (car mylist)
        (duplicate mylist (+ n 1))))
          (else 
             (duplicate (cdr mylist) 0)))))
  (define pass
     (lambda (mylist)
       (duplicate list 0)))

I will appreaciate all valuable comments.

Upvotes: 1

Views: 4857

Answers (4)

CambodianCoder
CambodianCoder

Reputation: 487

Try using map and list

(define (duplicate my-list)
  (flatten
    (map 
      (lambda (x) 
      (list x x))
    my-list)))`

Gives requested format:

> (duplicate (list 1 2 3 4 4))
 '(1 1 2 2 3 3 4 4 4 4)

Upvotes: 0

alinsoar
alinsoar

Reputation: 15783

I would do it so:

(define (dup l)
  (define (iter l co)
    (if (null? l)
        (co '())
        (iter (cdr l)
              (lambda (x)
                (co (cons (car l) (cons (car l) x)))))))
  (iter l (lambda (x) x)))

(dup '(1 2 3))

Upvotes: 1

ben rudgers
ben rudgers

Reputation: 3669

It may be simpler to treat duplicate as zipping a list with itself. Then flattening the resulting list.

In Scheme or Racket:

(require srfi/1)

(define (duplicate-list-members lox)
  (flatten (zip lox lox)))

Though it runs in O(n) time, profiling may indicate that passing through the list twice is a bottleneck and justify rewriting the function. Or it might not.

Upvotes: 0

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 235984

Just a couple of fixes (see the comments) and we're good to go:

(define duplicate
  (lambda (mylist n)
    (cond ((null? mylist) '()) ; base case must return the empty list
          ((< n 2) (cons (car mylist)
                         (duplicate mylist (+ n 1))))
          (else 
           (duplicate (cdr mylist) 0)))))

(define pass
  (lambda (mylist)
    (duplicate mylist 0)))     ; pass myList, not list

Notice that the procedure can be simplified a bit:

(define (pass lst)
  (if (null? lst)
      '()
      (cons (car lst)
            (cons (car lst)
                  (pass (cdr lst))))))

Or even better, using higher-order procedures for a more idiomatic solution:

(define (pass lst)
  (foldr (lambda (ele acc) (list* ele ele acc))
         '()
         lst))

Yet another alternative:

(define (pass lst)
  (append-map (lambda (ele) (list ele ele))
              lst))

Anyway, it works as expected:

(pass '(1 2 3 4 4))
=> (1 1 2 2 3 3 4 4 4 4)

Upvotes: 2

Related Questions