Get the middle elements from List in scheme - scheme

I'm new to scheme , can someone please give me ideas on how to get , "the middle element from a list?"

Here's my solution. It's based on a tortoise-and-hare algorithm (which is used in any kind of list traversal where you need to detect circular lists), so it doesn't do any more work than a sane list traversal has to do anyway. :-)
(define (middle-elements lst)
(if (null? lst) '()
(let loop ((tortoise lst)
(hare (cdr lst)))
(cond ((eq? tortoise hare) #f)
((null? hare) (list (car tortoise)))
((null? (cdr hare)) (list (car tortoise) (cadr tortoise)))
(else (loop (cdr tortoise) (cddr hare)))))))
It covers the following cases:
If given an empty list, returns an empty list.
If given a list with an odd number of elements, returns a singleton list with the middle element.
If given a list with an even number of elements, returns a list with the two middle elements.
If given a circular list, returns #f.
If given an improper list (including a non-list), summons nasal demons.

Related

How do I check my list to see if it contains only one value or more than one?

Here's what I have so far:
(DEFINE (swap lst)
(COND ((NULL? lst) lst)
(IF (lst --------))
))
I'm new to Scheme so I'm a little bit confused right now. For this function I'm supposed to check for a few things:
Is the list empty? If so, print out the unchanged empty list.
Is the list a single atom (element)? If so, print out the unchanged list.
If the list is not empty and has more than one atom, count out pairs and swap
the orders of those pairs.
i.e. If my list is (a b c d e f g)
then my function should return (b a d c f e g)
My primary question is how I go about checking my list to see if it has a single value or more than one.
Checking if a list has no elements is simple:
(null? lst)
Now, how can we verify if it has a single element? it's very similar to the previous case, we just check to see if the element after the current is the empty list:
(null? (cdr lst))
After that, the solution to the problem is obtained from the definition:
(define (swap lst)
(cond ((null? lst) lst)
((null? (cdr lst)) lst)
(else <do your thing>)))
For the last case, take care of consing the second element, to the first element, to the result of recursively processing the rest of the list; also remember that in this case for obtaining the "rest" we must advance over two elements at a time.

How to check if a list is even, in

I want to test if a list is even, in . Like (evenatom '((h i) (j k) l (m n o)) should reply #t because it has 4 elements.
From Google, I found how to check for odd:
(define (oddatom lst)
(cond
((null? lst) #f)
((not (pair? lst)) #t)
(else (not (eq? (oddatom (car lst)) (oddatom (cdr lst)))))))
to make it even, would I just swap the car with a cdr and cdr with car?
I'm new to Scheme and just trying to get the basics.
No, swapping the car and cdr won't work. But you can swap the #f and #t.
Also, while the list you gave has 4 elements, what the function does is actually traverse into sublists and count the atoms, so you're really looking at 8 atoms.
You found odd atom using 'Google' and need even atom. How about:
(define (evenatom obj) (not (oddatom obj)))
or, adding some sophistication,
(define (complement pred)
(lambda (obj) (not (pred obj))))
and then
(define evenatom (complement oddatom))
you are mixing a procedure to check if a list has even numbers of elements (not restricted to atoms) and a procedure that checks if there are an even number of atomic elements in the list structure. Example: ((a b) (c d e) f) has an odd number of elements (3) but an even number (6) of atoms.
If you had some marbles, how would you determine if you had an odd or even number of marbles? you could just count them as normal and check the end sum for evenness or count 1,0,1,0 or odd,even,odd,even so that you really didn't know how many marbles I had in the end, only if it's odd or even. Lets do both:
(define (even-elements-by-count x)
(even? (length x)))
(define (even-elements-by-boolean x)
(let loop ((x x)(even #t))
(if (null? x)
even
(loop (cdr x) (not even)))))
now imagine that you had some cups in addition and that they had marbles to and you wondered the same. You'd need to count the elements on the floor and the elements in cups and perhaps there was a cup in a cup with elements as well. For this you should look at How to count atoms in a list structure and use the first approach or modify one of them to update evenness instead of counting.
The equivalent of the procedure you link to, for an even number of atoms, is
(define (evenatom lst)
(cond
((null? lst) #t)
((not (pair? lst)) #f)
(else (eq? (evenatom (car lst)) (evenatom (cdr lst))))))
You need to swap #t and #f, as well as leave out the not clause of the last line.

Remove element off list

Someone tell me what is wrong with this code. I thought I mastered a few scheme skills to solve a friend's problem but it ended up messing my head. I am trying to remove all similar elements off the list. Earlier it was removing only the first element I want to remove, but now its removing the car and the first element f what I want to remove. I am looking for an output like: (delete 3 (list 2 3 4 3 5 3)), returns (2 4 5).
(define (delete n lst)
(cond
((null? lst) null)
((equal? n (car lst)) (cdr lst))
(else
(remove n (cdr lst)))))
It's because of this conditional:
((equal? n (car lst)) (cdr lst))
What this line does is it checks that n is the same as the first element in the list. If it is, it returns the rest of the list. Since your target element is the second element of the list, it returns the rest of the list, from the third element onward. Your first element in the list is completely dropped. You're not keeping track of the OK elements you've checked so far.
From your code, it looks like you want to loop through the elements of the list and, if you find your target value, call remove. If you want to implement it in this fashion, you need to also track the values that you've checked and verified that are not your target value. So your function needs to take three parameters: n, your target; lst the remaining numbers to check; and clean (or whatever you want to call it) that holds the already checked numbers.
This is a working version of your algorithm:
(define (delete n lst clean)
(cond
((empty? lst) clean)
((equal? n (car lst)) (delete n (cdr lst) clean))
(else
(delete n (cdr lst) (append clean (list (car lst)))))))
You'd call it like so: (delete 3 (list 2 3 4 3 5 3) '())
First it checks if you have numbers left to check. If you don't, it returns your clean list.
Then it checks to see if the first element matches your target element. If it does, then it calls delete again, effectively dropping the first element in the lst (notice it does not append it to the list of clean numbers).
The else, which is reached if the first element is not the target number, appends the first value of lst to the end of clean and calls delete again.
(Note that this code uses tail recursion, which is a way of writing recursive methods that track the intermediate values with each recursive call, as opposed to "regular" recursion that does the calculation at the end. Samrat's answer, below, is a regular recursive solution. A discussion of the tail recursion can be found here.)
From your post, it sounds like you want to remove all instances of the target number. Instead of using the remove function -- which only removes the first instance of the target number -- you should look at using the remove* function, which removes all instances. This would greatly simplify your function. So to remove all instances of 3 from your list, this would suffice:
(remove* '(3) (list 2 3 4 3 5 3))
If you wanted to wrap it in a function:
(define (delete n lst)
(remove* (list n) lst))
You should read up on map functions in general, since they pretty much do what you're looking for. (They apply a procedure against all elements in a list; The above could also be implemented with a filter-map if you had a more complicated procedure.)
Here's what I came up with:
(define (delete n lst)
(cond ((empty? lst) lst)
((= (car lst) n) (delete n (cdr lst)))
(else (append (list (car lst)) (delete n (cdr lst))))))

Find whether element in list integer?

I was wondering, how do you check if every element in a list is an integer or not? I can check the first element by using (integer? (car list), but if I do (integer? (cdr list), it always returns false (#f) because the whole of the last part of the list is not an integer as a group.
In this case let's say list is defined as.
(define list '(1 2 5 4 5 3))
(define get-integers
(lambda (x)
(if (null? x)
"All elements of list are integers"
(if (integer? (car x))
(get-integers (cdr x))
"Not all elements are an integer"))))
Practical Schemes provide functions for doing tests across whole sequences. An application of the andmap function, for example, would be appropriate. Racket provides a for/and to do something similar. If you really needed to write out the loop by hand, you'll be using recursion.
What you need to do is test each element in the list to see if it satisfies a condition (being an integer, in this case). When you evaluate (integer? (car list)) on a list of integers, you're checking if the first element in the list is an integer, and that's fine. But the expression (integer? (cdr list)) tests if a list is an integer (because cdr returns a list), and that won't work - you need to test the next element in the list, and the next, and so on until the list is empty.
There are several ways to do the above, the most straightforward would be to recur on the list testing each element in turn, returning false if a non-integer element was found or true if all the list was consumed without finding a non-integer element, like this:
(define (all-integers? lst)
(cond ((null? lst) #t)
((not (integer? (car lst))) #f)
(else (all-integers? (cdr lst)))))
A more practical approach would be to use a built-in procedure, like this:
(andmap integer? lst)
andmap will check if all the elements in lst evaluate to true for the given predicate. For example:
(andmap integer? '(1 2 3))
> #t
(andmap integer? '(1 "x" 3))
> #f
SRFI-1 uses the terms every and any rather than andmap and ormap. match can also be used:
(define list-of-integers?
(lambda (lst)
(match lst
(((? number?) ..1) #t)
(_ #f))))

How can I get all possible permutations of a list with Common Lisp?

I'm trying to write a Common Lisp function that will give me all possible permutations of a list, using each element only once. For example, the list '(1 2 3) will give the output ((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)).
I already wrote something that kind of works, but it's clunky, it doesn't always work and I don't even really understand it. I'm not asking for code, just maybe for some guidance on how to think about it. I don't know much about writing algorithms.
Thanks,
Jason
As a basic approach, "all permutations" follow this recursive pattern:
all permutations of a list L is:
for each element E in L:
that element prepended to all permutations of [ L with E removed ]
If we take as given that you have no duplicate elements in your list, the following should do:
(defun all-permutations (list)
(cond ((null list) nil)
((null (cdr list)) (list list))
(t (loop for element in list
append (mapcar (lambda (l) (cons element l))
(all-permutations (remove element list)))))))
Here is the answer which allows repeated elements. The code is even more "lispish" as it doesn't use loop, with the disadvantage of being less comprehensible than Rainer Joswig's solution:
(defun all-permutations (lst &optional (remain lst))
(cond ((null remain) nil)
((null (rest lst)) (list lst))
(t (append
(mapcar (lambda (l) (cons (first lst) l))
(all-permutations (rest lst)))
(all-permutations (append (rest lst) (list (first lst))) (rest remain))))))
The optional remain argument is used for cdring down the list, rotating the list elements before entering the recursion.
Walk through your list, selecting each element in turn. That element will be the first element of your current permutation.
Cons that element to all permutations of the remaining elements.

Resources