Questions about LISP - lisp

I am learning LISP by using Racket!
I have problem in solving these three question.
1) (banana in (Jane has a backyard))
2) (banana and Jane)
3) (((banana) and ((Jane))) in her backyard)
In the form of the list above, how can I get only Jane? (using car/cdr)

Go to the Interactions window in DrRacket and play around with applying various combinations of car and cdr to each list.
Example:
> (car '(banana in (Jane has a backyard)))
'banana
> (cdr '(banana in (Jane has a backyard)))
'(in (Jane has a backyard))
> (car (cdr '(banana in (Jane has a backyard))))
'in
> (cdr (cdr '(banana in (Jane has a backyard))))
'((Jane has a backyard))
> (cdr (cdr (cdr '(banana in (Jane has a backyard)))))
'()
> (car (cdr (cdr '(banana in (Jane has a backyard)))))
'(Jane has a backyard)
I'm pretty sure that you can take over from here...

Related

Delete element from a nested list while keeping the original nested structure CLISP [duplicate]

I've got a homework assignment that has stumped me! I have to create a function goo(A L) that will remove every A in L and it has to work on nested lists also.
Here's what I've got so far
(defun goo(A L)
(cond ((null L) nil) ; if list is null, return nil
(T ; else list is not null
(cond ((atom (car L))) ;if car L is an atom
((cond ((equal A (car L)) (goo A (cdr L))) ;if car L = A, call goo A cdr L
(T (cons (car L) (goo A (cdr L)))))) ;if car L != A,
(T (cons (goo A (car L)) (goo A (cdr L)))))) ;else car L is not atom, call goo on car L and call goo on cdr L
))
This function returns True no matter what I give it.
You parens are messed up. Move the last paren around (atom (car L)) to include the next cond expression. I suggest using an IDE which shows matching parens.
As for styling, if you didn't know, cond can accept multiple clauses. This way you don't need to have the t and then the cond again. You can also use 'if' if you are only testing a single predicate and making a decision based solely on that.
Note: this was originally posted as an edit to the question by the original asker in revision 2.
I tried another approach and it's working now.
(defun goo(A L)
(cond ((null L) nil)
((atom (car L)) (cond ((equal A (car L)) (goo A (cdr L)))
(T (cons (car L) (goo A (cdr L))))))
(T (cons (goo A (car L)) (goo A (cdr L))))
))
Note 2: this should conventionally be formatted like this to show the program structure:
(defun goo (a l)
(cond ((null l) nil)
((atom (car l))
(cond ((equal a (car l))
(goo a (cdr l)))
(t (cons (car l)
(goo a (cdr l))))))
(t (cons (goo a (car l))
(goo a (cdr l))))))
I think it might be easier to look at this a replacement into trees problem. It's easy to define a function that takes a tree and replaces subtrees in it that satisfy a test. There's a standard function subst-if that does that, but it replaces every matching subtree with the same thing. It will be more useful to us if we replace the element with a value computed from the subtree:
(defun %subst-if (new test tree)
"Replace subtrees of TREE that satisfy TEST with the result
of calling NEW with the subtree."
(cond
;; If tree satifies the test, return (new tree).
((funcall test tree)
(funcall new tree))
;; If tree is a cons, recurse.
((consp tree)
(cons (%subst-if new test (car tree))
(%subst-if new test (cdr tree))))
;; Otherwise, just return the leaf.
(tree)))
With this, its easy to define the kind of function we need. When an element X appears somewhere in a nested list structure, it means that there is a cons cell whose car is X. We want to replace that cons cell with its cdr, but to also recurse on the cdr of the cell. This isn't hard:
(defun replace* (x list &key (test 'eql))
"Remove occurrences of X in LIST and its sublists."
(%subst-if
(lambda (cons)
"Replace elements of the form (X . more) with
(replace* x more :test test)."
(replace* x (cdr cons) :test test))
(lambda (subtree)
"Detect subtrees of the form (X . more)."
(and (consp subtree)
(funcall test x (car subtree))))
list))
(replace* 'a '(1 a (2 a 3) a 4 a 5))
;=> (1 (2 3) 4 5)

In MIT Scheme, What is the difference between (null? lst) and (null? (cdr lst))?

I am currently going through SICP and I am having a hard time understanding the difference between the two expressions below. Assume we have a list, called lst, What is the difference between:
(null? lst) and (null? (cdr lst))
I know that the first expression checks if the list is empty. But doesn't the second expression check for the same condition as well? In other words checks if the rest of the list is empty.
No, they are no the same thing, (null? lst) just checks whether lst is empty or not. Whereas(null? (cdr lst)) checks whether lst has only one element, since (cdr lst) returns lst with everything but the first element. See examples below.
> (null? '())
#t
> (null? '(1))
#f
> (null? (cdr '(1)))
#t
> (null? (cdr '(1 2)))
#f

Removing from nested lists

I've got a homework assignment that has stumped me! I have to create a function goo(A L) that will remove every A in L and it has to work on nested lists also.
Here's what I've got so far
(defun goo(A L)
(cond ((null L) nil) ; if list is null, return nil
(T ; else list is not null
(cond ((atom (car L))) ;if car L is an atom
((cond ((equal A (car L)) (goo A (cdr L))) ;if car L = A, call goo A cdr L
(T (cons (car L) (goo A (cdr L)))))) ;if car L != A,
(T (cons (goo A (car L)) (goo A (cdr L)))))) ;else car L is not atom, call goo on car L and call goo on cdr L
))
This function returns True no matter what I give it.
You parens are messed up. Move the last paren around (atom (car L)) to include the next cond expression. I suggest using an IDE which shows matching parens.
As for styling, if you didn't know, cond can accept multiple clauses. This way you don't need to have the t and then the cond again. You can also use 'if' if you are only testing a single predicate and making a decision based solely on that.
Note: this was originally posted as an edit to the question by the original asker in revision 2.
I tried another approach and it's working now.
(defun goo(A L)
(cond ((null L) nil)
((atom (car L)) (cond ((equal A (car L)) (goo A (cdr L)))
(T (cons (car L) (goo A (cdr L))))))
(T (cons (goo A (car L)) (goo A (cdr L))))
))
Note 2: this should conventionally be formatted like this to show the program structure:
(defun goo (a l)
(cond ((null l) nil)
((atom (car l))
(cond ((equal a (car l))
(goo a (cdr l)))
(t (cons (car l)
(goo a (cdr l))))))
(t (cons (goo a (car l))
(goo a (cdr l))))))
I think it might be easier to look at this a replacement into trees problem. It's easy to define a function that takes a tree and replaces subtrees in it that satisfy a test. There's a standard function subst-if that does that, but it replaces every matching subtree with the same thing. It will be more useful to us if we replace the element with a value computed from the subtree:
(defun %subst-if (new test tree)
"Replace subtrees of TREE that satisfy TEST with the result
of calling NEW with the subtree."
(cond
;; If tree satifies the test, return (new tree).
((funcall test tree)
(funcall new tree))
;; If tree is a cons, recurse.
((consp tree)
(cons (%subst-if new test (car tree))
(%subst-if new test (cdr tree))))
;; Otherwise, just return the leaf.
(tree)))
With this, its easy to define the kind of function we need. When an element X appears somewhere in a nested list structure, it means that there is a cons cell whose car is X. We want to replace that cons cell with its cdr, but to also recurse on the cdr of the cell. This isn't hard:
(defun replace* (x list &key (test 'eql))
"Remove occurrences of X in LIST and its sublists."
(%subst-if
(lambda (cons)
"Replace elements of the form (X . more) with
(replace* x more :test test)."
(replace* x (cdr cons) :test test))
(lambda (subtree)
"Detect subtrees of the form (X . more)."
(and (consp subtree)
(funcall test x (car subtree))))
list))
(replace* 'a '(1 a (2 a 3) a 4 a 5))
;=> (1 (2 3) 4 5)

Lisp prefix calculator

How can I write a calculator to prefix notation, when it should count this example '(+ * 3 2 - 2 1), where there are no brackets between characters? When I have the brackets, I can handle it, but in this case I am lost.
A quick search on google yielded this wikipedia page, with an implementation (in pseudocode) of prefix evaluation using a stack. It's a starting point for writing your own implementation. Also notice that a stack can be easily implemented using Lisp's linked lists, simply add/remove elements at the head.
I'm a beginner in scheme (excuse me if it is nasty code). This one is with the brackets:
(define (fce a)
(case a
(( + ) +)
(( - ) -)
(( * ) *)
(( / ) /)))
(define (analyze vyraz)
(if (list? vyraz)
(calcul vyraz)
vyraz))
(define (calcul vyraz)
(if (= (length vyraz) 3 )
((fce (car vyraz)) (analyze (cadr vyraz)) (analyze (caddr vyraz)))
(calcul (cons (calcul (list (car vyraz) (cadr vyraz) (caddr vyraz) (cadddr vyraz)))))))
this code can count for example this : (calcul '(- (* 3 2)(+ 1 2))
I wanted to repair this code to code without brackets but conditions and listing the original input stopped me. I do not know how to write the conditions so that I didn't lose the original input and also came the final calculation.
there are my conditions (but i think, there are at wrong syntax
(define (count vyraz)
(cond (list? vyraz)
(number? (car vyraz) (cons (car vyraz)))
(number? (cdr vyraz) (cons (cdr vyraz)))
(symbol? (cddr vyraz) (cons (cddr vyraz)))
(else (cdr vyraz) (count vyraz)))
(calcul vyraz))
Thank you for all your answers and tips :)
(define (polish-notation-eval expr)
(if (finished? expr)
(car expr)
(polish-notation-eval (the-once-over expr))))
;;either we are finished, or we need to make the-once-over to get closer to finished.
(define (the-once-over expr)
(cond ((null? expr) expr )
((well-formed-expr? expr)
(cons ((get-operator (car expr)) (cadr expr) (caddr expr))
(the-once-over (cdddr expr))))
(else (cons (car expr) (the-once-over (cdr expr))))))
;; just scrolls down the list looking for well-formed expressions to evaluate.
(define *the-operations*
(list (list '+ +)
(list '* *)
(list '- -)
(list '/ /)))
;; an association list with names and functions
(define (get-operator name)
(cadr (assoc name *the-operations*)))
;;returns the function that goes with the name
(define (finished? expr)
(= (length expr) 1))
;; we are finished one we get down to a length one list, otherwise not
(define (well-formed-expr? expr)
(and (assoc (car expr) *the-operations*)
(number? (cadr expr))
(number? (caddr expr))))
;;are the next three elements something we can go ahead and evaluate?

Delete element in list that contains lists

beginner in LISP here. I'm preparing myself for my upcoming exam in LISP and I've come across a problem I can't solve, so I was hoping someone more experienced might help me out.
Anyways, here is my problem :
You are given a list that may contain lists as elements. Your task is to delete an atomic element at a given position.
The list and the position are given as input parameters.
Example : Position=5 , List=(1 (2 3) ((4)) (5 (6))) , should return (1 (2 3) ((4)) ((6))).
Here is what i got so far...(PS the code below works thanks to the assistance of imMaw , you can check edit to see my previous mistake ).
(defun number_of_atoms(List)
(atoms List 0)
)
(defun atoms(List Number)
(cond
((null List) Number)
((atom (car List)) (atoms (cdr List) (+ 1 Number)))
((+ (atoms (car List) Number) (atoms (cdr List) 0)))
)
)
(defun deleteElement(Pos List)
(deleteElementAcc Pos 1 List)
)
(defun deleteElementAcc(Pos CurrPos List)
(cond
((null List) nil)
((and (atom (car List)) (not(eql CurrPos Pos))) (cons (car List) (deleteElementAcc Pos (+ CurrPos 1) (cdr List))))
((and (atom (car List)) (eql CurrPos Pos)) (deleteElementAcc Pos (+ CurrPos 1) (cdr List)))
((cons (deleteElementAcc Pos CurrPos (car List))
(deleteElementAcc Pos (+ CurrPos (number_of_atoms(car List))) (cdr List))))
)
)
Why are you spelling Pos and CurrPos with z's in half the places?
And the problem in your code lies in the last branch of the cond. When you recurse on the cdr of List, CurrPos needs to be advanced by the number of elements in (car List). And a simple (length List) won't work, because it needs to recursively count elements in sublists.
Edit: more elaboration
Say we call
(deleteElement 3 '((1 2) (3 4)))
You turn this into
(deleteElementPos 3 1 '((1 2) (3 4))),
which falls into the last case of the cond, and you get
(cons (deleteElementAcc 3 1 '(1 2))
(deleteElementAcc 3 1 '((3 4))))
notice that currPos is wrong for the cdr of the list - it should be 3, not 1. You actually want your code to turn into
(cons (deleteElementAcc 3 1 '(1 2))
(deleteElementAcc 3 (+ 1 2) '((3 4))))
because (car List) has 2 elements in it.
So, you just need to change
(deleteElementAcc Pos CurrPos (cdr List))
into
(deleteElementAcc Pos (+ CurrPos (recursive-length (car List))) (cdr List))
and program recursive-length, which is a pretty simple function. It should count elements in sublists, so for example (recursive-length '((1 2) ((3)))) returns 3.
While solving this problem in just any way isn't particularly difficult, it is really non-trivial to solve it well. By well I mean both big O's and code complexity, just as well as handling of corner cases. I'm not sure this code will handle even improper lists, and it has parts that could be certainly reduced in verbosity, but, technically, it is there. It walks through the tree in exactly O(n), where n is the number of elements in the tree, and it uses O(n + 2 * (maximum depth)) space, i.e. it will use the memory already used by the tree and in addition the memory proportional to the maximum depth of the tree.
No attempt was made to identify cyclic lists or duplicates:
(defun remove-from-tree-linear (tree &rest positions)
(loop with node = tree
with nilcar = (gensym)
with positions = (sort (remove-duplicates positions) #'<)
with counter = 0
with copy = nil
with root = nil
with stack = nil
with backrefs = nil
while (or node stack) do
(cond
((null node)
(setf backrefs (cdr backrefs))
(when (car stack)
(setf copy (car backrefs)))
(setf node (car stack) stack (cdr stack)))
((consp (car node))
(if copy
(if (eq (car copy) nilcar)
(setf (car copy) (list nilcar)
copy (car copy)
(car backrefs) copy)
(setf (cdr copy) (list nilcar)
copy (cdr copy)
(car backrefs) copy))
(setf copy (list nilcar)
root copy))
(setf backrefs (cons copy backrefs))
(setf stack (cons (cdr node) stack)
node (car node)))
(t (if (and positions (= counter (car positions)))
(setf positions (cdr positions))
(if copy
(progn
(if (eq (car copy) nilcar)
(setf (car copy) (list (car node))
copy (car copy))
(setf (cdr copy) (list (car node))
copy (cdr copy)))
(setf (car backrefs) copy))
(setf copy (list (car node))
root copy
backrefs (list copy))))
(setf node (cdr node))))
(incf counter)
finally (return root)))