Sort an element and put it in a variable - recursion

I have fowling task:
Write a recursive function SORT-LIST which, from a list of any number of "apples" and "peas", sorts out the "apples" and stores them in an optional variable and at the end returns the contents of this optional variable.
I have no idea how to fix ist. That's my beginning. Maybe there is someone who could help me. Thanks a lot!!
(defun sort-list (x l)
(cond ((null l) nil))
((equal (first l) x)
(cons (first l) (sort-list x (rest l))))
((sort-list x (rest l))))

The name is misleading. It is not sort but actually a filter.
(defun applep (x)
"something looking whether x is an apple or not")
(defun my-filter (pred l &optionals (acc '()))
(cond ((null l) (nreverse acc))
((funcall pred (car l)) (my-filter pred (cdr l) (cons (car l) acc)))
(t (my-filter pred (cdr l) acc))))
Which is in-built in lisps - so even without defining it, you could run:
(filter #'applep l)

Related

Why is this function returning true when it should be returning false?

So, I have this helper function that checks to see if there is a reflexive relationship between a list and a list of pairs.
(define helper
(lambda (L S)
(cond
((if (equal? L '()) #f ;; here, when L equals empty list, it should return #f, but somehow it returns #t even if L is '().
(if (equal? S (car (car L)))
(if (list-equal? (car L))#t
(helper (cdr L) S))
(helper (cdr L) S))))
)))
However, the part where it checks if L is an empty list returns true even if the list is an empty list, allowing my other function to return true.
I've been stumped trying to figure out why its returning #t instead of #f for hours. Please help me figure out what's making this happen.
Oh and I'm using Dr.Racket version 6.12.
EDIT: more clearly, I would like the function to return #f when L is '() as a base case so that the function doesn't need to do anymore recursion.
You put if forms within cond which is quite superfluous.
So your mistake was for sure your lack of understanding of the cond syntax.
Remember cond syntax goes like:
(cond (condition1 what-to-do-if-condition1-is-true)
(condition2 what-to-do-if-condition2-is-true)
( ... ... )
(else what-to-do-if-none-of-the-conditions-listed-above-evaluated-to-true))
So I formed your expression accordingly to:
(define helper
(lambda (L S)
(cond ((equal? L '()) #f)
((and (equal? S (car (car L))) (list-equal? (car L))) #t)
(else (helper (cdr L) S)))))
Since you didn't gave definition for list-equal? - I cannot run this code for testing.
You have nested if in cond. Lets rewrite you code som something identical:
(define helper
(lambda (L S)
(let ((result
(if (equal? L '())
#f
(if (equal? S (car (car L)))
(if (list-equal? (car L))
#t
(helper (cdr L) S))
(helper (cdr L) S)))))
(cond
(result result)
(else 'implementation-defined-value)))))
A cond will return a implementation defined value as the else clause should none of the previous predicates hit. Since your base casse returns #f it goes to the default else case.
Since the other answer show the code with cond, here is the same with if:
(define helper
(lambda (L S)
(if (equal? L '())
#f
(if (and (equal? S (car (car L)))
(list-equal? (car L)))
#t
(helper (cdr L) S)))))
You can also write this only with and and or:
(define helper
(lambda (L S)
(and (pair? L)
(or (and (equal? S (car (car L)))
(list-equal? (car L)))
(helper (cdr L) S)))))

Scheme - Recursive cases

I'm finishing up a Scheme assignment and I'm having some trouble with the recursive cases for two functions.
The first function is a running-sums function which takes in a list and returns a list of the running sums i.e (summer '(1 2 3)) ---> (1 3 6) Now I believe I'm very close but can't quite figure out how to fix my case. Currently I have
(define (summer L)
(cond ((null? L) '())
((null? (cdr L)) '())
(else (cons (car L) (+ (car L) (cadr L))))))
I know I need to recursively call summer, but I'm confused on how to put the recursive call in there.
Secondly, I'm writing a function which counts the occurrences of an element in a list. This function works fine through using a helper function but it creates duplicate pairs.
(define (counts L)
(cond ((null? L) '())
(else (cons (cons (car L) (countEle L (car L))) (counts (cdr L))))))
(define (countEle L x)
(if (null? L) 0
(if (eq? x (car L)) (+ 1 (countEle (cdr L) x)) (countEle (cdr L) x))))
The expected output is:
(counts '(a b c c b b)) --> '((a 1) (b 3) ( c 2))
But it's currently returning '((a . 1) (b . 3) (c . 2) (c . 1) (b . 2) (b . 1)). So it's close; I'm just not sure how to handle checking if I've already counted the element.
Any help is appreciated, thank you!
To have a running sum, you need in some way to keep track of the last sum. So some procedure should have two arguments: the rest of the list to sum (which may be the whole list) and the sum so far.
(define (running-sum L)
(define (rs l s)
...)
(rs L 0))
For the second procedure you want to do something like
(define (count-elems L)
(define (remove-elem e L) ...)
(define (count-single e L) ...)
(if (null? L)
'()
(let ((this-element (car L)))
(cons (list this-element (count-single this-element L))
(count-elems (remove-elem this-element (cdr L)))))))
Be sure to remove the elements you've counted before continuing! I think you can fill in the rest.
To your first problem:
The mistake in your procedure is, that there is no recursive call of "summer". Have a look at the last line.
(else (cons (car L) (+ (car L) (cadr L))))))
Here is the complete solution:
(define (summer LL)
(define (loop sum LL)
(if (null? LL)
'()
(cons (+ sum (car LL)) (loop (+ sum (car ll)) (cdr LL)))))
(loop 0 LL))

Return value in Lisp

So i started learning Lisp yesterday and started doing some problems.
Something I'm having a hard time doing is inserting/deleting atoms in a list while keeping the list the same ex: (delete 'b '(g a (b) l)) will give me (g a () l).
Also something I'm having trouble with is this problem.
I'm suppose to check if anywhere in the list the atom exist.
I traced through it and it says it returns T at one point, but then gets overriden by a nil.
Can you guys help :)?
I'm using (appear-anywhere 'a '((b c) g ((a))))
at the 4th function call it returns T but then becomes nil.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Let's look at one obvious problem:
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Think about the last line of above.
Let's format it slightly differently.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T
(appear-anywhere a (car l))
(appear-anywhere a (cdr l)))))
The last three lines: So as a default (that's why the T is there) the last two forms will be computed. First the first one and then the second one. The value of the first form is never used or returned.
That's probably not what you want.
Currently your code just returns something when the value of a appears anywhere in the rest of the list. The first form is never really used.
Hint: What is the right logical connector?

need to combine results of two functions in Scheme with a driver

I have a Scheme assignment in which a user is to input a list of numbers, and the output should be the max value and min value from the list. The assignment says we can have two separate functions, and combine the result with a driver, but I don't know how to do this. Here is what I have so far:
(define (findmin l) (if (null? (cdr l)) (car l)
(if (< (car l) (findmin (cdr l)))(car l)
(findmin (cdr l)))))
(define (findmax l) (if (null? (cdr l)) (car l)
(if (> (car l) (findmax (cdr l)))(car l)
(findmax (cdr l)))))
I can't seem to get around having to input a list for findmin, and another list for findmax. The user should only have to input one list.
driver:
(define (min-and-max l) (list (findmin l) (findmax l)))

homework on scheme

how to design a function content which
inputs a single list of atoms lat and which returns
the content of lat.Thus the content of '(a b c a b c d d) is '(a b c d).
The procedure content below should get you what you need.
(define (work x y)
(if (null? (cdr x))
(if (in? (car x) y)
y
(cons (car x) y))
(if (in? (car x) y)
(work (cdr x) y)
(work (cdr x) (cons (car x) y)))))
(define (in? x y)
(if (null? y)
#f
(if (equal? x (car y))
#t
(in? x (cdr y)))))
(define (content x) (work x (list)))
The procedure content accepts a list as a parameter. It sends the list to another procedure called work. This procedure processes the list and adds the items in the list to a new list (if they are not already in the new list). The work procedure makes use of yet another procedure called in, which checks to see if an item is a member of a list.
My solution essentially divides your problem into two sub-problems and makes use of procedures which operate at a lower level of abstraction than your original problem.
Hope that helps.
It is PLT Scheme solution:
(define (is_exists list element)
(cond
[(empty? list) false]
[else
(cond
[(= (first list) element) true]
[else (is_exists (rest list) element)])]))
(define (unique list target)
(cond
[(empty? list) target]
[else
(cond
[(is_exists target (first list)) (unique (rest list) target)]
[else (unique (rest list) (cons (first list) target))])]))
(define (create_unique list)
(unique list empty))
Check it:
> (define my_list (cons '1 (cons '2 (cons '3 (cons '2 (cons '1 empty))))))
> my_list
(list 1 2 3 2 1)
> (create_unique my_list)
(list 3 2 1)
How about little schemer style,
(define (rember-all a lat)
(cond
((null? lat) '())
((eq? a (car lat)) (rember-all a (cdr lat)))
(else (cons (car lat) (rember-all a (cdr lat))))))
(define (content lat)
(cond
((null? lat) '())
(else (cons (car lat)
(content (rember-all (car lat) (cdr lat)))))))
Start from a procedure that simply creates a copy of the passed-in list (very easy to do):
(define (unique-elements seq)
(define (loop ans rest)
(cond ((null? rest) ans)
(else
(loop (cons (car rest) ans)
(cdr rest)))))
(loop '() seq))
To ensure that the output list's elements are unique, we should skip the CONS if the head of REST is already a member of ANS. So we add another condition to do just that:
;;; Create list containing elements of SEQ, discarding duplicates.
(define (unique-elements seq)
(define (loop ans rest)
(cond ((null? rest) ans)
((member (car rest) ans) ; *new*
(loop ans (cdr rest))) ; *new*
(else
(loop (cons (car rest) ans)
(cdr rest)))))
(loop '() seq))
The following function takes in a list and returns a new list with only the unique inputs of it's argument using recursion:
(defun uniq (list)
(labels ((next (lst new)
(if (null lst)
new
(if (member (car lst) new)
(next (cdr lst) new)
(next (cdr lst) (cons (car lst) new))))))
(next list ())))
As was mentioned in the comments, common lisp already has this function:
(defun uniq (list)
(remove-duplicates list))
(define (remove-duplicates aloc)
(cond
((empty? aloc) '())
(else (cons (first aloc)
(remove-duplicates
(filter (lambda (x)
(cond
((eq? x (first aloc)) #f)
(else #t)))
(rest aloc)))))))

Resources