Need help in scheme program won't know how to create it - scheme

Write a Scheme function that takes two atoms and a list as parameters and returns a list identical to the parameter list except all occurrences of the first given atom in the list are replaced with the second given atom.
(define(swap val1 val2 lst)
(cond ((null? lst) (lst val1))
((equal? val2 lst) (lst))
(else(equal? val2 (cadr lst)) (swap val1 val2 (cadr lst)))))

Two major syntactical problems is that (lst val1) and (lst) tries to call lst as a function, and that else shouldn't have a condition - the cond form is
(cond (condition1 expression1)
(condition2 expression2)
(else expression))
(equal? val2 lst) says "val2 is equal to the entire list lst". This does not make sense.
(equal? val2 (cadr lst)) says "val2 is equal to the second element of the list lst". You don't need to care about the second element.
The first element is car. The tail is cdr. (Many use first and rest, which are more modern names.)
You're pretty close to a solution, so I'll just give you a structure:
If the list is empty, the result is the empty list.
If the first element of the list is the one you're replacing, cons the new value onto the result of recursing on the rest of the list.
Otherwise, cons the existing value onto the result of recursing on the rest of the list.

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.

Scheme - Inserting a number in a List

I have this code :
(define (Insert value list)
(if (null? list) (list value))
(if (< value (car list)) (list (Insert (value list))))
(Insert (cdr list) list))
I want this code to take a list (assuming it's in low to increasing order of integers) and insert a number in the correct place. This code does not work but I don't know why. Anyone know?
You have a bunch of errors. First, let's see how you can fix your implementation:
(define (insert value lst)
(cond ((null? lst) ; if the list is empty
(list value)) ; then return a single-element list
((<= value (car lst)) ; if current element >= value
(cons value lst)) ; insert value in current position
(else ; otherwise keep building the list
(cons (car lst) ; by adding current element
(insert value (cdr lst)))))) ; and advancing recursion
Now, let's see what went wrong with your code:
You must not name a parameter list, that clashes with the built-in procedure of the same name - one you're actually using! it's clear that they'll conflict
The conditionals are incorrectly structured, if you have multiple conditions use a cond expression. Notice that the values of the first two ifs are discarded, because they're not nested (inside a procedure, only the value of the last expression is returned). Some Scheme interpreters will even raise an error when you write ifs without the corresponding else part
In the second condition, you must stop the recursion by consing the value with the rest of the list. It's better to stop as soon as possible, when element >= value, in case there are repeated elements
In the last condition, you're passing the parameters in the wrong order, and forgot about the value
Also in the last condition, you forgot to cons the current element
You have several errors in your code. First, in Scheme it is more natural to include else clauses for ifs. Also, you had wrong the last if. Here is a version of your code with minor modifications:
(define (Insert value lst)
(if (null? lst) (list value)
(if (< value (car lst))
(cons value lst)
(cons (car lst) (Insert value (cdr lst))))))
Note that you have to provide actions for when the value is less than the head of the list and when it is not, and you have to construct the returning value using cons.

Scheme,level intermediate student, find min without recursion

How can I write a function using abstract list functions (foldr, map, and filter) without recursion that consumes a list of numbers (list a1 a2 a3 ...) and produces a new list removing the minimum number from the original list?
The recursion code is:
(define (find-min lst)
(cond
[(empty? (rest lst)) (first lst)]
[else
(local [(define min-rest (find-min (rest lst)))]
(cond
[(< (first lst) min-rest) (first lst)]
[else min-rest]))]))
A fold applies a 2-argument function against a given value and the car of a list uses the result against the successive cars or the cdrs or the list. this is what we want.
Whereas map returns a new list by doing something with each element of a list.
And filter returns a smaller or equal list based on some predicate.
Now just to formulate a function that can choose the lessor of two arguments
(define (the-lessor x y)
(if (< x y)
x
y))
From there implementation is straightforward.
(define (min L) (fold the-lessor (car L) (cdr L)))
Since this looks like a homework question, I'm not going to provide all the code, but hopefully push you in the right direction.
From the HTDP book, we see that "The Intermediate Student language adds local bindings and higher-order functions." The trick here is probably going to using "local bindings".
Some assumptions:
(remove-min-from-list '()) => not allowed: input list must be non-empty
(remove-min-from-list '(1)) => '()
(remove-min-from-list '(1 2 3 1 2 3)) => '(2 3 2 3) ; all instances of 1 were removed
Somehow, we need to find the minimum value of the list. Call this function min-of-list. What are its inputs and outputs? It's input is a list of numbers and its output is a number. Of the abstract list functions, which ones allow us to turn a list of numbers into a number? (And not another list.) This looks like foldl/foldr to me.
(define (min-of-list lst)
(foldr some-function some-base lst))
Since you already showed that you could write min-of-list recursively, let's move on. See #WorBlux's answer for hints there.
How would we use this in our next function remove-min-from-list? What are the inputs and outputs of remove-min-from-list? It takes a list of numbers and returns a list of numbers. Okay, that looks like map or filter. However, the input list is potentially shorter than that output list, so filter and not map.
(define (remove-min-from-list lst)
....
(filter some-predicate list))
What does some-predicate look like? It needs to return #f for the minimum value of the list.
Let's pull this all together and use local to write one function:
(define (remove-min-from-list lst)
(local [(define min-value ...)
(define (should-stay-in-list? number) ...min-value ...)]
(filter should-stay-in-list? lst)))
The key here, is that the definition for should-stay-in-list? can refer to min-value because min-value came before it in the local definitions block and that the filter later on can use should-stay-in-list? because it is in the body of the local.
(define (comparator n) (local [(define (compare v) (not (equal? v n)))] compare))
(define (without-min list) (filter (comparator (foldr min (foldr max 0 list) list)) list))

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

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

Resources