implement expand function with racket - scheme

I can't seem to figure out how to write this function. What I am trying to write is a function expand that takes a list lst as a parameter of the form '(a (2 b) (3 c)) and is evaluated to '(a b b c c c)

This looks like homework, so I'm not giving you a straight answer. Instead, I'll give you some pointers in the right direction. The most useful hint, is that you should split the problem in two procedures, one for processing the "outer" list and the other for generating the repetitions encoded in the inner sublists.
Notice that both procedures are mutually recursive (e.g., they call each other). The expand procedure recurs over the list, whereas the repeat procedure recurs over the number of repetitions. This is the general structure of the proposed solution, fill-in the blanks:
; input: lst - list to be processed
; output: list in the format requested
(define (expand lst)
(cond ((null? lst) ; if the list is null
'()) ; then return null
((not (pair? (car lst))) ; if the first element of the list is an atom
(cons <???> <???>)) ; cons the atom and advance the recursion
(else ; if the first element of the list is a list
<???>))) ; call `repeat` with the right params
; input: n - number of repetitions for the first element in the list
; lst - list, its first element is of the form (number atom)
; output: n repetitions of the atom in the first element of lst
(define (repeat n lst)
(if (zero? n) ; if the number of repetitions is zero
(expand (cdr lst)) ; continue with expand's recursion
(cons <???> ; else cons the atom in the first element and
<???>))) ; advance the recursion with one less repetition

As this was answered three years ago, I don't think that I am helping with homework. Would just like to point out that the two functions really don't need to be mutually recursive. As replicate is a fairly common function, I would propose:
(define (replicate what n)
(if (zero? n)
(list)
(cons what (replicate what (- n 1)))))
(define (my-expand xs)
(if (empty? xs)
(list)
(let ((x (first xs)))
(if (list? x)
(let ((the-number (first x))
(the-symbol (cadr x)))
(flatten (cons (replicate the-symbol the-number)
(my-expand (rest xs)))))
(cons x (my-expand (rest xs)))))))
Of course it is better to use two lists and perform the flatten at the end, something like this:
(define (my-expand xs)
(define (inner-expander xs ys)
(if (empty? xs) (flatten (reverse ys))
(let ((x (first xs)))
(if (list? x)
(let ((the-number (first x))
(the-symbol (cadr x)))
(inner-expander (rest xs) (cons (replicate the-symbol the-number) ys)))
(inner-expander (rest xs) (cons x ys))))))
(inner-expander xs (list)))

Related

Implement a function on scheme (racket) that returns all possible subsets of a given 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) '())

How to do a powerset in DrRacket?

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

how to delete third element in a list using scheme

This is what I want:
(delete-third1 '(3 7 5)) ==> (3 7)
(delete-third1 '(a b c d)) ==> (a b d)
so I did something like:
(define (delete-third1 LS ) (list(cdr LS)))
which returns
(delete-third1 '(3 7 5))
((7 5))
when it should be (3 7). What am I doing wrong?
Think about what cdr is doing. cdr says that "given a list, chop off the first value and return the rest of the list". So it's removing only the first value, then returning you the rest of that list (which is exactly what you are seeing). Since it returns a list, you don't need a list (cdr LS) there either.
What you want is something like this:
(define (delete-n l n)
(if (= n 0)
(cdr l)
(append (list (car l)) (delete-n (cdr l) (- n 1)))))
(define (delete-third l)
(delete-n l 2))
So how does this work? delete-n will delete the nth element of a list by keeping a running count of what element we are up to. If we're not up to the nth element, then add that element to the list. If we are, then skip that element and add the rest of the elements to our list.
Then we simply define delete-third as delete-n where it removes the 3rd element (which is element 2 when we start counting at 0).
The simplest way would be: cons the first element, the second element and the rest of the list starting from the fourth position. Because this looks like homework I'll only give you the general idea, so you can fill-in the blanks:
(define (delete-third1 lst)
(cons <???> ; first element of the list
(cons <???> ; second element of the list
<???>))) ; rest of the list starting from the fourth element
The above assumes that the list has at least three elements. If that's not always the case, validate first the size of the list and return an appropriate value for that case.
A couple more of hints: in Racket there's a direct procedure for accessing the first element of a list. And another for accessing the second element. Finally, you can always use a sequence of cdrs to reach the rest of the rest of the ... list (but even that can be written more compactly)
From a practical standpoint, and if this weren't a homework, you could implement this functionality easily in terms of other existing procedures, and even make it general enough to remove elements at any given position. For example, for removing the third element (and again assuming there are enough elements in the list):
(append (take lst 2) (drop lst 3))
Or as a general procedure for removing an element from a given 0-based index:
(define (remove-ref lst idx)
(append (take lst idx) (drop lst (add1 idx))))
Here's how we would remove the third element:
(remove-ref '(3 7 5) 2)
=> '(3 7)
This works:
(define (delete-third! l)
(unless (or (null? l)
(null? (cdr l))
(null? (cddr l)))
(set-cdr! (cdr l) (cdddr l)))
l)
if you want a version that does not modify the list:
(define (delete-third l)
(if (not (or (null? l)
(null? (cdr l))
(null? (cddr l))))
(cons (car l) (cons (cadr l) (cdddr l)))
l))
and if you want to do it for any nth element:
(define (list-take list k)
(assert (not (negative? k)))
(let taking ((l list) (n k) (r '()))
(if (or (zero? n) (null? l))
(reverse r)
(taking (cdr l) (- n 1) (cons (car l) r)))))
(define (delete-nth l n)
(assert (positive? n))
(append (list-take l (- n 1))
(if (> n (length l))
'()
(list-tail l n))))
(define (nth-deleter n)
(lambda (l) (delete-nth l n)))
(define delete-3rd (nth-deleter 3))

Simple Scheme, squaring all elements in a list

Okay, I'm new to Scheme and I thought I understood it, but got confused on this problem. I want to square all the elements of a list. So, (mapsq '(1 2 3)) returns (list 1 4 9).
my code:
(define mapsq
(lambda (ls)
(cond ((null? ls) 0)
(else (cons (car ls) (car ls))
(mapsq (cdr ls)))))))
In a practical (non-academic) context, this problem can be easily solved by using the map procedure:
(define mapsq
(lambda (ls)
(map (lambda (x) (* x x))
ls)))
Of course, if this is homework and you need to implement the solution from scratch, I shouldn't spoon-feed the answer. Better find out the solution by yourself, filling-in the blanks:
(define mapsq
(lambda (ls)
(cond ((null? ls) ; If the list is empty
<???>) ; ... then return the empty list.
(else ; Otherwise
(cons (* <???> <???>) ; ... square the first element in the list
(mapsq <???>)))))) ; ... and advance the recursion.
There are two problems in your solution: first, the base case should not return 0 - if we're building a list as an answer, then you must return the empty list. Second, in the recursive step you aren't actually squaring the current element in the list - to do that just multiply it by itself with the * operator.
You could write it like this:
(define (mapsq xs)
(define (square x) (* x x))
(map square xs))
Or this:
(define (mapsq xs)
(map (lambda (x) (* x x)) xs))
Or maybe like this:
(define (mapsq xs)
(let loop ((xs xs) (sqs '()))
(if (null? xs)
(reverse sqs)
(loop (cdr xs) (cons (* (car xs) (car xs)) sqs)))))
Or even like this:
(define (mapsq xs)
(if (null? xs)
'()
(cons (* (car xs) (car xs)) (mapsq (cdr xs)))))
My preference would be the first option. The second option is shorter, but the auxiliary function makes the first option easier to read. I would probably not use either the third or fourth options.
By the way, the solution by laser_wizard doesn't work, either.
I notice that you're new here. If you like an answer, click the up arrow next to the answer so the person who gave the answer gets points; this mark also lets the community of readers know that there is something of value in the answer. Once you have an answer that you are confident is correct, click the check mark next to the answer; that also gives points to the person that gave the answer, and more importantly lets other readers know that you believe this answer most correctly addresses your question.
(define (mapsq xs)
(map * xs xs))
> (mapsq '(1 2 3 4 5))
'(1 4 9 16 25)

Scheme append procedure

I'm having trouble appending a list to another list. Below is my code. When I run (append '(1 2) '(3 4)) I get '(1 3 2 4).
I want the output to be '(1 2 3 4)
(define (append l m)
(if (null? l) '()
(cons (car l) (append m (cdr l)))))
Thanks
Well by switching the two lists around like that (switching the position of m and l when calling append recursively), you'll get the first item of the first list followed by the first item of the second list etc.
If you don't want that, you should keep l as the first argument and m as the second. So you get:
(define (append l m)
(if (null? l) '()
(cons (car l) (append (cdr l) m))))
Of course this doesn't work as wanted either, because now you only get the first list back and nothing is appended at all. What you need to do is, once the first list is fully appended (i.e. once l is empty), you need to return the second one as the tail, like this:
(define (append l m)
(if (null? l) m
(cons (car l) (append (cdr l) m))))
I came across this while studying myself. #sepp2k's answer is a fine piece of instruction guiding OP to correct their code to achieve a recursive definition of append. Here's an alternate definition of my-append using the higher-order function foldr:
(define (myappend xs ys)
(foldr cons ys xs))

Resources