Function returns other recursive function in Racket - scheme

Suppose we have a function f. This function takes as an argument a list l and returns a function of one argument g.Function g takes as an argument x and looking for the x in the list l. If it finds it returns true, else false.
I'm interested in a solution without using the built-in functions.
My start code:
(define (f l)
(lamda (x)
..........
)))

You could go for this:
(define (f l)
(lambda (x)
(and (member x l) #t)))
(define g (f '(a b c e)))
(g 'a)
=> #t
(g 'd)
=> #f
If you need to avoid the built-in member procedure, you can roll your own member?:
(define (member? e l)
(and (not (null? l))
(or (eq? (car l) e) (member? e (cdr l)))))
(define (f l)
(lambda (x)
(member? x l)))
or have member? as an internal procedure, if you prefer:
(define (f l)
(define (member? e l)
(and (not (null? l))
(or (eq? (car l) e) (member? e (cdr l)))))
(lambda (x)
(member? x l)))

Related

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

Scheme Loop Through a List

How would I loop this list in scheme?
(define test-document '(
((h e l l o))
((t h i s)(i s)(t e s t))
))
What I tried it only showed the first column.
car and cdr family of functions are your friends to navigate lists. Here are some examples.
(define test-document '(
((h e l l o))
((t h i s)(i s)(t e s t))
))
(car test-document) ;; `((h e l l o))
(caar test-document) ;; `(h e l l o)
(cadr test-document) ;; `((t h i s) (i s) (t e s t))
(car (cadr test-document) ;; `(t h i s)
(cadr (cadr test-document) ;; `(i s)
(caddr (cadr test-document) ;; `(test )
Define a function that will walk the list and call a function for each item that is not a list.
(define (walk-list lst fun)
(if (not (list? lst))
(fun lst)
(if (not (null? lst))
(begin
(walk-list (car lst) fun)
(walk-list (cdr lst) fun)))))
Call it to print each item.
(walk-list test-document print)
What you have is a list of lists of lists:
(define test-document '(((h e l l o)) ((t h i s) (i s) (t e s t))))
To loop over its elements you must create a loop of a loop of a loop. To do so we can use map and curry as follows:
(map (curry map (curry map
(compose string->symbol string-upcase symbol->string)))
test-document)
This produces the following output:
(((H E L L O)) ((T H I S) (I S) (T E S T)))
If your Scheme interpreter doesn't have a built-in curry function then you can define one as follows:
(define (curry func . args)
(lambda x (apply func (append args x))))
Hope this helped.
Were you thinking of something like this?
(define (walk-list lst)
(define (sub-walk lst)
(if (null? lst)
'()
(let ((x (car lst)))
(if (list? x)
(cons (sub-walk x) (sub-walk (cdr lst)))
(apply string-append (map symbol->string lst))))))
(flatten (sub-walk lst)))
then
(walk-list test-document)
=> '("hello" "this" "is" "test")
which you can process using the usual suspects (map, filter, ...).
If your Scheme has no flatten procedure, you can use this one:
(define (flatten lst)
(reverse
(let loop ((lst lst) (res null))
(if (null? lst)
res
(let ((c (car lst)))
(loop (cdr lst) (if (pair? c) (loop c res) (cons c res))))))))

Insert element to start of sublist in list of lists

I'm having a little trouble with an assignment. I have to create a procedure that requests a list of lists and an element and proceeds to add the element to the first position in every sublist. I managed to do that and it looks like this:
(define (add-element lst elem)
(foldr cons lst (list elem)))
(define (insert-first lst1 x)
(cond
[(empty? lst1) empty]
[else (local [(define insert (add-element(first lst1) x))]
(cons insert (insert-first (rest lst1) x)))]))
So if you were to type (insert-first '((a b) (c d)) you'd end up with (list (list 'x 'a 'b) (list 'x 'c 'd))
Only problem is that I'm required to code the procedure using map and local. The latter one I think I accomplished but I can't for the life of me figure out a way to use map.
(define (insert-first elt lst)
(map (lambda (x)
(cons elt x))
lst))
then
(insert-first 'x '((a b) (c d)))
=> '((x a b) (x c d))
(define (insert-first lst elem)
(foldr (lambda (x y) (cons (cons elem x) y)) '() lst))
Close to your solution, but map is more naturally suited to the problem than a fold, since you want to want to do something to each element of a list. Use fold when you want to accumulate a value by successively applying a function to elements of that list.
foldr embodies a certain recursion pattern,
(foldr g init [a,b,c,...,z])
= (g a (foldr g init [b,c,...,z]))
....
= (g a (g b (g c ... (g z init) ...)))
if we manually expand the foldr call in your add-element function definition, we get
(add-element lst elem)
= (foldr cons lst (list elem))
= (cons elem (foldr cons lst '()))
= (cons elem lst)
then, looking at your insert-first function, we see it is too following the foldr recursion pattern,
(insert-first lst1 x)
= (foldr (lambda(a r)(cons (add-element a x) r)) empty lst1)
= (foldr (lambda(a r)(cons (cons x a) r)) empty lst1)
But (foldr (lambda(a r) (cons (g a) r)) empty lst) === (map g lst), because to combine sub-terms with cons is to build a list, which is what map does; and so we get
(insert-first lst1 x) = (map (lambda(a)(cons x a)) lst1)
and so we can write
(define (insert-first lst1 x)
(local [(define (prepend-x a) (cons ... ...))]
(map ... ...)))

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.

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