How can i get only one solution from filter map? - scheme

(filter-map (lambda (x y) (and (eq? x z) y) ) list1 list2 )
in scheme, i have two list list1 and list2, if any element of list1 equal to z, i want to return corresponding to list2 element. i know only one element on list1 equal to z.
My code is working but i get a result such that '(bla) but i want to only a result such that bla how can i remove this parentheses?

You can use car to retrieve the first element in the output list, but I don't think filter-map is the best option here - after all you're not interested in the list of results returned by filter-map, only in a single element - and this is unavoidable, a list will be returned even if it's empty. Basically, you need to look for a value in an association list. Try this instead:
(cdr (assq 'z (map cons list1 list2)))
=> 'bla
Explanation:
(map cons list1 list2) builds an association list, where the elements in list1 are the keys and the elements in list2 are the values
assq looks for the key-value pair that has 'z as its key (using eq? for the comparisons), and returns that pair
cdr returns the value part of that pair
Alternatively, you can check if your interpreter has a hash table implementation available (useful if you have to efficiently perform more than one search), for instance in Racket:
(hash-ref (make-hasheq (map cons list1 list2)) 'z)
=> 'bla
Explanation:
(map cons list1 list2) builds an association list, where the elements in list1 are the keys and the elements in list2 are the values
make-hasheq creates a new hash table using the association list, and uses eq? when finding a value given the key
hash-ref returns the value corresponding to the key 'z
Be aware that both of the above options will raise an error when we attempt to obtain the value if the key wasn't present in list1, you have to decide how to handle this case if the need arises; for example we can return #f:
(let ((pair (assq 'z (map cons list1 list2))))
(and pair (cdr pair)))
(hash-ref (make-hasheq (map cons list1 list2)) 'z
(const #f))

The naive approach would be to call car on the result, since car returns the first element of a list. But that would cause an error if no element matches - your function would return an empty list, and car will fail.
Some languages (i.e. Haskell) implement an option type. An option type is either empty or contains exactly one value. It's somewhat analogue to a list that can contains no more than one value. You can implement one for scheme and use it as the return type.
An alternative approach is to return the lists' first element, or #f (false) if no result was found. This approach is based on the fact that Scheme is a dynamic language.

While filter-map is nice and functional, an iterative answer might be the more straightforward (read: intelligible) way to approach this.
#lang racket
(define list1 '(a b z d))
(define list1a '(a b c d)) ; doesn't have 'z in it
(define list2 '(1 2 3 4))
(define (find-matching-pair lst1 lst2)
(let loop ((l1 lst1)
(l2 lst2))
(cond ((null? l1) #f) ; didn't find it
((eqv? (car l1) 'z) (car l2)) ; this ASSUMES l2 is not shorter than l1
(else (loop (cdr l1) (cdr l2))))))
(find-matching-pair list1 list2) ; => 3
(find-matching-pair list1a list2) ; => #f

Related

How to use the built-in function filter with lambda in Scheme programming?

"Implement unique, which takes in a list s and returns a new list containing the same elements as s with duplicates removed."
scm> (unique '(1 2 1 3 2 3 1))
(1 2 3)
scm> (unique '(a b c a a b b c))
(a b c)
What I've tried so far is:
(define (unique s)
(cond
((null? s) nil)
(else (cons (car s)(filter ?)
This question required to use the built-in filter function. The general format of filter function is (filter predicate lst), and I was stuck on the predicate part. I am thinking it should be a lambda function. Also, what should I do to solve this question recursively?
(filter predicate list) returns a new list obtained by eliminating all the elements of the list that does not satisfy the predicate. So if you get the first element of the list, to eliminate its duplicates, if they exists, you could simply eliminate from the rest of the list all the elements equal to it, something like:
(filter
(lambda (x) (not (eqv? x (first lst)))) ; what to maintain: all the elements different from (first lst)
(rest lst)) ; the list from which to eleminate it
for instance:
(filter (lambda (x) (not (eqv? x 1))) '(2 1 3 2 1 4))
produces (2 3 2 1 4), eliminating all the occurrences of 1.
Then if you cons the first element with the list resulting from the filter, you are sure that there is only a “copy” of that element in the resulting list.
The last step needed to write your function is to repeat recursively this process. In general, when you have to apply a recursive process, you have to find a terminal case, in which the result of the function can be immediately given (as the empty list for lists), and the general case, in which you express the solution assuming that you have already available the function for a “smaller” input (for instance a list with a lesser number of elements).
Consider this definition:
define (unique s)
(if (null? s)
'()
(cons (first s)
(filter
(lambda (x) (not (eq? x (first s))))
(unique (rest s))))))
(rest s) is a list which has shorter than s. So you can apply unique to it and find a list without duplicates. If, from this list, you remove the duplicates of the first element with filter, and then cons this element at the beginning of the result, you have a list without any duplicate.
And this is a possibile solution to your problem.

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

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.

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

Resources