How to write a scheme function that takes two lists and returns four lists - lisp

I have 2 lists of elements '(a b c) '(d b f) and want to find differences, union, and intersection in one result. Is that possible? How?
I wrote a member function that checks if there is a car of the first list in the second list, but I can't throw a member to the new list.
(define (checkResult lis1 lis2)
(cond...........
))
(checkresult '( a b c) '(d b f))
My result should be (( a c) (d f) (a b c d f) (b)).

Like others have said, all you need to do is create separate functions to compute the intersection, union, and subtraction of the two sets, and call them from checkresult:
(define (checkresult a b)
(list (subtract a b)
(subtract b a)
(union a b)
(intersect a b)))
Here are some example union, intersection, and subtraction functions:
(define (element? x lst)
(cond ((null? lst) #f)
((eq? x (car lst)) #t)
(#t (element? x (cdr lst)))))
(define (union a b)
(cond ((null? b) a)
((element? (car b) a)
(union a (cdr b)))
(#t (union (cons (car b) a) (cdr b)))))
(define (intersect a b)
(if (null? a) '()
(let ((included (element? (car a) b)))
(if (null? (cdr a))
(if included a '())
(if included
(cons (car a) (intersect (cdr a) b))
(intersect (cdr a) b))))))
(define (subtract a b)
(cond ((null? a) '())
((element? (car a) b)
(subtract (cdr a) b))
(#t (cons (car a) (subtract (cdr a) b)))))
Note: since these are sets and order doesn't matter, the results are not sorted. Also, the functions assume that the inputs are sets, and therefore don't do any duplicate checking beyond what's required for union.

Sure it is possible. Assuming that you have function to compute the differences, union intersection etc:
(define (checkResult lis1 list2)
(list (difference lis1 lis2)
(union ...

Sure it's possible. Here are a couple hints:
what's the result of combining a list and an empty list?
You don't have to do it all at once. Take a piece at a time.

On top of Charlie Martin's and tomjen's answers, I have come up with this source:
Union Intersection and Difference
Implementation of the distinct functions can be found with nice explanations.

Related

Lisp: ordered union of two lists

I am trying to make a function that returns the union of two lists in an ordered manner.
Here is my code:
(defun setunion (lst1 lst2)
(cond
((null lst1) lst2)
((null lst2) lst1)
((member (car lst2) lst1)
(setunion lst1 (cdr lst2)))
(t (append (setunion lst1 (cdr lst2))
(list (car lst2))))))
(print (setunion '(a b c) '(a c d e f a)))
This returns (A B C F E D) but the output I am looking for is (A B C D E F). How can I change my code to return the right output?
Thanks!
EDIT: I figured it out I think. I made a helper function that removes the duplicates of list 2 and reverses it as well as remove the duplicates of list 1.
(defun help (lst1 lst2)
(setunion (remove-duplicates lst1 :from-end t) (reverse(remove-duplicates lst2 :from-end t))))
(print (help '(b c b d) '(a d e a)))
This gives me the output (B C D A E) which is what I'm looking for.
OK, so basically all you want to do is remove duplicates over all lists, and the elements should be in order of first appearance. You could append all lists, then remove duplicates from the end:
(defun set-union (&rest lists)
(remove-duplicates (reduce #'append lists)
:from-end t))
If what you want is the union of a bunch of lists such that elements in the lists occur in the order they occur in the lists, working from the left, then here is one fairly natural way of doing that. I'm not sure if this is what I'd write in real life. It has the advantage that:
it's easy to see what is happening;
it doesn't rely on hairy standard CL functions.
It has the disadvantage that it requires tail-call elimination to work with long lists (and some people regard code which works like this not to be idiomatic CL).
(defun union-preserving-order (&rest ls)
;; Union of a bunch of lists. The result will not contain
;; duplicates (under EQL) and elements will occur in the order they
;; occur in the lists, working from the left to the right. So
;; (union-preserving-order '(a b) '(b a c)) will be (a b c), as will
;; (union-preserving-order '(a b) '(c b a)), while
;; (union-preserving-order '(b a) '(a b c) '(c d)) will be (b a c
;; d).
(upo/loop (first ls) (rest ls) '()))
(defun upo/loop (lt more accum)
;; LT is the list we're working on, MORE is more lists for later,
;; ACCUM is the list we're building (backwards). In real life this
;; would be a local function in UNION-PRESERVING-ORDER.
(if (null lt)
;; Finished this list
(if (null more)
;; no more lists: we're done
(nreverse accum)
;; more lists, so pick the first of them and loop on that
(upo/loop (first more) (rest more) accum))
;; not finished this list, so loop on it
(upo/loop (rest lt) more
;; Either the next element of this list is already in
;; the accumulator, or it's not and we need to add it.
(if (member (first lt) accum)
accum
(cons (first lt) accum)))))
Here's a version which uses explicit iteration but otherwise does the same trick.
(defun union-preserving-order (&rest ls)
;; Union of a bunch of lists. The result will not contain
;; duplicates (under EQL) and elements will occur in the order they
;; occur in the lists, working from the left to the right. So
;; (union-preserving-order '(a b) '(b a c)) will be (a b c), as will
;; (union-preserving-order '(a b) '(c b a)), while
;; (union-preserving-order '(b a) '(a b c) '(c d)) will be (b a c
;; d).
(let ((accum '()))
(dolist (l ls (nreverse accum))
(dolist (e l)
(pushnew e accum)))))
Finally here's a dirty hack which builds the results forwards. Without proof I think this is as good as you can do in terms of performance without resorting to some clever lookup structure like a hash-table to check whether you've seen elements already.
(defun union-preserving-order (&rest ls)
;; Union of a bunch of lists. The result will not contain
;; duplicates (under EQL) and elements will occur in the order they
;; occur in the lists, working from the left to the right. So
;; (union-preserving-order '(a b) '(b a c)) will be (a b c), as will
;; (union-preserving-order '(a b) '(c b a)), while
;; (union-preserving-order '(b a) '(a b c) '(c d)) will be (b a c
;; d).
(let ((results '()) ;results we'll return
(rlc nil)) ;last cons of results
(dolist (l ls results)
(dolist (e l)
(unless (member e results)
(if (not (null rlc))
(setf (cdr rlc) (list e)
rlc (cdr rlc))
(setf rlc (list e)
results rlc)))))))

How the map function implemeted in racket

How does the map function implemented in racket and why, recursion or iteration.
Maybe some implementation example
How to implement map
The map function walks a list (or multiple lists), and applies a given function to every value of a list. For example mappiing add1 to a list results in:
> (map add1 '(1 2 3 4))
'(2 3 4 5)
As such, you can implement map as a recursive function:
(define (map func lst)
(if (empty? lst)
'()
(cons (func (first lst)) (map func (rest lst)))))
Of course, map can accept any number of arguments, with each element passed to the given prop. For example, you can zip two lists together using map list:
> (map list '(1 2 3) '(a b c))
'((1 a) (2 b) (3 c))
To implement this variable arity map, we need to make use of the apply function:
(define (map proc lst . lst*)
(if (empty? lst)
'()
(cons (apply proc (first lst) (map first lst*))
(apply map proc (rest lst) (map rest lst*)))))
Now, this does assume all of the given lists have the same length, otherwise you will get some unexpected behavior. To do that right you would want to run empty? on all lists, not just the first one. But...when you use it, you get:
> (map list '(a b c) '(1 2 3))
'((a 1) (b 2) (c 3))
Note that map here calls itself recursively 3 times. A faster implementation might do some unrolling to run faster. A better implementation would also do proper error checking, which I have elided for this example.
How Racket's map is implemented
If you open up DrRacket (using the latest Racket 7 nightly) and make the following file:
#lang racket
map
You can now right click on map and select Open Defining File. From here, you can see that map is renamed from the definition map2. The definition of which is:
(define map2
(let ([map
(case-lambda
[(f l)
(if (or-unsafe (and (procedure? f)
(procedure-arity-includes? f 1)
(list? l)))
(let loop ([l l])
(cond
[(null? l) null]
[else
(let ([r (cdr l)]) ; so `l` is not necessarily retained during `f`
(cons (f (car l)) (loop r)))]))
(gen-map f (list l)))]
[(f l1 l2)
(if (or-unsafe
(and (procedure? f)
(procedure-arity-includes? f 2)
(list? l1)
(list? l2)
(= (length l1) (length l2))))
(let loop ([l1 l1] [l2 l2])
(cond
[(null? l1) null]
[else
(let ([r1 (cdr l1)]
[r2 (cdr l2)])
(cons (f (car l1) (car l2))
(loop r1 r2)))]))
(gen-map f (list l1 l2)))]
[(f l . args) (gen-map f (cons l args))])])
map))

Implement every, some in Lisp [duplicate]

I want a predicate as a parameter of a function.
(DEFUN per (F L)
(cond ((F L) 'working)
(T 'anything)))
(per 'numberp 3)
as result it raises an error:
Undefined operator F in form (F L).
As explained in Technical Issues of Separation in Function Cells and Value Cells,
Common Lisp is a Lisp-2, i.e., you
need funcall:
(defun per (F L)
(if (funcall F L)
'working
'other))
(per #'numberp 3)
==> WORKING
(per #'numberp "3")
==> OTHER
See also apply.
Late to the party, but here's another example:
(defun strip-predicate (p list)
(cond ((endp list) nil)
((funcall p (first list)) (strip-predicate (rest list)))
( T (cons (first list) (strip-Predicate p (rest list))))))
This could be used on predicates such as atom or numberp:
(strip-predicate 'numberp '(a 1 b 2 c 3 d))
(a b c d)
or:
(strip-predicate 'atom '(a (a b) b c d))
((a b))

How do I find the index of an element in a list in Racket?

This is trivial implement of course, but I feel there is certainly something built in to Racket that does this. Am I correct in that intuition, and if so, what is the function?
Strangely, there isn't a built-in procedure in Racket for finding the 0-based index of an element in a list (the opposite procedure does exist, it's called list-ref). However, it's not hard to implement efficiently:
(define (index-of lst ele)
(let loop ((lst lst)
(idx 0))
(cond ((empty? lst) #f)
((equal? (first lst) ele) idx)
(else (loop (rest lst) (add1 idx))))))
But there is a similar procedure in srfi/1, it's called list-index and you can get the desired effect by passing the right parameters:
(require srfi/1)
(list-index (curry equal? 3) '(1 2 3 4 5))
=> 2
(list-index (curry equal? 6) '(1 2 3 4 5))
=> #f
UPDATE
As of Racket 6.7, index-of is now part of the standard library. Enjoy!
Here's a very simple implementation:
(define (index-of l x)
(for/or ([y l] [i (in-naturals)] #:when (equal? x y)) i))
And yes, something like this should be added to the standard library, but it's just a little tricky to do so nobody got there yet.
Note, however, that it's a feature that is very rarely useful -- since lists are usually taken as a sequence that is deconstructed using only the first/rest idiom rather than directly accessing elements. More than that, if you have a use for it and you're a newbie, then my first guess will be that you're misusing lists. Given that, the addition of such a function is likely to trip such newbies by making it more accessible. (But it will still be added, eventually.)
One can also use a built-in function 'member' which gives a sublist starting with the required item or #f if item does not exist in the list. Following compares the lengths of original list and the sublist returned by member:
(define (indexof n l)
(define sl (member n l))
(if sl
(- (length l)
(length sl))
#f))
For many situations, one may want indexes of all occurrences of item in the list. One can get a list of all indexes as follows:
(define (indexes_of1 x l)
(let loop ((l l)
(ol '())
(idx 0))
(cond
[(empty? l) (reverse ol)]
[(equal? (first l) x)
(loop (rest l)
(cons idx ol)
(add1 idx))]
[else
(loop (rest l)
ol
(add1 idx))])))
For/list can also be used for this:
(define (indexes_of2 x l)
(for/list ((i l)
(n (in-naturals))
#:when (equal? i x))
n))
Testing:
(indexes_of1 'a '(a b c a d e a f g))
(indexes_of2 'a '(a b c a d e a f g))
Output:
'(0 3 6)
'(0 3 6)

Count of atoms on the each level, Scheme

Please, help me with one simple exercise on the Scheme.
Write function, that return count of atoms on the each level in the
list. For example:
(a (b (c (d e (f) k 1 5) e))) –> ((1 1) (2 1) (3 2) (4 5) (5 1))
My Solution:
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
(define (count L)
(cond ((null? L) 0)
((pair? (car L))
(count (cdr L)))
(else
(+ 1 (count (cdr L))))))
(define (fun L level)
(cons
(list level (count L))
(ololo L level)))
(define (ololo L level)
(if (null? L)
'()
(if (atom? (car L))
(ololo (cdr L) level)
(fun (car L) (+ level 1)))))
(fun '(a (b (c (d e (f) k 1 5) e))) 1)
It's work fine, but give not correctly answer for this list:
(a (b (c (d e (f) (k) 1 5) e)))
is:
((1 1) (2 1) (3 2) (4 4) (5 1))
But we assume that 'f' and 'k' on the one level, and answer must be:
((1 1) (2 1) (3 2) (4 4) (5 2))
How should I edit the code to make it work right?
UPD (29.10.12):
My final solution:
(define A '(a (b (c (d e (f) k 1 5) e))))
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
(define (unite L res)
(if (null? L) (reverse res)
(unite (cdr L) (cons (car L) res))))
(define (count-atoms L answ)
(cond ((null? L) answ)
((pair? (car L))
(count-atoms (cdr L) answ))
(else
(count-atoms (cdr L) (+ answ 1)))))
(define (del-atoms L answ)
(cond ((null? L) answ)
((list? (car L))
(begin
(del-atoms (cdr L) (unite (car L) answ))))
(else
(del-atoms (cdr L) answ))))
(define (count L)
(define (countme L level answ)
(if (null? L) (reverse answ)
(countme (del-atoms L '()) (+ level 1) (cons (cons level (cons (count-atoms L 0) '())) answ))))
(countme L 1 '()))
(count A)
What can you say about this?
Do you know what you get if you run this?
(fun '(a (b (c (d e (f) k 1 5) e)) (a (b (c)))) 1)
You get this:
((1 1) (2 1) (3 2) (4 5) (5 1))
The whole extra nested structure that I added on the right has been ignored. Here is why...
Each recursion of your function does two things:
Count all the atoms at the current "level"
Move down the level till you find an s-expression that is a pair (well, not an atom)
Once it finds a nested pair, it calls itself on that. And so on
What happens in oLoLo when fun returns from the first nested pair? Why, it returns! It does not keep going down the list to find another.
Your function will never find more than the first list at any level. And if it did, what would you to do add the count from the first list at that level to the second? You need to think carefully about how you recur completely through a list containing multiple nested lists and about how you could preserve information at each level. There's more than one way to do it, but you haven't hit on any of them yet.
Note that depending on your implementation, the library used here may need to be imported in some other way. It might be painstakingly difficult to find the way it has to be imported and what are the exact names of the functions you want to use. Some would have it as filter and reduce-left instead. require-extension may or may not be Guile-specific, I don't really know.
(require-extension (srfi 1))
(define (count-atoms source-list)
(define (%atom? x) (not (or (pair? x) (null? x))))
(define (%count-atoms source-list level)
(if (not (null? source-list))
(cons (list level (count %atom? source-list))
(%count-atoms (reduce append '()
(filter-map
(lambda (x) (if (%atom? x) '() x))
source-list)) (1+ level))) '()))
(%count-atoms source-list 1))
And, of course, as I mentioned before, it would be best to do this with hash-tables. Doing it with lists may have some didactic effect. But I have a very strong opposition to didactic effects that make you write essentially bad code.