Reputation: 45
My question is how can i print the elements of a list two times, the code i have tried is given below
(define duplicate-list
(lambda (mylist n)
(cond ((null? mylist) '())
((< n 2) (cons (car mylist)
(duplicate-list mylist (+ n 1))))
(else
(duplicate-list (cdr mylist) 0)))))
(define duplicate
(lambda (mylist)
(duplicate-list mylist 0)))
The problem in this code is that, it works fine only when i give it a list as input, this fails to work when i give it an input of a nested list.
>(duplicate '(a 1 b 2 c 3 r x)) -> a a 1 1 b b 2 2 c c 3 3 r r x x
>(duplicate '( (a 1) b ((c)) 2)) ->((a 1) (a 1) b b ((c)) ((c)) 2 2)
Whereas, the expected outcome needed should be
(duplicate '( (a 1) b ((c)) 2 z 3) = ( (a a 1 1) b b ((c c)) 2 2 z z 3 3)
Upvotes: 1
Views: 1165
Reputation: 135197
Here's another solution using pattern matching via match
-
(define (duplicate l)
(match l
((list (list a ...) b ...) ; nested list
(cons (duplicate a)
(duplicate b)))
((list a b ...) ; flat list
(cons a
(cons a
(duplicate b))))
(_ ; otherwise
null)))
It works as expected -
(duplicate '((a 1) b ((c)) 2 z 3))
; '((a a 1 1) b b ((c c)) 2 2 z z 3 3)
(duplicate '())
; '()
Upvotes: 0
Reputation: 235984
You're using the wrong approach to build the output list, you have to recur over the car
and cdr
parts, given that this is a list of lists. Try this:
(define (duplicate lst)
(cond ((null? lst)
'())
((not (pair? (car lst)))
(cons (car lst)
(cons (car lst) ; here we duplicate each element
(duplicate (cdr lst)))))
(else
(cons (duplicate (car lst))
(duplicate (cdr lst))))))
It works as expected:
(duplicate '((a 1) b ((c)) 2 z 3))
=> '((a a 1 1) b b ((c c)) 2 2 z z 3 3)
Upvotes: 2