Racket recursive variable? - recursion

Fig. 65 in "How to Design Programs" is as follows:
; Nelon -> Number
; determines the smallest number on l
(define (inf l)
(cond
[(empty? (rest l)) (first l)]
[else
(local ((define smallest-in-rest (inf (rest l))))
(cond
[(< (first l) smallest-in-rest) (first l)]
[else smallest-in-rest]))]))
Can somebody explain how variable smallest-in-rest works. I get recursion in a function but a variable has me confused

It's just a shorthand (longhand ;-)) for the following:
(let ((smallest-in-rest (inf (rest l))))
(cond
[(< (first l) smallest-in-rest) (first l)]
[else smallest-in-rest]))
The let should make it clear that we're just storing the result of the (inf (rest l)) so that it only has to be written once in the code, rather than once for each branch of the cond.

Related

Sort an element and put it in a variable

I have fowling task:
Write a recursive function SORT-LIST which, from a list of any number of "apples" and "peas", sorts out the "apples" and stores them in an optional variable and at the end returns the contents of this optional variable.
I have no idea how to fix ist. That's my beginning. Maybe there is someone who could help me. Thanks a lot!!
(defun sort-list (x l)
(cond ((null l) nil))
((equal (first l) x)
(cons (first l) (sort-list x (rest l))))
((sort-list x (rest l))))
The name is misleading. It is not sort but actually a filter.
(defun applep (x)
"something looking whether x is an apple or not")
(defun my-filter (pred l &optionals (acc '()))
(cond ((null l) (nreverse acc))
((funcall pred (car l)) (my-filter pred (cdr l) (cons (car l) acc)))
(t (my-filter pred (cdr l) acc))))
Which is in-built in lisps - so even without defining it, you could run:
(filter #'applep l)

Member function for nested list in Scheme

Can someone show me the error in this code please?
I want to generalize the member function to support nested lists. I need to search thing inside the nested list and return the rest of the list when I found thing. I don't really understand whats wrong with the code below.
(define (memberk thing lis)
(cond
((null? lis) #f)
((list? (car lis))
(cons (memberk thing (car lis))
(memberk thing (cdr lis))))
(else
(if (equal? (car lis) thing)
lis
(memberk thing (cdr lis))))))
Expexted output: (memberk 3 '(1 4 (3 1) 2)) = '((3 1) 2)
Actual output from the code above: '((3 1) . #f)
So how I see this you would like the top level cons that has the key found somewhere in car. I'm thinking something like:
(define (memberk needle lst)
(define (found? haystack)
(or (equal? needle haystack)
(and (pair? haystack)
(or (found? (car haystack))
(found? (cdr haystack))))))
(let loop ((lst lst))
(cond ((null? lst) #f)
((found? (car lst)) lst)
(else (loop (cdr lst))))))
(memberk '(a) '(a b (b (a) c) c d)) ; ==> ((b (a) c) c d)
Something like this?
It is a bit unclear what you want - since there is only one test case.
(define (memberk thing lis)
(cond
[(null? lis)
#f]
[(and (cons? (car lis)) (memberk thing (car lis)))
=> (λ (found) (cons found (cdr lis)))]
[(equal? (car lis) thing)
lis]
[else
(memberk thing (cdr lis))]))

Recursive function to calculate the powerset of a set [duplicate]

I'm using the beginning language with list abbreviations for DrRacket and want to make a powerset recursively but cannot figure out how to do it. I currently have this much
(define
(powerset aL)
(cond
[(empty? aL) (list)]
any help would be good.
What's in a powerset? A set's subsets!
An empty set is any set's subset,
so powerset of empty set's not empty.
Its (only) element it is an empty set:
(define
(powerset aL)
(cond
[(empty? aL) (list empty)]
[else
As for non-empty sets, there is a choice,
for each set's element, whether to be
or not to be included in subset
which is a member of a powerset.
We thus include both choices when combining
first element with smaller powerset,
that, which we get recursively applying
the same procedure to the rest of input:
(combine (first aL)
(powerset (rest aL)))]))
(define
(combine a r) ; `r` for Recursive Result
(cond
[(empty? r) empty] ; nothing to combine `a` with
[else
(cons (cons a (first r)) ; Both add `a` and
(cons (first r) ; don't add, to first subset in `r`
(combine ; and do the same
a ; with
(rest r))))])) ; the rest of `r`
"There are no answers, only choices". Rather,
the choices made, are what the answer's made of.
In Racket,
#lang racket
(define (power-set xs)
(cond
[(empty? xs) (list empty)] ; the empty set has only empty as subset
[(cons? xs) (define x (first xs)) ; a constructed list has a first element
(define ys (rest xs)) ; and a list of the remaining elements
;; There are two types of subsets of xs, thouse that
;; contain x and those without x.
(define with-out-x ; the power sets without x
(power-set ys))
(define with-x ; to get the power sets with x we
(cons-all x with-out-x)) ; we add x to the power sets without x
(append with-out-x with-x)])) ; Now both kind of subsets are returned.
(define (cons-all x xss)
; xss is a list of lists
; cons x onto all the lists in xss
(cond
[(empty? xss) empty]
[(cons? xss) (cons (cons x (first xss)) ; cons x to the first sublist
(cons-all x (rest xss)))])) ; and to the rest of the sublists
To test:
(power-set '(a b c))
Here's yet another implementation, after a couple of tests it appears to be faster than Chris' answer for larger lists. It was tested using standard Racket:
(define (powerset aL)
(if (empty? aL)
'(())
(let ((rst (powerset (rest aL))))
(append (map (lambda (x) (cons (first aL) x))
rst)
rst))))
Here's my implementation of power set (though I only tested it using standard Racket language, not Beginning Student):
(define (powerset lst)
(if (null? lst)
'(())
(append-map (lambda (x)
(list x (cons (car lst) x)))
(powerset (cdr lst)))))
(Thanks to samth for reminding me that flatmap is called append-map in Racket!)
You can just use side effect:
(define res '())
(define
(pow raw leaf)
(cond
[(empty? raw) (set! res (cons leaf res))
res]
[else (pow (cdr raw) leaf)
(pow (cdr raw) (cons (car raw) leaf))]))
(pow '(1 2 3) '())

Return value in Lisp

So i started learning Lisp yesterday and started doing some problems.
Something I'm having a hard time doing is inserting/deleting atoms in a list while keeping the list the same ex: (delete 'b '(g a (b) l)) will give me (g a () l).
Also something I'm having trouble with is this problem.
I'm suppose to check if anywhere in the list the atom exist.
I traced through it and it says it returns T at one point, but then gets overriden by a nil.
Can you guys help :)?
I'm using (appear-anywhere 'a '((b c) g ((a))))
at the 4th function call it returns T but then becomes nil.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Let's look at one obvious problem:
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Think about the last line of above.
Let's format it slightly differently.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T
(appear-anywhere a (car l))
(appear-anywhere a (cdr l)))))
The last three lines: So as a default (that's why the T is there) the last two forms will be computed. First the first one and then the second one. The value of the first form is never used or returned.
That's probably not what you want.
Currently your code just returns something when the value of a appears anywhere in the rest of the list. The first form is never really used.
Hint: What is the right logical connector?

Scheme Recursively going through a List

Just trying to get back into the swing of scheme again, because everyone loves recursion.. (mhhmnmm.)
anyways trying to return #t or #f to determine whether all elements in a list are unique.
Comparing 1st element and 2nd element no problem. It's recursively continuing..
(define (unique ls)
(if (null? ls) #t
(equal? (car ls)(car(cdr ls)))))
I'll write a different, simpler function that demonstrates looping. Hopefully between that and what you have, you'll get there. :-)
(define (member x lst)
(cond ((null? lst) #f)
((equal? x (car lst)) lst)
(else (member x (cdr lst)))))
Another example:
(define (assoc x alist)
(cond ((null? alist) #f)
((equal? x (caar alist)) (car alist))
(else (assoc x (cdr alist)))))
Well your (equal?) invocation is incomplete. If the head and head-of-the-tail are equal, then the value of "unique" is false. If they're not equal, then you'd return the value of unique as applied to the tail (cdr) of the list.
(It's implicit in your proto-implementation that you're checking a pre-sorted list. If not, then that's another step to take.)
(use srfi-1)
(define (unique? ls) (eq? (length ls) (length (delete-duplicates ls))))

Resources