Table of Contents

## set?

Based on what they say in the book, I’m guessing that a set is defined as a list of atoms where no atom appears more than once. This includes the empty set.

This was my solution:

1 2 3 4 5 6 |
(define myset? (lambda (lat) (cond ((null? lat) #t) ((> (occur (car lat) lat) 1) #f) (else (myset? (cdr lat)))))) |

This was their solution:

Their way is very similar to mine. The main difference is that I used `occur`

for my second line to see whether there was more than 1 occurrence of the first element of the list within the entire list. So with the example `(apple peaches apple plum)`

, I’d check if `apple`

occurred more than once. Since it does, I return false. With their approach, they check if the first element of the list is a member of the remainder of the list. So with the same example, they’d check if `apple`

was a member of `(peaches apple plum)`

. Since it is, that indicates there are two copies of `apple`

, and so they return false. I think both approaches are fine.

## makeset

I tried but made an error:

1 2 3 4 5 6 7 8 9 |
(define mymakeset (lambda (lat) (cond ((null? lat) '()) ((member? (car lat) (cdr lat)) (mymakeset (cdr lat))) (else (cons (car lat) (mymakeset (cdr lat))))))) |

The output should be

The way I wrote my `member?`

line, the first copy of an atom in a list is being thrown out, but I actually want the second copy to be the one that isn’t included.

I figured out how to get the result I wanted with the following approach:

1 2 3 4 5 6 7 8 |
(define mymakeset (lambda (lat) (cond ((null? lat) '()) ((member? (car lat) (cdr lat)) (cons (car lat) (mymakeset (rember* (car lat) (cdr lat))))) (else (cons (car lat) (mymakeset (cdr lat))))))) |

This is similar to the earlier approach in some ways. The key difference is the use of the `rember*`

procedure to remove all subsequent instances of an atom from a list.

They want to use `multirember`

instead of `rember*`

.

They also made things shorter:

With the previous way of solving the problem, we cared whether `car lat`

was a member of `cdr lat`

because we only wanted to “skip” `cons`

ing the first element of the `lat`

together with the rest of the list when that first element was in fact a member of the rest of the list. But with `multirember`

, we can just call it for each `car lat`

recursively. If there are no duplicates, then `multirember`

just returns the whole second argument that it’s given. There’s no downside to just using it every time.

## subset?

They ask for a procedure that checks whether one set is a subset of another set, and they define that as each element of the first set appearing somewhere in the second set. My solution:

1 2 3 4 5 6 7 |
(define mysubset? (lambda (set1 set2) (cond ((null? set1) #t) ((member? (car set1) set2) (mysubset? (cdr set1) set2)) (else #f)))) |

Their shortened version of the procedure was exactly the same:

Next question:

This was my solution:

1 2 3 4 5 6 |
(define mysubset2? (lambda (set1 set2) (cond ((null? set1) #t) (else (and (member? (car set1) set2) (mysubset2? (cdr set1) set2)))))) |

Their solution was the same.

## eqset?

They want you to write `eqset?`

. My attempt:

1 2 3 4 5 6 7 8 |
(define myeqset? (lambda (set1 set2) (cond ((and (null? set1) (null? set2)) #t) ((member? (car set1) set2) (myeqset? (cdr set1) (rember (car set1) set2))) (else #f)))) |

I check if both sets are empty to make sure they have the same number of atoms.

If `car set1`

is a member of *set2*, I recursively call `myeqset?`

with the remainder of *set1* and a version of *set2* with the first instance of the value of *set1* removed by `rember`

. Otherwise, I return false.

A similar simplification as was used in the `subset`

procedure is possible here by using `and`

:

1 2 3 4 5 6 7 |
(define myeqset? (lambda (set1 set2) (cond ((and (null? set1) (null? set2)) #t) (else (and (member? (car set1) set2) (myeqset? (cdr set1) (rember (car set1) set2))))))) |

They had a different approach:

I like this approach and find it elegant.

I was not sure quite what they were getting at. It was apparently this:

A shorter version (that they agree with):

1 2 3 4 5 |
(define myeqset2? (lambda (set1 set2) (and (subset? set1 set2) (subset? set2 set1)))) |

## intersect?

My attempt:

1 2 3 4 5 6 7 |
(define myintersect? (lambda (set1 set2) (cond ((null? set1) #f) ((member? (car set1) set2) #t) (else (myintersect? (cdr set1) set2))))) |

This was the same as their shorter version.

1 2 3 4 5 6 7 |
(define myintersect2? (lambda (set1 set2) (cond ((null? set1) #f) (else (or (member? (car set1) set2)) (myintersect? (cdr set1) set2))))) |

Their version was the same.

## intersect

My attempt:

1 2 3 4 5 6 7 8 |
(define myintersect (lambda (set1 set2) (cond ((null? set1) '()) ((member? (car set1) set2) (cons (car set1) (myintersect (cdr set1) set2))) (else (myintersect (cdr set1) set2))))) |

Their version agrees with mine.

## union

My answer:

1 2 3 4 5 6 7 8 |
(define myunion (lambda (set1 set2) (cond ((null? set1) set2) ((member? (car set1) set2) (myunion (cdr set1) set2)) (else (cons (car set1) (myunion (cdr set1) set2)))))) |

Their solution was the same.

## mystery function

It returns elements that are unique to set 1. It is very similar to `union`

. The base case is different, though. Instead of returning the entirety of *set2* like in `union`

, this program returns the empty list. Since `xxx`

skips over any elements from *set1* that appear in *set2*, and only `cons`

es elements onto the new list it builds which appear only in *set1* and not in *set2*, returning the empty list when *set1* is null leads to a list being generated of only the items that are unique to *set1*.

## intersectall

Wasn’t sure how to proceed on this one.

Gonna walk through the first example with the lists of letters in order to understand what’s happening here.

So the base case would be when we have one list left, `(e f g h a b)`

. That’s when `cdr l-set`

would be null. In that case, we return `'(e f g h a b)`

.

So one recursive “step up”, we’d find the `intersect`

of `(c a d e)`

and `(e f g h a b)`

, which would be `(a e)`

. Then *that* value would be returned as the result of `intersectall`

one further recursive step up, and so we’d then find the `intersect`

of `(a b c)`

and `(a e)`

, which is `(a)`

.

## a-pair?

Here was my initial mistaken attempt at defining `a-pair?`

:

1 2 3 4 5 |
(define my-a-pair? (lambda (l) (null? (cdr (cdr l))))) |

I only caught one of the cases though:

If you give `a-pair?`

a single atom (like *3*), or the empty list, or an empty nested list `(())`

, my version returns an error message, whereas their version appropriately returns false.

## one-liners of pair functions

One-liners:

1 2 3 4 5 6 7 8 9 10 11 12 |
(define first (lambda (p) (car p))) (define second (lambda (p) (car (cdr p)))) (define build (lambda (s1 s2) (cons s1 (cons s2 '())))) |

My answer:

1 2 3 4 5 |
(define third (lambda (p) (car (cdr (cdr p))))) |

## rels and fun?

I’m not sure why the example with the question mark added isn’t a `rel`

. It seems like it should be considered a `rel`

, as it seems like a set of pairs.

Ok I think I figured it out. A *rel* is a list of pairs that is a set. A set is a list in which no value appears more than once. Since `apples peaches`

appears more than once in the list I wasn’t sure about, that list isn’t a *rel*. A value can appear as part of a pair more than once (for example, the number 4 appearing more than once in a list) and the list can still be a *rel*, as long as the full entry isn’t duplicated (e.g. as long as `(4 2)`

doesn’t appear twice).

a *function* for our purposes is a *rel* for which no first value in a pair appears more than once.

My attempt:

1 2 3 4 |
(define myfun? (lambda (rel) (set? (firsts rel)))) |

They agree.

## revrel

1 2 3 4 5 6 7 8 9 |
(define myrevrel (lambda (rel) (cond ((null? rel)'()) (else (cons (cons (car (cdr (car rel))) (cons (car (car rel)) '())) (myrevrel (cdr rel)) ))))) |

Their version was cleaner.

They also did my version, but they maintain that their version is more readable. I agree.

My solution:

1 2 3 4 5 6 7 |
(define myrevrel (lambda (rel) (cond ((null? rel)'()) (else (cons (myrevpair (car rel)) (myrevrel (cdr rel)) ))))) |

Their solution was the same.

## fullfun?

So they want you to write `fullfun?`

. I discovered that `seconds`

was a function while doing this.

1 2 3 4 |
(define myfullfun? (lambda (fun) (set? (seconds fun)))) |

They agreed 🙂

## seconds

They want you to define `seconds`

.

My approach:

1 2 3 4 5 6 7 |
(define myseconds (lambda (l) (cond ((null? (cdr l)) (cdr (car l))) (else (cons (second (car l)) (myseconds (cdr l))))))) |

We `cons`

the second value of the first pair/sublist onto the value of the recursive call to `myseconds`

with the rest of `l`

. Then when we get to the case where there’s only one pair left, we get the `cdr (car l)`

of that list, which returns the second value as a list. We actually want it as a list so we can `cons`

onto it.