Scheme matching elements - list

I'm currently playing a bit around with scheme, and I've been stuck for quite a while trying to figure out how to implement a test, that checks if any element in 'xs' is also stored in 'l'.
That is the mathematical function '\in', just for each element in the list xs.

Do you want to write it yourself for practice, or do you just need the functionality?
If you just want the functionality then use the answer by larsmans (I have never used that, but it looks good to me).
To implement try the following (disclaimer: I have not tested this)
(define has-intersect?
(lambda (xs l)
(cond
[(null? xs) #f]
[(member? (car xs) l) #t]
[else (has-intersect? (cdr xs) l)])))

In mathematical terms, you're checking whether the intersection of two lists/sets is non-empty. If you have an SRFI-1 library, this is trivial:
(not (null? (lset-intersection l xs)))
An implementation of SRFI-1 can be found in SLIB.
(Disclaimer: I'm a former SLIB contributor.)

Related

SCHEME- comparing lists and returning only the values that do not appear in the second list

I am having a hard time debugging this code and was hoping somebody might be able to help with pseudocode or examples of similar problems. Thank you ahead of time!
Define a non-recursive Scheme procedure (remove-them2 lst n) which returns a list of all elements of lst that do not appear in the list n.
Here is what I have so far:
(define (remove-them2 lst n)
(if (null? lst)
n
(let ((tail (remove-them2 cons((cdr lst) (cdr n)))))
(if (member (car lst) (car n) tail)
tail
(cons (car lst) (car n) tail)))))
I'm afraid there are several syntax errors in your solution, please take some time to study how to write procedures in Scheme and how to invoke procedures. To name a few:
We don't call a procedure like this: cons(...), the correct way is (cons ...)
cons expects two arguments, but you're passing three
remove-them2 expects two arguments, but you're passing one
member expects two arguments, but you're passing three
The way you're building the output list is incorrect
We don't need to ask for (car n), we're interested in checking if an element is a member of the whole n list
There's no need to have a tail variable here, it's easier if we just call the recursion directly; and anyway you're using tail incorrectly.
It's not clear what algorithm you tried to implement, but the actual solution is simple - although we'll have to rewrite the code from scratch to make it work:
(define (remove-them2 lst n)
(if (null? lst)
'()
(if (member (car lst) n)
(remove-them2 (cdr lst) n)
(cons (car lst) (remove-them2 (cdr lst) n)))))
EDIT: It's also possible to write a solution without using recursion:
(define (remove-them2 lst n)
(filter (lambda (e) (not (member e n)))
lst))
Either way, it works as expected:
(remove-them2 '(1 2 3 4 5 6 7) '(1 3 5))
=> '(2 4 6 7)
Without knowing which subset of the language you are allowed to use it's hard to answer this reasonably.
I'll assume that you want something which is not syntactically recursive (so you can't use a function with an accumulator: I'm not sure what the right word is for this), you are allowed to use map and append, but you're not allowed to use filter as that seems like such an immediate answer.
With those constraints here is how you can do this:
(define (remove-them2 l baddies)
(apply append (map (lambda (e)
(if (memv e baddies)
'()
(list e)))
l)))
I think this is pretty artificial and horrible, but it works (in languages like CL it would not portably work however, which is why I think it's horrible).

if statement in lambda Scheme

I'm a new schemer. I just want to ask if I can include if-statements in a lambda? For example, (lambda (x) (if e1 e2 e3)). I don't see why not, but my program just keep failing if I write this way.
Thanks a lot!
Here's my code here.I'm trying to implement filter with higher-order functions as an exercise. Since #sepp2k has answered that it's totally fine to include ifs in lambda, I'd guess it's the problem of my use of foldr?
If anyone can give some insight into this to help me understand the way it works, I'd really appreciate it!
(define filter (f xs)
(if (null? xs) '()
(foldr (lambda (elem ys) ((if (f elem) (cons elem ys)
(cons '() ys)))) '() xs)))
Of course we can use an if inside a lambda, in fact, any valid expression can go inside a lambda. There are more serious errors in your code:
There are additional (and unnecessary) parentheses surrounding the innermost if expression. Scheme will interpret them as a function application, and that's not what you want to do here
The else of the if expression is wrong, you just have to pass the accumulator without modifications
The function definition is incorrect
Also the whole function can be simplified, there's no need for the outermost if and the indentation can be improved. Try this:
(define (filter f xs)
(foldr (lambda (elem ys)
(if (f elem) ; if the predicate is true
(cons elem ys) ; then `cons` element to accumulator
ys)) ; otherwise leave accumulator alone
'()
xs))
It works as expected:
(filter even? '(1 2 3 4 5 6))
=> '(2 4 6)
Yes, it is perfectly valid to use ifs inside lambdas. If your program fails that must be because of other reasons.
Extra parens around the call to if. Scheme overloads grouping (list of expressions) and function-calls (+ 2 2).
FWIW, you might also use foldl, as foldr takes up O(|elements of the input|) memory.
Going deeper, lambdas are what's called a "special form" in scheme. That means that they obey different evaluation rules. I only bring this up because it gives some insight into a key feature of scheme: everything is just a form. define? Special form. lambda? Special form. Nothing you couldn't write yourself if you really felt like it. That means that with a lot of special forms, even if they seem automagic/baked-in, they don't have any esoteric caveats lying around.
Also, just for future reference, here are a couple of gems for your scheming: MIT Scheme Reference (lambdas), Racket Guide (Pairs and Lists)

Racket Sum of Perfect Roots Implementation

I am trying to write a Racket function that takes in a list of numbers as the input, and outputs the sum of the square roots of those numbers in the list that are perfect squares. The code I have currently does not compile, and is as follows:
(define (sum-of-perfect-roots lst)
(apply + (map (lambda (number)
(sqrt number)) (filter (exact? sqrt(number)) lst))))
I know that my error lies in the usage of the predicate for the filter function. I don't know how to return the list of only perfect squares correctly. Any help is appreciated!
Racket actually has a built-in math library, and the math/number-theory module provides a convenient perfect-square function. The documentation for perfect-square describes it as follows:
Returns (sqrt m) if m is perfect square, otherwise #f.
This, of course, makes implementing your function trivial. You could just do something like this:
(require math/number-theory)
(define (sum-of-perfect-roots lst)
(apply + (filter-map perfect-square lst)))
Using filter-map is also more efficient, since it doesn't need to build the list twice. Still, if you'd rather roll your own implementation for learning purposes, reimplementing perfect-square would not be terribly difficult.
(define (perfect-square n)
(define root (sqrt n))
(if (integer? root) root #f))
If you wanted to make it more efficient, you could avoid building the intermediate list entirely by using fold. Racket's for/sum comprehension form makes this easy to implement.
(define (sum-of-perfect-roots lst)
(for/sum ([n (in-list lst)])
(or (perfect-square n) 0)))

Re-implementing lists with closures in scheme

This is purely a curiosity question for me:
So for fun, one can easily redefine cons, car, and cdr like so:
(define cons+
(lambda (a b)
(lambda (f)
(f a b)
)))
(define car+
(lambda (f)
(f (lambda (a b) a))))
(define cdr+
(lambda (f)
(f (lambda (a b) b))))
This creates the basic functionality of a list using closures. In this context, what would be the best way to define an empty list?
There's no particular special value that you need as the empty list; you just need something and then to treat it as the empty list. In Common Lisp, a list is either a cons or the symbol NIL. You could take the same approach and use the symbol NIL, or you could use some other value, so long as you treat it consistently. Part of the beauty (and sometimes, the ugliness) of linked lists in the Lisp families is that they are intensional data structures. They're built out of a bit of structure and a lot of convention. That's why we can use cons cells to implement singly-linked lists, tree, etc.
Now, what does it mean to treat it consistently? Some of that will depend on exactly how you want it to behave. In Common Lisp, you can call car and cdr with the empty list, and you'll get back the empty list. In Scheme, you'll get an error. In the closure-based approach, you've got a "leaky" abstraction in the sense that you can call car+ and cdr+ with values that were not produced by cons+, and you might get a value back.
What interface do you want?
When implementing singly linked lists in the Lisp styles (conses and an empty list), you typically want an interface that will let you check:
(cons? (cons ...)) == true
(empty? empty) == true
(In terms of those, you can implement list?)
(define (list? x)
(or (cons? x)
(null? x)))
After what you've already done, it shouldn't be hard to implement a cons? function. But what about empty?? You actually have a lot of freedom here. You could implement empty? such that there are actually multiple objects that serve as a empty lists. As long as the contract works, it's OK.
Should anything else work?
At the moment, you've got a working implementation of ordered pairs, but it's a leaky abstraction in that some things that weren't created with cons could still be passed to car and cdr without any error. You've satisfied the axioms
(car (cons x y)) == x
(cdr (cons x y)) == y
but not the implications
(car z) == x ⇒ z == (cons x _)
(cdr z) == y ⇒ z == (cons _ y)
If you can find a way to make those implications true, so that car and cdr only work with things produced by cons, then you can probably figure out how to implement cons?, and you can use the same technique to generate a unique empty list object.

Scheme list counting function

I'm trying to write a Scheme function that counts all the items in a list, but unlike the length function that is available would count inner lists also so countAll '(a (a b)) would return 3 and not 2.
the first check is for an empty list, the second is supposed to check if the head of the list is currently a list itself, it should then add the length of THAT list to the total and call the next recursive call, if it isn't, it should simply skip to the third part which will add one to the total and call the function recursively.
I'm getting syntactical errors and I'm unsure about my approach. Am I going about this the right way? Are there better/Easier ways to do this?
(define countAll
(lambda (list)
(if (null? list)
0
((if (list? (car list)
(+ length (car list)
(countAll (cdr list))))))
(+ 1
(countAll (cdr list))))))
(+ 1
(countAll(cdr list)
)))))
You've made a mess of your parentheses. I would strongly advise rewriting this using cond, as in
(cond
((null? lst) 0)
((list? (car lst)) (???))
(else (???)))
This will make it easier to see what you are doing and much less likely that you mess up your parentheses. Nested ifs really are something to avoid except in the simplest of circumstances.
Your approach is nearly right, but you've missed something. You have made a big assumption about what happens when (list? (car lst)) evaluates to true. Can you think what it is? If you think about it hard enough, you'll realise that you cannot use the length function here.
The solution to this kind of problem follows a well-known structure, a recipe if you wish, for traversing a list of lists. This looks like homework, so I'll help you with the general idea and you go ahead filling-in the blanks:
(define (countAll lst)
(cond ((null? lst) ; if the list is empty.
<???>) ; then it doesn't have any elements
((not (list? (car lst))) ; if the first element in the list is not a list
(<???> (countAll <???>))) ; add one and advance the recursion over the `cdr`
(else ; otherwise
(+ (countAll <???>) ; add the result of the recursion over the `car`
(countAll <???>))))) ; with the result of the recursion over the `cdr`
If you need more help understanding how to structure a solution to this kind of problems dealing with lists of lists, I'd recommend you take a look at either The Little Schemer or How to Design Programs, both books will teach you how to grok recursive processes in general.
if you want to count elements of nested list you can use the deep recursion function as some people answer here. or what I do is use racket function (flatten) to make the nested list flat then use recursion on level 1 list as in the following code
(define (howMany ls)
(if (null? ls)
0
(+ 1 (howMany (cdr ( flatten ls )))))) ; flat the nested list and deal with it as a level 1 list.