Find a list in a binary tree scheme 2 - scheme

Write a function in Scheme that receives as input argument list cedulas (identification) of students, a binary search tree with instances of the student structure and returns a list of instances of the student structure, where the identification of the list of students is in the binary search tree.
example:
This is the binary tree
(make-árbol-bin
(make-estudiante 5 "35889188" "Victor" (make-fecha 10 6 1991) "calle 67 con cra 20" "4444444") (make-
árbol-bin
(make-estudiante 2 "6457234" "Manuel" (make-fecha 12 10 1992) "calle 56 con cra 33" "5555555") (make-árbol-bin
(make-estudiante 1 "94252688" "Estela" (make-fecha 20 5 1993) "calle 4 con cra 2" "3333333") empty empty) empty)
(make-árbol-bin
(make-estudiante 7 "34987678" "Juan" (make-fecha 25 3 1995) "calle 34 con cra 12" "6666666") empty
empty)
)
List identification
(list "94252688" "94888888")
It should return the following list:
(list (make-estudiante 1 "94252688" "Estela" (make-fecha 20 5 1993) "calle 4 con cra 2" "3333333") )
and I did this but I can not make me return the list
(define-struct fecha ( dia mes año))
This is the structure of the student:
(define-struct estudiante ( codigo id nombre fechanaci direccion telefono))
This is the structure of the binary search tree:
(define-struct arbol-bin( estudiante nod-izq nod-der))
these are the functions that searches the list in the tree
(define(buscarevd n E)
(cond
[(or(empty? E) (empty? n))false]
[(equal? (first n)(estudiante-id E)) true]
[else (buscarevd (rest n) E)]))
(define(buscare n E)
(cond
[(empty? E)false]
[(< (car n)(estudiante-id E)) true]
[else false]))
(define (member-bt x bt)
(cond
[(empty? bt) false]
[(or(buscarevd x (arbol-bin-estudiante bt))
[else
(member-bt x (arbol-bin-nod-der bt))]))
and this
(member-bt (list "94252688" "94888888") tree)
return
true
As I can do to make me return the list.

Not sure if there is some kind of relationship between nodes which would permit you to skip sub-trees here, so I'd use this kind of approach:
(define (member-bt lst tree)
(let loop ((tree tree) (res '()))
(if (null? tree)
res
(let* ((node (árbol-bin-estudiante tree))
(res1 (loop (árbol-bin-nod-der tree) res))
(res2 (loop (árbol-bin-nod-izq tree) res1)))
(if (member (estudiante-id node) lst string=?)
(cons node res2)
res2)))))
then
(let ((lst '("94888888" "34987678" "94252688")))
(let ((res (member-bt lst tree)))
(values res (map estudiante-nombre res))))
=>
'(#<estudiante> #<estudiante>)
'("Estela" "Juan")
Note that this traverses the tree only once, but the order of the students in the result list is not the same as in the initial list. If order needs to be preserved you need to take a different approach, for example:
(define (member-bt-ordered lst tree)
(define (sub e tree)
(if (null? tree)
#f
(let ((node (árbol-bin-estudiante tree)))
(if (string=? e (estudiante-id node))
node
(or (sub e (árbol-bin-nod-der tree))
(sub e (árbol-bin-nod-izq tree)))))))
(filter values (map (lambda (e) (sub e tree)) lst)))
then
(let ((lst '( "94252688" "94888888" "35889188" "34987678" "6457234")))
(let ((res (member-bt-ordered lst tree)))
(values res (map estudiante-nombre res))))
=>
'(#<estudiante> #<estudiante> #<estudiante> #<estudiante>)
'("Estela" "Victor" "Juan" "Manuel")

Related

CPSed binary tree traversal doesn't work as expected

My recursive version looks like
(struct node (val left right) #:transparent)
(define t3 (node 3 '() '()))
(define t4 (node 4 '() '()))
(define t5 (node 5 '() '()))
(define t2 (node 2 t4 t5))
(define t1 (node 1 t2 t3))
;
; ----- 1 -----
; | |
; -- 2 -- 3
;| |
;4 5
(define (countv tree)
(if (null? tree)
0
(+ (node-val tree)
(countv (node-left tree))
(countv (node-right tree)))))
(countv t1)
And CPSed version
(define (countk tree k)
(if (null? tree)
(k 0)
(countk (node-left tree)
(λ (lval)
(countk (node-right tree)
(λ (rval)
(+ (node-val tree) lval rval)))))))
(countk t1 (λ (x) (node-val x)))
The result of countv was 15 as expected, while countk got 4.
You forgot to pass the recursive result to the continuation:
(define (countk tree k)
(if (null? tree)
(k 0)
(countk (node-left tree)
(λ (lval)
(countk (node-right tree)
(λ (rval)
(k (+ (node-val tree) lval rval))))))))
^
Here
Once you remember that, you'll get a runtime error since the result isn't a tree.
This didn't happen in your code because your initial continuation was never applied to anything.
You should call it like this instead:
(countk t1 (λ (x) x))

Rewrite an item in a list of list

This seems straightforward, but I can't seem to find a solution. I want to replace an item within a list of a list with something, but if that item appears multiple times then you randomly replace one of them, but not both. I want to do this in ISL+.
I created the function flatten which appends all sublists :
(check-expect (flatten '((a b) (c) (d e f g) (h i j)))
(list 'a 'b 'c 'd 'e 'f 'g 'h 'i 'j))
(define (flatten lol)
(foldr append empty lol))
I also made rewrite, which replaces the value at index n with whatever you choose
(check-expect (rewrite '(x x x - x x x x) 3 'x)
(list 'x 'x 'x 'x 'x 'x 'x 'x))
(define (rewrite ls n val)
(cond
[(empty? ls) (error "error")]
[(= n 0) (cons val (rest ls))]
[else (cons (first ls) (rewrite (rest ls) (sub1 n) val))]))
The problem is I don't know how to apply this to a list of list and I also don't know how to randomly replace one of items if it occurs more than once. This is what I have for the final product, but it's probably not the way to go:
(define (fullreplace b)
(local [
;makes a list of nested lists of each index the element occurs
;problem is that it makes a list of nested lists so I can't use flatten either
(define (position ls ele n)
(cond [(empty? ls) 0]
[(equal? ele (first ls)) (list n (position (rest ls) ele (add1 n))) ]
[else (position (rest ls) ele (+ 1 n))]))]
;lol-full? checks if the item occurs in the list of lists at all
(if (lol-full? b) b (rewrite (flatten b)
(position (flatten b) '- 0)
"item replaced"))))
;just used for testing
(define lol2 (list
(list 2 2 2 2)
(list 4 '- 4 '-)
(list '- 8 8 8)
(list 16 '- '- 16)))
(fullreplace lol2) may return this or where any of the other '- are located:
(list
(list 2 2 2 2)
(list 4 '- 4 2)
(list '- 8 8 8)
(list 16 '- '- 16))
I've been working on this awhile so any new insight would go a long way. Thank you
The "random" part is what makes this problem pathological. If you could just replace the first occurrence, it would be easy. But to replace a random occurence, you must first know how many occurrences there are. So before you go replacing stuff, you have to go a-counting:
(define (count/recursive val tree)
(cond ((equal? val tree)
1)
(else (foldl (λ (next-value total)
(cond ((equal? val next-value)
(add1 total))
((list? next-value)
(+ total (count/recursive val next-value)))
(else total))) 0 tree))))
Then you need a function that can replace the nth occurrence of a value:
(define (replace/recursive val replace-with n tree)
(cond ((equal? val tree)
replace-with)
(else
(cdr
(foldl (λ (next-value total/output-tree)
(local ((define total (car total/output-tree))
(define output-tree (cdr total/output-tree)))
(cond ((equal? next-value val)
(cons (add1 total)
(cons (if (= total n) replace-with next-value) output-tree)))
((list? next-value)
(cons (+ total (count/recursive val next-value))
(cons (replace/recursive val replace-with (- n total) next-value)
output-tree)))
(else (cons total (cons next-value output-tree)))))) (cons 0 empty) tree)))))
Finally, you use random to pick the instance you will replace, using count/recursive to limit how high of a number random picks:
(define original '((x x (x y x) a b (((c x z x) x) y x x))))
(replace/recursive 'x '- (random (count/recursive 'x original)) original)
How to replace all occurences of a value with another value:
(define (replace-all needle new-value haystack)
(cond ((equal? needle haystack) new-value)
((pair? haystack)
(cons (replace-all needle new-value (car haystack))
(replace-all needle new-value (cdr haystack))))
(else haystack)))
The only thing to change is to check if the first part constituted a change. If it did you don't do the replace on the other half. Use equal? to compare structure.
It's not random. It will replace the first occurence it finds either by doing car before cdr or cdr before car.

count duplicate value in a tree scheme

i'm attempting to count duplicate in a tree. i'm attaching a picture for a better illustration. I'm on the wrong track i have no where to go.
Here is what i did
(define (arbre-insere valeur arbre)
(cond ((null? arbre) (list (cons valeur 1) '() '()))
((< valeur(car arbre))
(list (cons (car arbre) count)
(arbre-insere valeur (cadr arbre))
(caddr arbre)))
(> valeur(car arbre) (list cons ((car arbre) count) (cadr arbre)
(arbre-insere valeur (caddr arbre) )))
(else
)
))][1]
Here is a sketch, where ... and stuff in <...> is meant to be filled out by you.
(define leaf '())
; leaf? : tree -> boolean
; return #t if the tree is a leaf,
; #f otherwise
(define (leaf? tree)
(null? leaf?))
; value : tree -> element
; return the root element of the tree
(define (value tree)
...)
; count : tree -> integer
; return the count of the root element of tree
(define (count tree)
...)
; left : tree -> tree
; return the left subtree of tree
(define (left tree)
...)
; right : tree -> tree
; return the right subtree of tree
(define (right tree)
...)
; make-node : value integer tree tree
; construct tree from a value and count,
; left is a tree whose elements are smaller than value
; right is a tree whose elements are greater than value
(define (make-node value count left right)
(list left (cons value count) right))
; tree-insert : value tree -> tree
(define (tree-insert v t)
(cond
[(leaf? t) (make-tree v 1 leaf leaf)]
[(= v (value t)) (make-tree v <old-count+1> (left t) (right t))]
[(< v (value t)) (make-tree v (make-node (value t) (count t)
(insert-tree v (left t)) r))]
[(> v (value t)) <???>]
[else (error 'tree-insert "an unexpected error occurred")]))

maximum value of a tree scheme

I want to get the maximum value of a tree
I have this:
define (dato-tree nodo)
(first nodo))
(define (left-tree nodo)
(first (rest nodo)))
(define (right-tree nodo)
(first (rest (rest nodo))))
(define maximum
(lambda (arbol)
(if (eqv? (right-tree arbol) #f)
arbol
(maximum (right-tree arbol)))))
and run it:
(define tree (list 5 (list 2 (list 1 empty empty) empty) (list 7 empty empty)))
(maximum tree)
gives me this error:
rest: expects a non-empty list; given: empty
how could it?
If the tree is a sorted binary tree as suggested in your previous question, you only have to consider the right branches and find the value of the last node:
(define (maximum arbol (m #f))
(if (empty? arbol)
m
(maximum (right-tree arbol) (dato-tree arbol))))
then
> (maximum tree)
7
and you can even specify the value you want to be returned for an empty tree:
> (maximum empty)
#f
> (maximum empty 'empty)
'empty
> (maximum empty empty)
'()
Otherwise I would go for:
(define (cons2 atom lst)
(if atom (cons atom lst) lst))
(define (maximum arbol)
(if (empty? arbol)
#f
(apply max
(cons2 (maximum (left-tree arbol))
(cons2 (maximum (right-tree arbol))
(list (dato-tree arbol)))))))
where cons2 is a procedure that conses the atom only if it is not #f:
> (cons2 1 '(2))
'(1 2)
> (cons2 #f '(2))
'(2)
and comes in handy in procedure maximumto prevent testing if the maximum for a sub-tree is empty:
> (maximum tree)
7
> (maximum empty)
#f

Find a list of items in a binary tree structures scheme

Write a function in Scheme that receives as argument of entry a binary search tree of instances of the student structure
, a list of birth years and returns a list of list of codes that indicate which birth dates are provided each year.
example:
This is the binary tree
(make-árbol-bin
(make-estudiante 5 "35889188" "Victor" (make-fecha 10 6 1991) "calle 67 con cra 20" "4444444") (make-
árbol-bin
(make-estudiante 2 "6457234" "Manuel" (make-fecha 12 10 1992) "calle 56 con cra 33" "5555555") (make-árbol-bin
(make-estudiante 1 "94252688" "Estela" (make-fecha 20 5 1993) "calle 4 con cra 2" "3333333") empty empty) empty)
(make-árbol-bin
(make-estudiante 7 "34987678" "Juan" (make-fecha 25 3 1995) "calle 34 con cra 12" "6666666") empty
empty)
)
List years
(list 1992 1991 )
It should return a list of lists of codes:
((list (list 2) (list 5) )
and I did this but I can not make me return the list of the list
(define-struct fecha ( dia mes año))
This is the structure of the student:
(define-struct estudiante ( codigo id nombre fechanaci direccion telefono))
This is the structure of the binary search tree:
(define-struct arbol-bin( estudiante nod-izq nod-der))
I did this
(define (elimina X L)
(if(null? L) '()
(if (equal? X (car L))
(elimina X (cdr L))
(cons (car L) (elimina X (cdr L))))))
(define (busca d tree)
(if (null? tree)
#f
(let ((node (arbol-bin-estudiante tree)))
(let ((n (estudiante-codigo node)))
(let ((fe (estudiante-fechanaci node)))
(if (or(equal? d (fecha-año fe))
(busca d (arbol-bin-nod-der tree)))
n
(busca d (arbol-bin-nod-izq tree))))))))
(define (pert lst tree)
(elimina false (map (lambda (d) (busca d tree)) lst)))
and this
(pert (list 1992 1991 ) tree)
return
(list 2 5)
As I can do to make me return this:
((list (list 2) (list 5) )
help me please!
You cannot make it return ((list (list 2) (list 5))), because that's not a correct Scheme expression. You can make it return (list (list 2) (list 5)) though:
> (list (list 2) (list 5))
'((2) (5))
To do so, in busca, just replace n with (list n):
(define (busca d tree)
(if (null? tree)
#f
(let ((node (árbol-bin-estudiante tree)))
(let ((n (estudiante-codigo node)))
(let ((fe (estudiante-fechanaci node)))
(if (or (equal? d (fecha-año fe))
(busca d (árbol-bin-nod-der tree)))
(list n) ; <------
(busca d (árbol-bin-nod-izq tree))))))))
or
> (list (list (list 2) (list 5)))
'(((2) (5)))
by changing the above line to (list (list n)).

Resources