Scheme: Searching element in a list and sublist - scheme

I want to write a function that receives list and returns a list of each element.
For example:
get - (x 3 4 5 (x 4) 3 x (6))) and receive: (x (x) x ())
(define (lookForX lst)
(cond
((null? lst) '())
((eq? (car lst) 'x) (cons (car lst) (lookForX (cdr lst))) )
(else (lookForX (cdr lst)))))
my code result for:
(lookForX '(x 3 4 5 (x 4) 3 x (6)))
-> (x x)
What am I doing wrong?

In you function you are only looking for x as element in the list and you are not doing sub lists:
(define (filter-x lst)
(cond
((null? lst) '())
((eq? (car lst) 'x)
(cons (car lst)
(filter-x (cdr lst))))
((pair? (car lst))
(cons (filter-x (car lst))
(filter-x (cdr lst))))
(else (filter-x (cdr lst)))))
(filter-x '(x 3 4 5 (x 4) 3 x (6)))
; ==> (x (x) x ())
Notice I renamed this to be more lisp like. Lisp code usually don't use camelCase but lisp-case. You can do it more general:
(define (filter-tree predicate? lst)
(cond
((null? lst) '())
((predicate? (car lst))
(cons (car lst)
(filter-tree predicate? (cdr lst))))
((pair? (car lst))
(cons (filter-tree predicate? (car lst))
(filter-tree predicate? (cdr lst))))
(else (filter-tree predicate? (cdr lst)))))
(define (filter-tree-x lst)
(filter-tree (lambda (v) (eq? v 'x)) lst))
(filter-tree-x '(x 3 4 5 (x 4) 3 x (6)))
; ==> (x (x) x ())
(define (filter-tree-numbers lst)
(filter-tree number? lst))
(filter-tree-numbers '(x 3 4 5 (x 4) 3 x (6)))
; ==> (3 4 5 (4) 3 (6))

Related

Removing all ()'s from a sublist in Racket

I need to have the following program interaction:
(clean'(1 (2 () (3 () 4))()()(()) 5)) → (1 (2 (3 4)) 5)
This is what I have so far
define (emptyClear theList)
(cond ((null? theList) '())
((null? (car theList)) (emptyClear (cdr theList)))
(else (cons (car theList) (emptyClear (cdr theList))))))
(define (clean tree)
(cond ((null? tree) '())
((not (list? (car tree))) (cons (car tree) (prune (cdr tree))))
(cons (emptyClear (car tree)) (prune (cdr tree)))))
But this gives me: -> (1 5) as the output.
How can I solve this issue?
From the example the task seems to be not simply to remove empty lists from a tree, but to continue to perform this operation until possible (since '(())) is not an empty list, but it is removed nevertheless).
Here is a possible solution, tested with DrRacket.
(define (my-empty? x)
(cond ((null? x) #t)
((list? x) (andmap my-empty? x))
(else #f)))
(define (clean x)
(cond ((null? x) '())
((not (list? x)) x)
((my-empty? (car x)) (clean (cdr x)))
(else (cons (clean (car x)) (clean (cdr x))))))
(clean '(1 (2 () (3 () 4))()()((())) 5)) ;=> '(1 (2 (3 4)) 5)

Create palindrom function without append function in output in scheme

i am trying to create palyndrom function which is doing palyndrom from input string. Something like this: (palindrome '(1 2 3 4)) ==> (1 2 3 4 3 2 1).
I have created this code below but it is returning me (palindrome '(1 2 3 4)) ==> (1 (2 (3 (4) 3) 2) 1)
My code is below. Task is to NOT use append or reverse.
(define (palindrome l)
(cond
((null? (cdr l)) (list (car l)))
((list (car l) (palindrome (cdr l)) (car l)))))
Thanks for help.
As in the comment of Sylwester, you can do your own version of append or reverse. Here is an example in which only the append function (called concatenate) is defined.
(define (palindrome l)
(define (concatenate l1 l2)
(if (null? l1)
l2
(cons (car l1) (concatenate (cdr l1) l2))))
(define (p l)
(cond ((null? l) '())
((null? (cdr l)) l)
(else (cons (car l) (concatenate (p (cdr l)) (list (car l)))))))
(p l))
(palindrome '(1 2 3 4))
'(1 2 3 4 3 2 1)
Here instead is a tail recursive version:
(define (palindrome l)
(define (concatenate l1 l2)
(if (null? l1)
l2
(cons (car l1) (concatenate (cdr l1) l2))))
(define (p l prefix suffix)
(cond ((null? l) (concatenate prefix suffix))
((null? (cdr l)) (concatenate prefix (cons (car l) suffix)))
(else (p (cdr l) (concatenate prefix (list (car l))) (cons (car l) suffix)))))
(p l '() '()))

Scheme - how to not 'flattened' pairs in list?

My task is to get first atom in structure, that's why I'm used flatten and func "first-atom-lst". But there is one big problem - I need to handle pairs in structure and do NOT broke pairs. Can you please help me to handle this?
(define (check-improper? lst)
(cond
((null? lst) #f)
((number? lst) #f)
((atom? lst) #f)
((list? lst) #f)
((pair? (cdr lst)) #t)
(#t #f)
))
(define (improper-to-proper lst)
(cond
((null? lst) '())
((not (pair? (cdr lst))) (cons lst '()))
(else (cons (car lst) (improper-to-proper (cdr lst))))
)
)
(define (first-atom-from-pair lst)
(cond ((check-improper? lst))
((null? lst) #f)
((atom? (car (flatten lst)))
(car (flatten lst)))
(else
(first-atom (cdr (flatten lst))))))
(define (first-atom lst)
(cond ((check-improper? lst))
((null? lst) #f)
((atom? lst) lst)
((pair? (cdr lst)) (first-atom-from-pair lst))
((pair? lst) #f)
((atom? (car (flatten (not pair? lst))))
(car (flatten (not pair? lst))))
(else
(first-atom (cdr (flatten lst))))))
You cannot flatten improper lists, but it's actually overkill in your case anyway. You could do something like this:
(define (first-atom tree)
(if (null? tree)
#f
(if (pair? tree)
(first-atom (car tree))
tree)))
then
> (first-atom '((2 . 0) 2))
2
> (first-atom '((1 . 0) (2 . 3) 2))
1
> (first-atom '((2 . 1) (2 3) 1))
2
> (first-atom '(((((((1 . 2) 3) 4))))))
1
Note that my second result differs from yours, but I believe mine is correct since the first element of a flattened list would also yield 1.
Solve problem, but need improvement.
(define (atom? a)
(and (not (pair? a))
(not (null? a))))
(define (true-pair? p)
(cond
((list? p) #f)
((pair? (cdr p)) #f)
(else #t)))
(define (flatten-atom x)
(cond ((null? x) '())
((atom? x) (list x))
((true-pair? x) (list x))
(else (append (flatten-atom (car x))
(flatten-atom (cdr x))))))
(flatten-atom '((a b . c)))
(flatten-atom '((a b c) d e () ((f)) (1 . 2)))
(flatten-atom '((a b . c) (((4 5))) () 6 (7 . 8)))
> (a (b . c))
> (a b c d e f (1 . 2))
> (a (b . c) 4 5 6 (7 . 8))

Removing Duplicates from a list as well as the elements themselves- Racket, Scheme

(define (remove-duplicates l)
(cond ((empty? l)
'())
((member (first l) (rest l))
(remove-duplicates (rest l)))
(else
(cons (first l) (remove-duplicates (rest l))))))
This code has this result.
> (remove-duplicates (list 1 1 2 2 3 4))
(list 1 2 3 4)
Without using filter, I would like the result to be
(remove-duplicates (list 1 1 2 2 3 4)) gives
(list 3 4)
Help would be deeply appreciated. Thanks in advance.
You could use a helper function:
(define helper
(lambda (lst collector dup)
(cond [(null? lst) collector]
[(memq (car lst) (cdr lst)) (helper (cdr lst) collector (cons (car lst) dup))]
[(memq (car lst) dup) (helper (cdr lst) collector dup)]
[else
(helper (cdr lst) (cons (car lst) collector) dup)])))
Maintain two lst, collector for all unique element, and dup for duplicated elements.
(define remove-dup
(lambda (lst)
(reverse (helper lst '() '()))))

How to duplicate a list in scheme?

the following code removes duplicate in a list which I got from abo-abo's answer in this question.
(define (remove-duplicates l)
(cond ((null? l)
'())
((member (car l) (cdr l))
(remove-duplicates (cdr l)))
(else
(cons (car l) (remove-duplicates (cdr l))))))
I am just starting learning scheme, how can I duplicate each item in the list for example (5 6 7 8 9 9 10 11 11) will become (5 5 6 6 7 7 8 8 9 9 9 9 10 10 11 11 11 11)?
Explicit recursion with appendand list, and foldr version just with cons:
(define (dup lst)
(if (empty? lst)
'()
(append (list (car lst) (car lst))
(dup (cdr lst)))))
(define (dup2 lst)
(foldr (λ (x xs) (cons x (cons x xs)))
'()
lst))
if you have a list l you can do the following to have a duplicate of the first item at the beginning of a resulting list,
(cons (car l) l)
or equivalently
(cons (car l) (cons (car l) (cdr l)))
This results in the following solution:
(define (duplicate l)
(cond ((null? l)
'())
(else
(cons (car l) (cons (car l) (duplicate (cdr l)))))))

Resources