Remove element off list - scheme

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))))))

Related

Shorest-Seek-Time in Scheme

So currently I'm working on a problem of implementing the shortest-seek-time disk scheduling algorithm. Our task is, being passed a list of tracks, to return a list of length 3 containing the Avg Movement, Total movement, and then a list of the movement amounts. Currently I'm tackling returning the list of movements as I feel the total and avg's are trivial.
What I'm currently stuck on is saving the distance between the current head position and the current track so I can continue searching the list for the shortest seek time. What I did first was to sort the list and pass it into a separate helper function that only returns the the shortest-movement from the current head position so I can continually call this function.
Is the best way to do this to simply pass in another variable to hold the distance and keep checking based on this number? and then remove that disk from the list once I've satisfied the movement?
In Scheme having accumulators and state as extra parameters to a helper function and update using recursion to have state during the execution without actually mutating bindings.
The simplest example:
(define (reverse lst)
(let loop ((lst lst) (acc '()))
(if (null? lst)
acc
(loop (cdr lst) (cons (car lst) acc)))))
(reverse '(1 2 3)) ; ==> (3 2 1)
EDIT
Now since you said you're not used to named let here is the same with a helper procedure and keeping the same names:
(define (reverse lst)
;; a helper with an accumulator
(define (loop lst acc)
(if (null? lst)
acc
(loop (cdr lst) (cons (car lst) acc))))
;; call the helper
(loop lst '()))
Now the names loop, lst, acc are just variable names. However their names suggest loop is a tail recursive procedure. lst is a list and acc is short for accumulator which indicates on the base case it will be part of the result and for the default case it will be updated.

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.

Scheme: a good set function

I need to write a good set function that checks whether its argument lst is a properly represented set, i.e. it is a list consisting only of integers, with no duplicates, and returns true #t or false #f. For example:
(good-set? (1 5 2)) => #t
(good-set? ()) => #t
(good-set? (1 5 5)) => #f
(good-set? (1 (5) 2)) => #f
so I have began writing the function as:
(define (good-set? lst)
so I don't know how to proceed after this. Can anybody help?
One option would be to use andmap and sets, as has been suggested by #soegaard:
(define (good-set? lst) ; it's a good set if:
(and (andmap integer? lst) ; all its elements are integers and
(= (length lst) ; the list's length equals the size
(set-count (list->set lst))))) ; of a set with the same elements
But if you can't use sets or other advanced procedures, then traverse the list and test if the current element is an integer and is not present somewhere else in the list (use member for this), repeating this test for each element until there are no more elements in the list. Here's the general idea, fill-in the blanks:
(define (good-set? lst)
(cond (<???> ; if the list is empty
<???>) ; then it's a good set
((or <???> ; if the 1st element is not an integer or
<???>) ; the 1st element is in the rest of the list
<???>) ; then it's NOT a good set
(else ; otherwise
(good-set? <???>)))) ; advance recursion
Sets are built into the Racket standard library: I would recommend not reimplementing them in terms of lists unless you really need to do something customized.
If we need to treat this as a homework assignment, I would recommend using a design methodology to systematically attack this problem. In this case, see something like How to Design Programs with regards to designing functions that work on lists. As a brief sketch, we'd systematically figure out:
What's the structure of the data I'm working with?
What tests cases do I consider? (including the base case)
What's the overall shape of the function?
What's the meaning of the natural recursion?
How do I combine the result of the natural recursion in order to compute a solution to the total?
For this, check if the first number is duplicated, if it is not, then recurse by checking the rest. As such:
(define (good-set? list)
(or (null? list) ; nothing left, good!
(let ((head (car list)))
(rest (cdr list)))
(and (number? head) ; a number
(not (member = head rest)) ; not in the rest
(good-set? rest))))) ; check the rest
If you need member, then
(define (member pred item list)
(and (not (null? list))
(or (pred item (car list))
(member pred item (cdr list)))))

Get the middle elements from List in 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.

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