I need to create a function that filters out predicates in Scheme. For example (filter-out number? '(a 2 #f b 7)): the output would be (a #f b)
The function that I have returns a list of what was filtered out. How can I change this to get what I need? Thanks
(define (filter pred lst)
(reverse (filter-help pred lst '())))
(define (filter-help pred lst res)
(cond ((null? lst) res)
((pred (car lst))
(filter-help pred (cdr lst) (cons (car lst) res)))
(else
(filter-help pred (cdr lst) res))))
Your functions work if you just negate the predicate on one line of filter-help (and change the name filter to filter-out as intended):
(not (pred (car lst)))
instead of
((pred (car lst))
Though you could write this more briefly by using the built-in filter with a lambda function:
(define (alt-filter-out pred lst)
(filter (lambda (x) (not (pred x))) lst))
Hope this helps!
Related
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)
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)))))
I'm trying to implement a quick sort using scheme, some dudes here already helped me fixing my split function and now I'm asking for you help with combining everything into one working algorithm.
Here is my code so far:
(define quick-sort (lambda (lst)
(define pivot (lambda (lst)
(if (null? lst)
null
(car lst))))
(define split (lambda (lst pivot)
(define lst1 null)
(define lst2 null)
(define split-helper (lambda (lst pivot lst1 lst2)
(if (null? lst)
(list lst1 lst2)
(if (<= (car lst) pivot)
(split-helper (cdr lst) pivot (cons (car lst) lst1) lst2)
(split-helper (cdr lst) pivot lst1 (cons (car lst) lst2))))))
(split-helper lst pivot lst1 lst2)))
(if (null? lst)
null
(append (quick-sort (car (split lst (pivot lst)))) (quick-sort (cdr (split lst (pivot lst))))))))
As you can see, I'm choosing the pivot to simply be the first element in the list, the problem I'm facing is that the program ran into an infinite loop when the pivot is the smallest element in the list because it makes the program choose the same pivot over and over.
Also, the way it's currently implemented makes it be really un-efficient because the split function is called twice with the same lst in every ineration of quick-sort but I just don't have good enough control over Scheme to write it any other way.
I saw some posts about Quick-Sort in Scheme but they were implemented a bit different and I rather try and correct my own implementation than copying some other dude's work.
Thank you.
This is a classical mistake when it comes to quicksort. Your pivot should not be a part of the partitions. That way a one element list makes two empty partitions, one before and one after the pivot.
As for doing the same operation twice. Use let to buffer the split result and use the variable twice.
Removed excessive lambdas, aliases, bindings, and reformatted, but didn't change or annotate semantics (Sylwester already pointed out the bug):
(define (quick-sort lst)
(define (pivot lst)
(if (null? lst)
'()
(car lst) ))
(define (split lst pivot)
(let split-helper ((lst lst) ; Named let instead of internal
(lst1 '()) ; definition
(lst2 '()) )
(if (null? lst)
(cons lst1 list2)
(if (<= (car lst) pivot)
(split-helper (cdr lst)
(cons (car lst) lst1)
lst2)
(split-helper (cdr lst)
lst1
(cons (car lst) lst2) )))))
(if (null? lst)
'()
(let ((spl (split lst (pivot lst)))) ; Memoization of the `split`
(append (quick-sort (car spl))
(quick-sort (cdr spl)) ))))
I think you're trying to implement a partition:
(define (partition pred xs)
(let part ((ps '()) (ns '()) ; Initial "positives" `ps`, and "negatives" `ns`
(xs' xs) )
(if (null? xs')
(cons ps ns) ; Returning pair of lists
(let ((x (car xs'))) ; Memoization of `(car lst)`
(if (pred x)
(part (cons x ps) ns (cdr xs'))
(part ps (cons x ns) (cdr xs')) )))))
(define (quicksort xs)
(if (null? xs) '()
(let* ((x (car xs))
(pn (partition ; Memoization of `partition`
(lambda (x')
(< x' x) )
(cdr xs) )))
(append (quicksort (car pn)) ; Extracting positives from pair
(list x) ; Pivot
(quicksort (cdr pn)) )))) ; Negatives
(display
(quicksort (list 4 2 3 5 1)) ) ; (1 2 3 4 5)
part is inefficient in strict languages like Scheme; it copies all three of its arguments for every recursive step. Often, straightforward formulations in terms of basic folds like filter and map are most efficient. A much more efficient implementation using filter:
(define (quicksort xs)
(if (null? xs) '()
(let ((x (car xs))
(xs' (cdr xs)) )
(append (quicksort
(filter (lambda (x')
(< x' x) )
xs'))
(list x)
(quicksort
(filter (lambda (x')
(>= x' x) )
xs'))))))
This strategy famously happens to be very briefly expressible in functional languages.
In lazy Haskell, a single-traversal partition is actually more efficient than filtering twice.
select :: (a -> Bool) -> ([a], [a]) -> a -> ([a], [a])
select pred (ps, ns) x | pred x = (x : ps, ns)
| otherwise = (ps, x : ns)
partition :: (a -> Bool) -> [a] -> ([a], [a])
partition pred = foldl (select pred) ([], [])
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (x : xs) = let (lt, gt) = partition (< x) xs
in quicksort lt ++ [x] ++ quicksort gt
I have a requirement to return the last negative number in a list, using a recursive procedure. Right now I have a recursive procedure that returns all negative numbers in the list.
(define returnLastNeg
(lambda (lst)
(if (null? lst)
'()
(if (positive? (car lst))
(returnLastNeg (cdr lst))
(cons (car lst) (returnLastNeg (cdr lst)))))))
calling it with (returnLastNeg'(1 -2 -3 4 -5 6)) returns
Output:
'(-2 -3 -5)
I need it to only return -5 though. I tried to modify my procedure to check to see if the last element in the list is positive. If it is, I want to remove the last element and then call the procedure again. But when I do that I get an error (below)
Modified procedure:
(define returnLastNeg-modified
(lambda (lst)
(if (null? lst)
'()
(if (positive? (last lst))
(remove (last lst) (lst))
(cons (car lst) (returnLastNeg-modified (cdr lst)))))))
ERROR:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 -2 -3 4 -5 6)
arguments...: [none]
>
A simpler approach would be with a helper procedure (called "sub") in this example:
(define returnLastNeg
(lambda (lst)
(define sub
(lambda (lst last-neg)
(if (null? lst)
last-neg
(let ((c (car lst)))
(sub (cdr lst)
(if (negative? c) c last-neg))))))
(sub lst null)))
EDIT
Knowing that
(define <procedureName> (lambda (<params>) ... )
is the same as
(define (<procedureName> <params>) ... )
and reformatting a little, this becomes:
(define (returnLastNeg lst)
(define (sub lst last-neg)
(if (null? lst)
last-neg
(let ((c (car lst)))
(sub (cdr lst) (if (negative? c) c last-neg)))))
(sub lst null))
I hope it's clearer
last-neg gets set to null by the very last expression
the recursive call to sub has 2 parameters (split on 2 lines in the initial version, but newlines don't matter).
This is the same as the even shorter version
(define (returnLastNeg lst)
(let sub ((lst lst) (last-neg null))
(if (null? lst)
last-neg
(let ((c (car lst)))
(sub (cdr lst) (if (negative? c) c last-neg))))))
using a so-called "named let".
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)))))))