how to remove neighbouring duplicate in a list? [duplicate] - scheme

I have to make a Dr. Racket program that removes letters from a list if they are following the same letter as itself. For example: (z z f a b b d d) would become
(z f a b d). I have written code for this but all it does is remove the first letter from the list.
Can anyone help?
#lang racket
(define (remove-duplicates x)
(cond ((null? x)
'())
((member (car x) (cons(car(cdr x)) '())))
(remove-duplicates (cdr x))
(else
(cons (car x) (remove-duplicates (cdr x))))))
(define x '( b c c d d a a))
(remove-duplicates x)

(define (remove-dups x)
(cond
[(empty? x) '()]
[(empty? (cdr x)) (list (car x))]
[(eq? (car x) (cadr x)) (remove-dups (cdr x))]
[else (cons (car x) (remove-dups (cdr x)))]))
(cadr x) is short for (car (cdr x)) in case you didn't know.
Also, pattern matching makes list deconstruction often much more readable. In this case not so much, but it's still better than the other version:
(define (rmv-dups x)
(match x
[(list) (list)]
[(list a) (list a)]
[(cons a (cons a b)) (rmv-dups (cdr x))]
[__ (cons (car x) (rmv-dups (cdr x)))]))

This problem will be simpler if you introduce a helper function.
I recommend something like this (where angle brackets mean you need to fill out the details):
(define (remove-duplicates x)
(cond
[ <x is empty> '()] ; no duplicates in empty list
[ <x has one element> x] ; no duplicates in a list with one element
[ <first and second element in x is equal> (cons (car x) (remove-from-front (car x) (cdr x)))]
[else (cons (car x) (remove-duplicates (cdr x)))]))
(define (remove-from-front e x)
(cond
[ <x is empty> '()] ; e is not the first element of x
[ <e equals first element of x> (remove-from-front e (cdr x))] ; skip duplicate
[else (remove-duplicates x)])) ; no more es to remove

Related

Maintaining list structure when duplicating

I am writing a function to duplicate all the items in a list, so that a list like (a (b c)) becomes (a a (b b c c)), however my function returns (a a b b c c). How do I ensure I retain the internal list structure? Here is my current code:
(define double
(lambda (l)
(cond ((null? l) '())
((list? l) (append (double (car l)) (double (cdr l))))
(else (append (list l) (list l)) )
)
))
To preserve the structure of the list, you have to avoid using append. Here is an implementation:
(define (double lst)
(cond
[(null? lst) empty]
[(list? (car lst))
(cons (double (car lst))
(double (cdr lst)))]
[else
(cons (car lst) (cons (car lst)
(double (cdr lst))))]))
For example,
> (double '(a (b c) ((a b) (c d))))
'(a a (b b c c) ((a a b b) (c c d d)))
Shallow copy:
(define (copy-list lst)
(map values lst))
And of course map is like this for one list argument:
(define (map f lst)
(if (null? lst)
'()
(cons (f (car lst))
(map f (cdr lst)))))
Deep copy:
(define (copy-tree tree)
(accumulate-tree tree values cons '()))
And this is how accumulate-tree is made:
(define (accumulate-tree tree term combiner null-value)
(let rec ((tree tree))
(cond ((null? tree) null-value)
((not (pair? tree)) (term tree))
(else (combiner (rec (car tree))
(rec (cdr tree)))))))

How to use self-compose with sort-step to sort

(define (compose f1 f2)
(lambda (p2) (f1 (f2 p2))))
(define (self-compose f n)
(if (= n 1) (compose f f)
(compose f (self-compose f (- n 1)))))
(define (sort-step l f)
(cond ((eq? l '()) '())
((eq? (cdr l) '()) (list (car l)))
((f (car l) (cadr l)) (cons (car l) (sort-step (cdr l) f)))
(else (cons (cadr l) (sort-step (cons (car l) (cddr l)) f)))))
How to use self-compose with sort-step to sort?
Tried:
(define (sort-f l f)
(self-compose (sort-step l f) (length l)))
test:
(sort-f '(8 4 6 5 3) >) ===> arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 0
(sort-step l f) is not a function of one argument as compose expects, it's a list.
Since you probably want to "thread" the list through the composition, you need to compose a function that takes a list and returns a list.
You can get one by rearranging sort-step slightly into a curried function:
(define (sort-step f)
(lambda (l)
(cond ((null? l) '())
((null? (cdr l)) l)
((f (car l) (cadr l)) (cons (car l) ((sort-step f) (cdr l))))
(else (cons (cadr l) ((sort-step f) (cons (car l) (cddr l))))))))
Now (sort-step f) is a function from list to list and you can say
(define (sort-f l f)
((self-compose (sort-step f) (length l)) l))
The l param can also be thread by a lambda in the self-compose without rewriting sort-step:
(define (sort-f l f)
((self-compose (lambda (l) (sort-step l f)) (length l)) l))

Where is the error in this Scheme program?

I am getting "Error: Invalid lambda: (lambda (insert-all))."
(define permutations
(lambda (L)
(let
((insert-all
(lambda (e Ls)
(let
((insert-one
(lambda (L)
(letrec
((helper
(lambda(L R)
(if (null? R)
(list (append L(list e)R))
(helper (append L (list (car R) ) ) (cdr R) )
))))
(helper '() L)))))
(apply append(map insert-one Ls)))))))
(cond ((null? L) '() )
((null?(cdr L)) (list L))
(else (insert-all (car L) (permutations ((cdr L))))))))
It is supposed to return all permutations of a given list.
The form that you have provided in not valid scheme. Specifically, your highest-level let form does not have a body. You might be thinking that the cond clause is the body but owing to your parenthesis it is not part of the let. Honestly, this is the fault of your formatting. Here is a 'properly' formatted Scheme form:
(define (permutations L)
(let ((insert-all
(lambda (e Ls)
(let ((insert-one
(lambda (L)
(let helper ((L '()) (R L))
(if (null? R)
(list (append L (list e) R))
(helper (append L (list (car R)))
(cdr R)))))))
(apply append (map insert-one Ls))))))
(cond ((null? L) '())
((null? (cdr L)) (list L))
(else (insert-all (car L)
(permutations (cdr L)))))))
At least it compiles and runs, although it doesn't produce the right answer (although I don't know what the proper input it):
> (permutations '(a b c))
((c b a))
> (permutations '((a b) (1 2)))
(((1 2) (a b)))
Here is an implementation that works:
(define (permutations L)
(define (insert-all e Ls)
(apply append
(map (lambda (e)
(map (lambda (x) (cons e x)) Ls))
e)))
(cond ((null? L) '())
((null? (cdr L)) (map list (car L)))
(else (insert-all (car L)
(permutations (cdr L))))))
> (permutations '((a b) (1 2) (x y)))
((a 1 x) (a 1 y) (a 2 x) (a 2 y) (b 1 x) (b 1 y) (b 2 x) (b 2 y))
The basic structure of your code was fine; just the implementation of your insert-one and helper were lacking.

Encapsulating Certain Parts of List

I'm trying to write a procedure that "encapsulates" (i.e. puts in a list) elements of a list between a "separator" element.
(my-proc '(1 + 2))
=> ((1) (2))
(my-proc '(x * y + z ^ 2 + 1 + 5))
=> ((x * y) (z ^ 2) (1) (5))
(my-proc '((x + 1) * y + 5))
=> (((x + 1) * y) (5))
In this case the procedure can be hard-coded to define the + symbol as the separator.
Assume that foldr (fold right operation) is defined, I'd prefer that it'd be in terms of it.
I'm not giving a full solution since this looks really homework-y.
(define (split-expr expr)
(foldr (lambda (e es)
(if (eq? e '+)
<???> ; do split
(cons (cons e (car es))
(cdr es))))
<???> ; what should start be?
es))
Just for fun, here's a version in continuation-passing style (no foldr, probably not suitable as a homework answer):
(define split/cps
(λ (sep ls)
(let loop ([ls ls] [k (λ (item acc)
(if item (cons item acc) acc))])
(cond
[(null? ls)
(k #f '())]
[(eq? sep (car ls))
(loop (cdr ls)
(λ (item acc)
(k #f (if item (cons item acc) acc))))]
[else
(loop (cdr ls)
(λ (item acc)
(k (if item
(cons (car ls) item)
(list (car ls)))
acc)))]))))
Here's another way to do it, also without foldr:
(define split/values
(λ (sep ls)
(let loop ([ls ls])
(cond
[(null? ls)
'()]
[else
(let-values ([(a d) (car-to-sep sep ls)])
(if (null? a)
(loop d)
(cons a (loop d))))]))))
(define car-to-sep
(λ (sep ls)
(let loop ([ls ls] [a '()])
(cond
[(null? ls)
(values '() '())]
[(eq? sep (car ls))
(values '() (cdr ls))]
[else
(let-values ([(a d) (loop (cdr ls) a)])
(values (cons (car ls) a) d))]))))

Homework: Sublist? checking if an item is a sublist of the first one

So I have this program that needs to be written in Scheme using Racket that has the following properties and I am stumped. The function is called sublist? with two inputs of S and L which are both lists. It checks whether S is a sublist of L and returns #t or #f.
Examples would be similar to:
sublist? of (A A) and (A B C) is #f
sublist? of (A B C) and (A B D A B C D) is #t
sublist? of (A (B)) and (C ((A (B))) (C)) is #t
A small function called extractLists needs to be created to extract the lists and (atomicSublist S L) is used to check the two extracted lists to see if every element of S is in L.
So far I have
(define (atomicSublist S L)
(cond ((null? L) #f)
((equal? S (car L)) #t)
(else (atomicSublist S (cdr L)))))
The second part does not really do anything and doesn't even output the extracted value of S.
Updated code:
Just for testing I use atomicSublist to check for now.
Begin with a simpler problem and then generalize.
How would you write a function that checks whether a symbol 'a is an a list or not?
I don't think you want this check ((equal? S (car L) ) #t) as the car of L will never be equal to the list S.
Heres what I came up with for atomicSublist.
(define (atomicSublist S L)
(cond
[(null? S) #t]
[(member? (car S) L) (atomicSublist (cdr s) L)]
[else #f]))
The question is a little ambiguous. What should this return? (sublist? '(a (b)) '(a b c d e)) ??
Anyway here is what i wrote:
(define (sublist? s l)
(cond ((null? s) true)
((atom? (car s))
(cond ((exists? (car s) l) (sublist? (cdr s) (remove-elm (car s) l)))
(else false)))
(else
(cond ((sublist? (car s) l) (sublist? (cdr s) (remove-elm (car s) l)))
(else false)))))
(define (exists? elm l)
(cond ((null? l) false)
((atom? (car l))
(cond ((symbol=? elm (car l)) true)
(else (exists? elm (cdr l)))))
(else
(cond ((exists? elm (car l)) true)
(else (exists? elm (cdr l)))))))
(define (remove-elm elm l)
(cond ((null? l) '())
((null? elm) l)
((atom? elm)
(cond ((atom? (car l))
(cond ((symbol=? elm (car l)) (cdr l))
(else (cons (car l) (remove-elm elm (cdr l))))))
(else
(cons (remove-elm elm (car l)) (remove-elm elm (cdr l))))))
(else
(remove-elm (cdr elm) (remove-elm (car elm) l)))))
(define (atom? elm)
(and (not (null? elm)) (not (pair? elm))))
(sublist? '(a a) ('a b c d e)) returns #f. (sublist? '(a b c) '(a d b e c f)) returns #t. (sublist? '(a (b)) '(c ((a (b)) e f))) returns #t. (sublist? '(a (b) b) '(c ((a (b)) e f))) retrns #f. However, (sublist? '(a (b)) '(a b c d)) returns #t.

Resources