Are pair and list different in Scheme? - scheme

I wonder whether '(1 . 2) and '(1 2) mean the same data (equal to each other) in Scheme or not? I think they are the same thing, is this correct?

No, they are not the same.
'(1 . 2) means (cons 1 2)
whereas
'(1 2) means (cons 1 (cons 2 nil))

(1 . 2) is sometimes called an improper list, because it is not NIL terminated. (1 2) represented in dot form may be written (1 2 . NIL), but you should not write something like this.

dr rackect explains it much more clearer:
"A pair joins two arbitrary values.....The cons procedure constructs pairs"
(cons 1 2)
'(1 . 2)
(pair? (cons 1 2))
#t
on the other hand
"A list is a combination of pairs that creates a linked list. More precisely, a list is either the empty list null, or it is a pair whose first element is a list element and whose second element is a list."
(cons 0 (cons 1 (cons 2 null)))
'(0 1 2)
http://docs.racket-lang.org/guide/pairs.html
please LISP has been around since the 50's for accurate answers look at their documentation and example they area around for more than 60 years some people was not even born there.

Yes!
Pairs: (cons y z) creates a pair between the values y and z. Likewise, the (more complicated) expression (cons x (cons y z)) creates a pair between x and the pair (y . z). You can also represent these pairs as '(y . z) and '(x . (y . z))
Lists: A list is just a special type of pair. It's the case where a value is paired onto an already-existing list. Since the very first list has to start somewhere, we always have the null list '() (sometimes called the 'empty list') ready to be paired. So (cons y '()) pairs y with the null list to become the one-item list '(y). Likewise, (cons x '(y)) and (cons x (cons y '())) pair x to the list '(y) to become the list '(x y).
listspairs

List must end with empty list (also termed as null). Below sample code on repl illustrates the difference.
> (cons 1 (cons 2 '())) ; I am a pair as well as list
'(1 2)
(pair? (cons 1 (cons 2 '())))
#t
> (list? (cons 1 (cons 2 '())))
#t
> (cons 1 (cons 2 3)) ;I am a pair but but not list
'(1 2 . 3)
> (pair? (cons 1 (cons 2 3)))
#t
> (list? (cons 1 (cons 2 3)))
#f

Related

Generating permutations in Lisp withous map functions

I want to generate in Lisp the list of all permutations of a set. This is what I tried:
(defun ins(e n l)
(cond
((equal n 1) (cons e l))
(T (cons (car l) (ins e (1- n) (cdr l))))
)
)
;; (print (ins '1 1 '(2 3)))
;; (print (ins '1 2 '(2 3)))
;; (print (ins '1 3 '(2 3)))
(defun insert(e n l)
(cond
((equal n 0) nil)
(T (cons (ins e n l) (insert e (1- n) l) ))
)
)
;; (print (insert '1 3 '(2 3)))
(defun inserare(e l)
(insert e (1+ (length l)) l)
)
;(print (inserare '1 '(2 3))) -> ((2 3 1) (2 1 3) (1 2 3))
And from here I just can't make the final permutations function. I tried something like this:
(defun perm(L)
(cond
((null L) nil)
(T (append (perm (cdr L)) (inserare (car L) L)))
)
)
But this is not the good approach
Here is one way.
First of all, if you have a list like (x . y) and you have the permutations of y you will need to create from them the permutations of (x . y). Well consider one of these permutations p, and let this be (p1 p2 ...). From this you will need to make a bunch of permutations including x: (x p1 p2 ...), (p1 x p2 ...), (p1 p2 x ...) ... (p1 p2 ... x).
So let's write a function to do this: a function which given some object and a list will 'thread' the object through the list creating a bunch of new lists with the object inserted at every point. For reasons that will become clear this function is going to take an extra argument which is the list of things to attach the new permutations to the front of. It's also going to use a little local function to do the real work.
Here it is:
(defun thread-element-through-list (e l onto)
(labels ((tetl-loop (erofeb after into)
(if (null after)
(cons (nreverse (cons e erofeb)) into)
(tetl-loop (cons (first after) erofeb)
(rest after)
(cons (revappend (cons e erofeb) after) into)))))
(tetl-loop '() l onto)))
I'm not going to explain the details of this function, but there are a couple of things worth knowing:
tetl-loop is thread-element-through-list-loop;
erofeb is before backwards, because the elements are in reverse order on it;
the nreverse is just a gratuitous hack because at that point erofeb is otherwise dead – there is effectively no mutation in this function.
And we can test it:
> (thread-element-through-list 1 '(2 3) '())
((2 3 1) (2 1 3) (1 2 3))
Now, OK, what we actually have is not just one permutation of y, we have a list of them. And we need to thread x through each of them, using `thread-element-through-list. So we need a function to do that.
(defun thread-element-through-lists (e ls onto)
(if (null ls)
onto
(thread-element-through-lists
e (rest ls)
(thread-element-through-list e (first ls) onto))))
This also has an argument which defines what it's adding its results to, and you can see how this onto list now gets passed around to build the list.
And we can test this
> (thread-element-through-lists '1 '((2 3) (3 2)) '())
((3 2 1) (3 1 2) (1 3 2) (2 3 1) (2 1 3) (1 2 3))
Look at that carefully. I gave thread-element-through-lists, 1, and a list which was the permutations of (2 3), and it has turned out for me the permutations of (1 2 3). So what you now need to do (which I am not going to do for you) is to write a function which:
knows the permutations of () (which is () and of a single-element list (which is a list containing that list)`;
uses thread-elements-through-lists together with a recursive call to itself to compute the permutations of any longer list.

If a list is found in another list?

I started to learn Racket and I don't know how to check if a list is found in another list. Something like (member x (list 1 2 3 x 4 5)), but I want that "x" to be a a sequence of numbers.
I know how to implement recursive, but I would like to know if it exists a more direct operator.
For example I want to know if (list 3 4 5) is found in (list 1 2 3 4 5 6 )
I would take a look at this Racket Object interface and the (is-a? v type) -> boolean seems to be what you are looking for?, simply use it while looping to catch any results that are of a given type and do whatever with them
you may also want to look into (subclass? c cls) -> boolean from the same link, if you want to catch all List types in one go
should there be a possiblity of having a list inside a list, that was already inside a list(1,2,(3,4,(5,6))) i'm afraid that recursion is probally the best solution though, since given there is a possibility of an infinit amount of loops, it is just better to run the recursion on a list everytime you locate a new list in the original list, that way any given number of subList will still be processed
You want to search for succeeding elements in a list:
(define (subseq needle haystack)
(let loop ((index 0)
(cur-needle needle)
(haystack haystack))
(cond ((null? cur-needle) index)
((null? haystack) #f)
((and (equal? (car cur-needle) (car haystack))
(loop index (cdr cur-needle) (cdr haystack)))) ; NB no consequence
(else (loop (add1 index) needle (cdr haystack))))))
This evaluates to the index where the elements of needle is first found in the haystack or #f if it isn't.
You can use regexp-match to check if pattern is a substring of another string by converting both lists of numbers to strings, and comparing them, as such:
(define (member? x lst)
(define (f lst)
(foldr string-append "" (map number->string lst)))
(if (regexp-match (f x) (f lst)) #t #f))
f converts lst (a list of numbers) to a string. regexp-match checks if (f x) is a pattern that appears in (f lst).
For example,
> (member? (list 3 4 5) (list 1 2 3 4 5 6 7))
#t
One can also use some string functions to join the lists and compare them (recursion is needed):
(define (list-in-list l L)
(define (fn ll)
(string-join (map number->string ll))) ; Function to create a string out of list of numbers;
(define ss (fn l)) ; Convert smaller list to string;
(let loop ((L L)) ; Set up recursion and initial value;
(cond
[(empty? L) #f] ; If end of list reached, pattern is not present;
[(string-prefix? (fn L) ss) #t] ; Compare if initial part of main list is same as test list;
[else (loop (rest L))]))) ; If not, loop with first item of list removed;
Testing:
(list-in-list (list 3 4 5) (list 1 2 3 4 5 6 ))
Output:
#t
straight from the Racket documentation:
(member v lst [is-equal?]) → (or/c list? #f)
v : any/c
lst : list?
is-equal? : (any/c any/c -> any/c) = equal?
Locates the first element of lst that is equal? to v. If such an element exists, the tail of lst starting with that element is returned. Otherwise, the result is #f.
Or in your case:
(member '(3 4 5) (list 1 2 3 4 5 6 7))
where x is '(3 4 5) or (list 3 4 5) or (cons 3 4 5)
it will return '(3 4 5 6 7) if x ( searched list '(3 4 5) ) was found in the list or false (#f) if it was not found
or you can use assoc to check if your x is met in one of many lists, or :
(assoc x (list (list 1 2) (list 3 4) (list x 6)))
will return :
'(x 6)
There are also lambda constructions but I will not go in depth since I am not very familiar with Racket yet. Hope this helps :)
EDIT: if member gives you different results than what you expect try using memq instead

finding subsets of length N of a list in scheme

I wrote a function which finds all the subsets of a list already and it works. I'm trying to write a second function where I get all the subsets of N length, but it's not working very well.
This is my code:
(define (subset_length_n n lst)
(cond
[(empty? lst) empty]
[else (foldr (lambda (x y) (if (equal? (length y) n) (cons y x) x)) empty (powerset lst))]
))
where (powerset lst) gives a list of all the subsets.
Am I misunderstanding the purpose of foldr?
I was thinking that the program would go through each element of the list of subsets, compare the length to n, cons it onto the empty list if there the same, ignore it if it's not.
But (subset_length_n 2 (list 1 2 3)) gives me (list (list 1 2) 1 2 3) when I want (list (list 1 2) (list 1 3) (list 2 3))
Thanks in advance
When using foldr you don't have to test if the input list is empty, foldr takes care of that for you. And this seems like a job better suited for filter:
(define (subset_length_n n lst)
(filter (lambda (e) (= (length e) n))
(powerset lst)))
If you must, you can use foldr for this, but it's a rather contrived solution. You were very close to getting it right! in your code, just change the lambda's parameters, instead of (x y) write (y x). See how a nice indentation and appropriate parameter names go a long way toward writing correct solutions:
(define (subset_length_n n lst)
(foldr (lambda (e acc)
(if (= (length e) n)
(cons e acc)
acc))
empty
(powerset lst)))
Anyway, it works as expected:
(subset_length_n 4 '(1 2 3 4 5))
=> '((1 2 3 4) (1 2 3 5) (1 2 4 5) (1 3 4 5) (2 3 4 5))

How to count individual elements in a pair - scheme ?

(cons 2 (cons ( cons 2 3 ) (cons 4 5 )))
This gives me a list that looks like this : (2 (2 . 3) 4 . 5) when I try to count the number of elements in this list the output is 3 as exepected.
How do I calculate the number of individual elements of a pair ? The output in this case should be 5 for example.
Here's a possible solution, the question is essentially asking for the number of atoms in a list structure (not necessarily null-terminated proper lists):
(define (count-all seq)
(cond ((null? seq) 0)
((not (pair? seq)) 1)
(else (+ (count-all (car seq))
(count-all (cdr seq))))))
It works on sequences of elements like this:
If the sequence is empty, it has zero elements
If the sequence is not a cons cell (a pair of elements), it's because it's a single element - an atom
Otherwise add the elements of both the car and the cdr of the sequence
It works as expected for arbitrarily nested list structures:
(count-all '(2 (2 . 3) 4 . 5))
=> 5
(count-all '(1 (2 . (3 (4 . 5) 6)) 7 . 8))
=> 8
We can solve this problem recursively for arbitrarily deeply nested lists.
(define (atom? x) (not (pair? x)))
(define (count-atoms lst)
(cond ((null? lst) 0) ; nothing to count, return 0
((atom? lst) 1) ; lst contains only one thing, return 1
(else ; otherwise, lst contains multiple elements
(+ (count-atoms (car lst)) ; add the number of atoms in the first position
(count-atoms (cdr lst)))))) ; to the number of atoms in the rest of the list
EDIT: This is a duplicate to Oscar's answer. I did not see that he had answered when I hit submit, but will leave this here since I feel the comments are useful.

What does the last element in a list point to in Scheme?

When I make a list in Scheme, what does the cdr of the last pair point to? Is it an 'empty word' or an 'empty list'? DrScheme doesnt mind (cons 'a empty) nor (cons 'a '()). Finally what is the difference between the empty word and the empty list?
DrScheme doesn't mind your cons-ing, because cons can do more than just build lists. From the reference,
(cons a d) → pair?
a : any/c
d : any/c
which means that cons builds pairs. It's also perfectly legal to do
> (cons 1 2)
(1 . 2)
which is not a list, but which still lets you do
> (car (cons 1 2))
1
> (cdr (cons 1 2))
2
But anyways, the "empty word" and the "empty list " are the same object, as can be checked by
> (eq? empty '())
#t
The cdr of the last pair points to '(), the empty list.
The answer to all of your questions can be found if you evaluate the symbol empty. It's defined to be equal to '(), the empty list, and this is what the last cdr points to. To convince yourself, try this:
(cdr (list 1 2 3))
(cdr (cdr (list 1 2 3)))
(cdr (cdr (cdr (list 1 2 3))))

Resources