How do I write every element in a list twice such that:
(double '(a((b)(c d)(((e)))))) --> '(a a((b b)(c c d d)(((e e)))))
I currently have this so far but it's not quite right.
(define double
(lambda (x)
(cond ((null? x) '())
((list? x)(append (double (car x)) (double cdr x)))
(else (cons x (cons x '()))))))
You were close to the answer, the key point is that we have to double the elements when the car of the list is an atom, not when the list itself is an atom, in this way we can modify the list that we're building as output. Here's a fixed version:
(define double
(lambda (x)
(cond ((null? x) '())
((list? (car x)) ; ask about the car of the list. It's better to use pair?
(cons (double (car x)) ; use cons, not append
(double (cdr x))))
(else (cons (car x) (cons (car x) (double (cdr x)))))))) ; double the car
It works as expected:
(double '(a ((b) (c d) (((e))))))
=> '(a a ((b b) (c c d d) (((e e)))))
Related
What is the function to reverse a list in Scheme?
It needs to be able to handle nested lists. So that if you do something like (reverse '(a (b c d) e)) you'll get (e (b c d) a) as the output.
How should I approach this problem? I'm not just looking for an answer, but something that will help me learn.
(define (my-reverse ls)
(define (my-reverse-2 ls acc)
(if (null? ls)
acc
(my-reverse-2 (cdr ls) (cons (car ls) acc))))
(my-reverse-2 ls '()))
This uses an accumulator variable to reverse the list, taking the first element off the incoming list and consing it to the front of the accumulator. It hides the accumulator taking function and just exposes the function that takes a list, so the caller doesn't have to pass in the empty list. That's why I have my-reverse-2.
(my-reverse-2 '(a (b c d) e) '()); will call
(my-reverse-2 '((b c d) e) '(a)); which will call
(my-reverse-2 '(e) '((b c d) a)); which will call
(my-reverse-2 '() '(e (b c d) a)); which will return
'(e (b c d) a)
Because the last function call in my-reverse-2 is a call to my-reverse-2, and the return value is passed right through (the return value of the first call is the return value of the second call, and so on) my-reverse-2 is tail optimized, which means it will not run out of room on the stack. So it is safe to call this with a list as long as you like.
If you want it to apply to nested lists use something like this:
(define (deep-reverse ls)
(define (deep-reverse-2 ls acc)
(if (null? ls)
acc
(if (list? (car ls))
(deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc))
(deep-reverse-2 (cdr ls) (cons (car ls) acc)))))
(deep-reverse-2 ls '()))
This checks to see if the element is a list before adding it to the list, and if it is, reverses it first.
Since it calls itself to revers the inner list, it can handle arbitrary nesting.
(deep-reverse '(a (b c d) e)) -> '(e (d c b) a) which is in reverse alphabetical order, despite the fact that there is a nested list.
It evaluates as so:
(deep-reverse-2 '(a (b c d) e) '()); Which calls
(deep-reverse-2 '((b c d) e) '(a))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d) '(b)) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(d) '(c b)) '(a)))
(deep-reverse-2 '(e) (cons '(d c b) '(a)))
(deep-reverse-2 '(e) '((d c b) a))
(deep-reverse-2 '() '(e (d c b) a))
'(e (d c b) a)
Use:
(define (reverse1 l)
(if (null? l)
nil
(append (reverse1 (cdr l)) (list (car l)))
)
)
Explanation:
Rules:
If the list is empty, then the reverse list is also empty
Else behind the reverse tail of the list, add the first element of the list
Look at this code this way:
reverse1 is name of the function and l is a parameter. If the list is empty then the reverse is also empty.
Else call the reverse1 function with (cdr l) which is the tail of the list and append that to the first alement (car l) that you make as a list.
In your example (pseudocode):
1st iteration
l=>(a (bcd)e)
car l => a
cdr l => (bcd)e
list(car l) =>(a)
------------------
reverse( cdr l)"+"(a)
------------------
2nd iteration
l=>((bcd)e)
car l => (bcd)
cdr l =>e
list(car l)=>(bcd)
--------------------
reverse(cdr l)"+"((bcd))+(a)
-----------------------
3rd iteration
l=>e
car l=> e
cdr l => nil
list (car l) =>(e)
-------------------------
(e (bcd)a)
This is one way that you can make a reverse function that applies to nested lists:
(define (reverse-deep l)
(map (lambda (x) (if (list? x) (reverse-deep x) x)) (reverse l)))
Explanation in pseudo-code:
Start by reversing the list as you would normally do
Then for each element in the reversed list:
- If the element is a list itself: Apply the procedure recursively
- Else: Don't touch the element
You could simply reverse the elements in a list using foldr:
(foldr (lambda (a r) (append r (list a))) empty lst)
This is a reverse function in Racket which I like much better than Scheme.
It uses the match pattern matching function only.
(define/match (rev l)
[('()) '()]
[((list a ... b)) (cons b (rev a))])
> (rev '(a (b c d) e))
'(e (b c d) a)
My solution:
(define (rvrs ls)
(if (null? ls)
empty
(append (rvrs (cdr ls)) (cons (car ls) empty))))
I used code similar to insertion sort:
(define deep-rev-list
(lambda (l)
(cond ((null? l) (quote ()))
((atom? (car l))
(swap-till-end (carl) (deep-rev-list (cdr l))))
(else
(swap-till-end (deep-rev-list (car l)) (deep-rev-list (cdr l)))))))
(define swap-till-end
(lambda (elm lst)
(cond ((null? lst) (cons elm '()))
(else
(cons (car lst) (swap-till-end elm (cdr lst)))))))
(define atom?
(lambda (x)
(and (not (null? x)) (not (pair? x)))))
I am reproducing it from memory. There may be some errors. I will correct the code if that's the case. But the technique used is similar to the commandments for nested lists given in THe Little Schemer :). I checked it in DrRacket.
(deep-rev-list '((1 2) (3) ((4 5)))) returns (((5 4)) (3) (2 1))
I'm finishing up a Scheme assignment and I'm having some trouble with the recursive cases for two functions.
The first function is a running-sums function which takes in a list and returns a list of the running sums i.e (summer '(1 2 3)) ---> (1 3 6) Now I believe I'm very close but can't quite figure out how to fix my case. Currently I have
(define (summer L)
(cond ((null? L) '())
((null? (cdr L)) '())
(else (cons (car L) (+ (car L) (cadr L))))))
I know I need to recursively call summer, but I'm confused on how to put the recursive call in there.
Secondly, I'm writing a function which counts the occurrences of an element in a list. This function works fine through using a helper function but it creates duplicate pairs.
(define (counts L)
(cond ((null? L) '())
(else (cons (cons (car L) (countEle L (car L))) (counts (cdr L))))))
(define (countEle L x)
(if (null? L) 0
(if (eq? x (car L)) (+ 1 (countEle (cdr L) x)) (countEle (cdr L) x))))
The expected output is:
(counts '(a b c c b b)) --> '((a 1) (b 3) ( c 2))
But it's currently returning '((a . 1) (b . 3) (c . 2) (c . 1) (b . 2) (b . 1)). So it's close; I'm just not sure how to handle checking if I've already counted the element.
Any help is appreciated, thank you!
To have a running sum, you need in some way to keep track of the last sum. So some procedure should have two arguments: the rest of the list to sum (which may be the whole list) and the sum so far.
(define (running-sum L)
(define (rs l s)
...)
(rs L 0))
For the second procedure you want to do something like
(define (count-elems L)
(define (remove-elem e L) ...)
(define (count-single e L) ...)
(if (null? L)
'()
(let ((this-element (car L)))
(cons (list this-element (count-single this-element L))
(count-elems (remove-elem this-element (cdr L)))))))
Be sure to remove the elements you've counted before continuing! I think you can fill in the rest.
To your first problem:
The mistake in your procedure is, that there is no recursive call of "summer". Have a look at the last line.
(else (cons (car L) (+ (car L) (cadr L))))))
Here is the complete solution:
(define (summer LL)
(define (loop sum LL)
(if (null? LL)
'()
(cons (+ sum (car LL)) (loop (+ sum (car ll)) (cdr LL)))))
(loop 0 LL))
My goal is to write a function named (double ALIST ELEM) that accepts a list of elements and returns that list where every occurrence of ELEM (any scheme value) has been replaced by a sequence of two ELEM's. The replacement will not occur within nested lists.
For example, if I were to call
(double '(a b c) 'c)
It would return
'(a b c c)
This is the code that I have so far
(define (double x y)
(cond ((null? x) '())
((not(equal? (car x) y)) (double (cdr x) y))
(else (append (list (car x)) (append x (double (cdr x) y))))))
If we take the previous example and replace c with a, I get the correct output. However, if I run the example above I get just a list containing '(c c). I have tried many different ways of writing this and I always seem to get this output. I am entirely unsure of what I am doing wrong in this case.
Ok, so I found one error (at least I think), to keep the previous elements in the list if the character I am looking for is not found, but now I am stuck on the else statement and what I need to put in there to add the element in that position again and recall the function. These are the updated changes
(define (double x y)
(cond ((null? x) '())
((not(equal? (car x) y)) (append (list (car x)) (double (cdr x) y)))
(else <insert-code-here>)))
In the event the element matches y, you want to cons y on twice
otherwise, just re-cons the list by recursing with the tail
(define (double xs y)
(cond ((null? xs) '())
((equal? y (car xs)) (cons y (cons y (double (cdr xs) y))))
(else (cons (car xs) (double (cdr xs) y)))))
(double '(a b c a b c a b c) 'c)
;; => '(a b c c a b c c a b c c)
Im trying to write a function called removesub* which accepts two arguments (l1 and l2). The function needs to return the second list with the first occurence of the subsequence removed. So, if the first list is '(a b c), the first a if the second list is removed, the first b that appears after the removed a is removed, and the first c that appears after the removed b is removed - no matter how deep the atoms are nested.
Working Example
Input: (removesub* '(a b) '(w (x b) ((a) ((y z))) b a))
Output: (w (x b) (() ((y z))) a)
My current attempt doesnt seem to work because I have no way of sharing the l1 argument between nested recursive calls i.e. ((pair? (car l2)) (cons (removesub* l1 (car l2)) (removesub* l1 (cdr l2)))) splits l1 into two separate instances resulting in the following result. How can I share the l1 value so every recursive calls knows if the others have found the first instance of a value in l1?
Working Example
Input: (removesub* '(a b) '(w (x b) ((a) ((y z))) b a))
Output: (w (x b) (() ((y z))) b)
Attempted Solution - Scheme
(define removesub*
(lambda (l1 l2)
(cond
((or (null? l1) (null? l2)) l2)
((pair? (car l2)) (cons (removesub* l1 (car l2)) (removesub* l1 (cdr l2))))
((eq? (car l1) (car l2)) (removesub* (cdr l1) (cdr l2)))
(else (cons (car l2) (removesub* l1 (cdr l2)))))))
You need to pass the resulting symbols to search for to the next iteration. THere are many ways to do this.
You can use a compound return in the helper
(define (removesub* elements-in-order haystack)
;; just use a pair to pass result and the
;; elements to continue searching for
(define (result eio h)
(cons eio h))
(cdr
(let rec ((eio elements-in-order)
(h haystack))
(cond ((or (not (pair? eio))
(not (pair? h)))
(result eio h))
((pair? (car h))
(let* ((r (rec eio (car h)))
(r2 (rec (car r) (cdr h))))
(result (car r2) (cons (cdr r) (cdr r2)))))
((eq? (car eio) (car h))
(rec (cdr eio) (cdr h)))
(else
(let ((r (rec eio (cdr h))))
(result (car r) (cons (car h) (cdr r)))))))))
Notice I do car first then use both parts of the result to do the next.
Scheme/Racket can return more than one value with values
(define (removesub* elements-in-order haystack)
(define (helper eio h)
(cond ((or (not (pair? eio))
(not (pair? h)))
(values eio h))
((pair? (car h))
(let*-values ([(eiocar hcar) (helper eio (car h))]
[(eiocdr hcdr) (helper eiocar (cdr h))])
(values eiocdr (cons hcar hcdr))))
((eq? (car eio) (car h))
(helper (cdr eio) (cdr h)))
(else
(let-values ([(eiocdr hcdr) (helper eio (cdr h))])
(values eiocdr (cons (car h) hcdr))))))
(let-values ([(eio result) (helper elements-in-order haystack)])
result))
Not really a semantic difference over the first, but it might be a tad faster since in theory the results can stay on the stack rather than each result having to create a cons that can be GC-ed as fast as the stack unrolls.
You can use continuation passing style:
(define (removesub* elements-in-order haystack)
(let cps ((eio elements-in-order)
(h haystack)
(c (lambda (eio h) h)))
(cond ((or (not (pair? eio))
(not (pair? h)))
(c eio h))
((pair? (car h))
(cps eio
(car h)
(lambda (eio hcar)
(cps eio
(cdr h)
(lambda (eio hcdr)
(c eio (cons hcar hcdr)))))))
((eq? (car eio) (car h))
(cps (cdr eio) (cdr h) c))
(else
(cps eio
(cdr h)
(lambda (eio res)
(c eio (cons (car h) res))))))))
This works by the helper has a continuation argument. This is close to what many Scheme implementations actually do to your code before running.
You can use mutation
Probably the fastest and easiest, but then you need to use #!r6rs or another standard Scheme rather than #!racket as implementation language.
What is the function to reverse a list in Scheme?
It needs to be able to handle nested lists. So that if you do something like (reverse '(a (b c d) e)) you'll get (e (b c d) a) as the output.
How should I approach this problem? I'm not just looking for an answer, but something that will help me learn.
(define (my-reverse ls)
(define (my-reverse-2 ls acc)
(if (null? ls)
acc
(my-reverse-2 (cdr ls) (cons (car ls) acc))))
(my-reverse-2 ls '()))
This uses an accumulator variable to reverse the list, taking the first element off the incoming list and consing it to the front of the accumulator. It hides the accumulator taking function and just exposes the function that takes a list, so the caller doesn't have to pass in the empty list. That's why I have my-reverse-2.
(my-reverse-2 '(a (b c d) e) '()); will call
(my-reverse-2 '((b c d) e) '(a)); which will call
(my-reverse-2 '(e) '((b c d) a)); which will call
(my-reverse-2 '() '(e (b c d) a)); which will return
'(e (b c d) a)
Because the last function call in my-reverse-2 is a call to my-reverse-2, and the return value is passed right through (the return value of the first call is the return value of the second call, and so on) my-reverse-2 is tail optimized, which means it will not run out of room on the stack. So it is safe to call this with a list as long as you like.
If you want it to apply to nested lists use something like this:
(define (deep-reverse ls)
(define (deep-reverse-2 ls acc)
(if (null? ls)
acc
(if (list? (car ls))
(deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc))
(deep-reverse-2 (cdr ls) (cons (car ls) acc)))))
(deep-reverse-2 ls '()))
This checks to see if the element is a list before adding it to the list, and if it is, reverses it first.
Since it calls itself to revers the inner list, it can handle arbitrary nesting.
(deep-reverse '(a (b c d) e)) -> '(e (d c b) a) which is in reverse alphabetical order, despite the fact that there is a nested list.
It evaluates as so:
(deep-reverse-2 '(a (b c d) e) '()); Which calls
(deep-reverse-2 '((b c d) e) '(a))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d) '(b)) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(d) '(c b)) '(a)))
(deep-reverse-2 '(e) (cons '(d c b) '(a)))
(deep-reverse-2 '(e) '((d c b) a))
(deep-reverse-2 '() '(e (d c b) a))
'(e (d c b) a)
Use:
(define (reverse1 l)
(if (null? l)
nil
(append (reverse1 (cdr l)) (list (car l)))
)
)
Explanation:
Rules:
If the list is empty, then the reverse list is also empty
Else behind the reverse tail of the list, add the first element of the list
Look at this code this way:
reverse1 is name of the function and l is a parameter. If the list is empty then the reverse is also empty.
Else call the reverse1 function with (cdr l) which is the tail of the list and append that to the first alement (car l) that you make as a list.
In your example (pseudocode):
1st iteration
l=>(a (bcd)e)
car l => a
cdr l => (bcd)e
list(car l) =>(a)
------------------
reverse( cdr l)"+"(a)
------------------
2nd iteration
l=>((bcd)e)
car l => (bcd)
cdr l =>e
list(car l)=>(bcd)
--------------------
reverse(cdr l)"+"((bcd))+(a)
-----------------------
3rd iteration
l=>e
car l=> e
cdr l => nil
list (car l) =>(e)
-------------------------
(e (bcd)a)
This is one way that you can make a reverse function that applies to nested lists:
(define (reverse-deep l)
(map (lambda (x) (if (list? x) (reverse-deep x) x)) (reverse l)))
Explanation in pseudo-code:
Start by reversing the list as you would normally do
Then for each element in the reversed list:
- If the element is a list itself: Apply the procedure recursively
- Else: Don't touch the element
This is a reverse function in Racket which I like much better than Scheme.
It uses the match pattern matching function only.
(define/match (rev l)
[('()) '()]
[((list a ... b)) (cons b (rev a))])
> (rev '(a (b c d) e))
'(e (b c d) a)
You could simply reverse the elements in a list using foldr:
(foldr (lambda (a r) (append r (list a))) empty lst)
My solution:
(define (rvrs ls)
(if (null? ls)
empty
(append (rvrs (cdr ls)) (cons (car ls) empty))))
I used code similar to insertion sort:
(define deep-rev-list
(lambda (l)
(cond ((null? l) (quote ()))
((atom? (car l))
(swap-till-end (carl) (deep-rev-list (cdr l))))
(else
(swap-till-end (deep-rev-list (car l)) (deep-rev-list (cdr l)))))))
(define swap-till-end
(lambda (elm lst)
(cond ((null? lst) (cons elm '()))
(else
(cons (car lst) (swap-till-end elm (cdr lst)))))))
(define atom?
(lambda (x)
(and (not (null? x)) (not (pair? x)))))
I am reproducing it from memory. There may be some errors. I will correct the code if that's the case. But the technique used is similar to the commandments for nested lists given in THe Little Schemer :). I checked it in DrRacket.
(deep-rev-list '((1 2) (3) ((4 5)))) returns (((5 4)) (3) (2 1))