Duplicate every found element in a list in Scheme - list

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.

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)

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))

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.

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)

Related

Storing return values in Scheme

(define (odds lst)
(if (null? lst)
lst
(cons (car lst)
(if (or (null? lst)
(not (pair? (cdr lst))))
'()
(odds (cddr lst)))))
)
This function returns the odd-numbered elements; my issue is, I want to take the list it returns and reverse it (using the built in reverse function). I've been trying to use lambda to store it but the results don't change, also tried using set-cons! also, to no avail. The concept of using let in a recursive function seems to escape me. If someone could point me in the right direction it would be very much appreciated!
Pass the function's result to reverse in the place where you want the reversed list:
> (odds '(a b c d e))
'(a c e)
> (reverse (odds '(a b c d e)))
'(e c a)
> (let ((o (reverse (odds '(a b c d e))))) (append o o))
'(e c a e c a)
> (define (reverse-odds ls) (reverse (odds ls)))
> (reverse-odds '(5 6 a 9 "hi"))
'("hi" a 5)
Here is a snippet storing both the return and the result using let*
(define (odds lst)
(if(null? lst)
lst
(cons (car lst)
(if (or (null? lst)
(not(pair? (cdr lst))))
'()
(odds (cddr lst))))))
(define data (odds `(1 2 3 4 5 6 7 8 9) ) )
(let ((rev_odds ( reverse data )))
;do stuff with results
(display rev_odds)
)
You can skip worrying about a return value if you just cons directly onto the recursive result
(define (odds lst)
(if (null? lst)
null
(if (odd? (car lst))
(cons (car lst)
(odds (cdr lst)))
(odds (cdr lst)))))
(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)
One way to represent a "return" value is by adding a parameter to our recursive function. Below we use acc in our auxiliary helper function, loop. Usage of parameters like this is one common way to move the recursive call into tail position
(define (odds lst)
(define (loop acc lst)
(if (null? lst)
(reverse acc)
(if (odd? (car lst))
(loop (cons (car lst) acc)
(cdr lst))
(loop acc
(cdr lst)))))
(loop null lst))
(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)
Another way is to represent our return value is by way of a lambda, cont below. We simply call cont with the value we wish to return. The recursive call looks a little more complicated in this case as we have to construct a lambda that represents the new return value. The added benefit here is odds constructs the result in order; reverse is no longer necessary
(define (odds lst (cont identity))
(if (null? lst)
(cont null)
(if (odd? (car lst))
(odds (cdr lst) (lambda (acc)
(cont (cons (car lst) acc))))
(odds (cdr lst) cont))))
(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)

how to split a list recursively with using conditions in clisp

I am trying to learn clisp and I have started learning how to manipulate lists recursively. I am unsure wether it is my logic or if I am just too unfamiliar with the constructs of lisp, for some I am able to do it i.e. for procedure (separate '(a 1 b 2 c 3 d 4)) => ((1 2 3 4) (a b c d)) by doing
(defun separate (lst)
(if (endp lst)
'(nil nil)
(let ((x (separate (cdr lst))))
(if (numberp (car lst))
(list (cons (car lst)
(car x)))
(list (car x)
(cons (car lst) (cadr x)))))))
but when I do the same approach for another procedure
(greater-than-n '(9 1 8 2 7 3 6 4) 5)
I would expect to get a list : ((9 8 7 6) (1 2 3 4))
but instead I get: ((9 8 7 6))
My program thus far is:
(defun greater-than-n (lst n)
(if (endp lst)
'(() ())
(let ((x (greater-than-n (cdr lst) n)))
(if (> (car lst) n)
(list (cons (car lst)
(car x)))
(list (car x)
(cons (car lst)
(car x)))))))
I appreciate any help or comments.
Your bug is in the
(list (cons (car lst)
(car x)))
form: you are returning a list of 1 element.
PS. Your functions seem like a textbook case for using multiple values instead of a list of values.

Make a function in Scheme to substract two lists

I am quite new with Scheme and with StackOverflow as well!
So, for the first contact I would like to do something simple and easy in Scheme.
I want to define a function that substracts the elements of the introduced list.
For example, the inputs should be: (sub '(4 12 6) '(0 6 3))
And the output should be: (4 6 3)
Thanks!!
What you'll need is to have a base case where you check if either list is empty and evaluate it to the empty list or you make a pair with the calculation of the first element of each list and the recursion for the rest of both lists. Basically you end up with:
(cons (- 4 0) (cons (- 12 6) (cons (- 6 3) '()))) ; ==> (4 6 3)
As an example of a recursive list processing function here is one that negates all elements:
(define (negate-list lst)
(if (null? lst)
'()
(cons (- (car lst))
(negate-list (cdr lst)))))
(negate-list '(1 2 3 4)) ; ==> (-1 -2 -3 -4)
Now there are even more fancy ways to do this. Eg,. you can use tail recursion:
(define (negate-list lst)
(let loop ((lst lst) (acc '()))
(if (null? lst)
(reverse acc)
(loop (cdr lst)
(cons (- (car lst)) acc)))))
You can use map:
(define (negate-list lst)
(map - lst))
So there you go. you're half way there.

Scheme Inverse List Function

I defined a function called zip which took two lists as parameters and returned a list of pairs.
(define (zip list1 list2)
(if (null? list1)
'()
(cons (list (cons (car list1) (car list2)))
(zip (cdr list1) (cdr list2)))))
(zip (list 1 3 5) (list 2 4 6))
> (((1 . 2)) ((3 . 4)) ((5 . 6)))
Now I'm basically having trouble writing the inverse function of this. This is what I have so far. This function needs to output a list of two lists. I only attempted at making the first of the two lists to make it easier for myself but the output is not what I want.
(define (unzip u-list)
(if (null? u-list)
'()
(list (car (car (car u-list))) (unzip(cdr u-list)))))
(unzip (zip (list 1 3 5) (list 2 4 6)))
> (1 (3 (5 ())))
Any help would be appreciated...
I believe there's a problem with your implementation of zip, did you notice that you're returning a list of single-element lists of pairs? returning a list of pairs makes more sense:
(define (zip lst1 lst2)
(if (null? lst1)
'()
(cons (cons (car lst1) (car lst2))
(zip (cdr lst1) (cdr lst2)))))
Or even better, let's use the map higher-order function for a shorter, more idiomatic solution:
(define (zip lst1 lst2)
(map cons lst1 lst2))
Regarding unzip: it's easier if we split the problem in parts - let's get the first element of each pair, then the second element of each pair, and finally build a list with the answer. Try this:
(define (unzip lst)
(define (firsts lst)
(if (null? lst)
'()
(cons (caar lst)
(firsts (cdr lst)))))
(define (seconds lst)
(if (null? lst)
'()
(cons (cdar lst)
(seconds (cdr lst)))))
(list (firsts lst) (seconds lst)))
But once again, we're reinventing the wheel. Let's just use built-in functions to write a simpler answer:
(define (unzip lst)
(list (map car lst) (map cdr lst)))
Anyway, now unzip is the inverse of zip:
(zip '(1 3 5) '(2 4 6))
=> '((1 . 2) (3 . 4) (5 . 6))
(unzip '((1 . 2) (3 . 4) (5 . 6)))
=> '((1 3 5) (2 4 6))
As you make it with pairs it's somewhat more difficult but not much:
(define (zip-pair a b)
(map cons a b))
(define (unzip-pair zipped-pair)
(list (map car zipped-pair)
(map cdr zipped-pair)))
zip is usually implemented with apply and map and takes list and produce list of lists, like this:
(define (zip . lists)
(apply map list lists))
(zip '(1 2 3) '(a b c)) ; ==> ((1 a) (2 b) (3 c))
Though this will make lists and not pairs. However a unzip is almost the same except that you will take a list of lists instead of variable number of arguments:
(define (unzip1 zipped-list)
(apply map list zipped-list))
; or reuse zip
(define (unzip1 zipped-list)
(apply zip zipped-list))
(unzip1 '((1 a) (2 b) (3 c))) ; ==> ((1 2 3) (a b c))

Scheme - Splitting a list into two equal lists

Problem:
Write a function (split l) that takes a list and partitions it into two equal-sized (within one) lists, and returns a pair whose car is the first list and whose cdr is the second list.
My code:
(define split list)
(let ((half (/ (length list) 2)
(cons (car half list)
(cdr half list))))
Here's another possible implementation using the tortoise and hare algorithm:
(define (split lst)
(let loop ((tortoise lst) (hare lst) (acc '()))
(if (or (null? hare) (null? (cdr hare)))
(cons (reverse acc) tortoise)
(loop (cdr tortoise)
(cddr hare)
(cons (car tortoise) acc)))))
The above solution has the advantage of traversing the list only once, notice that we don't need to know the length of the list to make the split. It's called "tortoise and hare" because we keep two pointers over the list: one advances slowly, one element at a time (the "tortoise") and the other goes faster, two elements at a time (the "hare"). The algorithm stops when the hare reaches the end of the input list.
Alternatively, we can implement a more idiomatic (albeit slower) solution using built-in procedures. Assuming that the take and drop procedures are available in your interpreter (if not, import them from SRFI-1), this is closer to what you had in mind:
(define (split lst)
(let ((half (quotient (length lst) 2)))
(cons (take lst half)
(drop lst half))))
Either way, it works as expected:
(split '(1 2 3 4))
=> ((1 2) 3 4)
(split '(1 2 3 4 5))
=> ((1 2) 3 4 5)
Try:
(define (splitAt n lst)
(let loop ((acc '()) (n n) (lst lst))
(if (or (= n 0) (null? lst)) (cons (reverse acc) lst)
(loop (cons (car lst) acc) (- n 1) (cdr lst)))))
(define (split lst) (splitAt (quotient (length lst) 2) lst))
It works as follows:
(split '(1 2 3 4)) => ((1 2) 3 4)
(split '(1 2 3 4 5)) => ((1 2) 3 4 5)
Hope this helps.