about a small program - scheme

Consider the following program. It's supposed to take a list of strings, and return a string whose characters are the first character from each string. For instance, (downward (cons "caa" (cons "abbb" empty)) should return "ca". Why do I keep getting an error?
(define (downward l)
(cond
[(empty? l) ""]
[else (substring (first l) 0 1
(downward (rest l)))]))

You're correctly iterating over the input, but forgot to "stick together" each part of the output. In this case, string-append will allow you to put together all the elements of the answer:
(define (downward l)
(cond
[(empty? l) ""]
[else (string-append (substring (first l) 0 1)
(downward (rest l)))]))
This is how it works:
(downward '("caa" "abbb"))
=> "ca"
On second thought, the question is a bit ambiguous. Do you want a string as the output? or a list? If it's a list, you only have to change the base case and the "sticking" procedure - use cons for building lists, in the same way that string-append is useful for building strings:
(define (downward l)
(cond
[(empty? l) empty]
[else (cons (substring (first l) 0 1)
(downward (rest l)))]))
(downward '("caa" "abbb"))
=> '("c" "a")

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

Scheme - n-ary subtraction function issues

I have the following n-ary function I defined:
(define (- . l)
(cond ((null? l) 0)
(else (b- (car l) (apply - (cdr l))))))
It works fine for two arguments, but anymore and it starts to add numbers in a strange way and I don't understand why.
Alternatively, I have a check implemented in a different version of this function in case there is only one argument:
(define (- . l)
(cond ((null? (cdr l)) (b- (b* l 2) l))
(else (b- (car l) (apply - (cdr l))))))
This second one does not work at all when I change the first condition.
Input should be something like (- 10 6 1)
I assume that b- is a binary subtraction, and that you want to mimic the usual subtraction of Scheme, which is a function such that:
with no arguments, gives an error,
with an argument, changes the sign of the argument,
with more than one argument, substracts from the first one all the others.
Here is a possibile solution (note that I've called the function n-):
(define (n- . l)
(define (aux l dec)
(if (null? l)
dec
(aux (cdr l) (b- dec (car l)))))
(cond ((null? l) (println "Error"))
((null? (cdr l)) (b- 0 (car l)))
(else (aux (cdr l) (car l)))))
(n-) ; => Error
(n- 3) ; => -3
(n- 10 6 1) ; => 3
(n- 11 4 8 2) ; => -3
The auxiliary function subtracts all the numbers from the list first argument to its second argument, and it is defined as a tail recursive function, so that it can be implemented in an iterative way.
The sane way to implement - is by using case-lambda, so that the unary, binary, and variadic cases can be handled separately:
(define -
(case-lambda
((a) (b- 0 a))
((a b) (b- a b))
((a b . rest) (apply - (b- a b) rest))))
Now, if you don't have case-lambda, then you'll have more work to do:
(define (- a . rest)
(if (null? rest)
(b- 0 a)
(let loop ((result a)
(rest rest))
(if (null? rest)
result
(loop (b- result (car rest)) (cdr rest))))))
This special-cases unary invocation to negate; otherwise, it iterates, using the first argument as the initial result, and updates the result by subtraction each time.

recursion over list of characters in scheme

I have found a recursive problem in one page that says the following:
If a person enter a string with two consecutive letters that are the same, it should put a 5 between them. For example if I enter "hello"
it should print "hel5lo"
I have done the following program in Scheme:
(define (function listT)
(if (empty? listT)
'()
(begin
(if (eq? (car listT) (car (cdr listT)))
(display 5)
(display (car listT))
)))
(function (cdr listT)))
and tested with:
(function'( 'h 'e 'l 'l 'o))
and the problem I got is
car: contract violation
expected: pair?
given: ()
I suppose that is because at one moment (car (cdr listT)) will face an empty list, have tried with a conditional before, but still with some issues.
Is it possible to do it only using recursion over the list of characters with cdr and car? I mean not with new variables, strings, using reverse or loops?
Any help?
Thanks
This happens when there is only one character left in the list; (cdr listT) will be the empty list '() and the car of the empty list is undefined.
So you either need to check that the cdr isn't empty, for example:
(define (f str)
(let loop ((lst (string->list str)) (res '()))
(if (null? lst)
(list->string (reverse res))
(let ((c (car lst)))
(loop (cdr lst)
(cons c
(if (and (not (null? res)) (char=? c (car res)))
(cons #\5 res)
res)))))))
or, instead of looking one character ahead, turn around your logic and keep track of the last character, which is initialised to some value that will be different in every case (not as elegant as the first solution though IMO):
(define (f str)
(list->string
(let loop ((prev #f) (lst (string->list str)))
(if (null? lst)
'()
(let ((c (car lst)))
(if (equal? c prev)
(cons #\5 (cons c (loop c (cdr lst))))
(cons c (loop c (cdr lst)))))))))
[EDIT alternatively, with an explicit inner procedure:
(define (f str)
(define (inner prev lst)
(if (null? lst)
'()
(let ((c (car lst)))
(if (equal? c prev)
(cons #\5 (cons c (inner c (cdr lst))))
(cons c (inner c (cdr lst)))))))
(list->string (inner #f (string->list str))))
]
Testing:
> (f "hello")
"hel5lo"
> (f "helo")
"helo"
> (f "heloo")
"helo5o"
Side note: don't double quote:
> '('h 'e 'l 'l 'o)
'('h 'e 'l 'l 'o)
> (car '('h 'e 'l 'l 'o))
''h
This is probably not what you expected. Instead:
> '(h e l l o)
'(h e l l o)
> (car '(h e l l o))
'h
or
> (list 'h 'e 'l 'l 'o)
'(h e l l o)
> (car (list 'h 'e 'l 'l 'o))
'h
Also note that these are symbols, whereas, since you start from a string, you want characters:
> (string->list "hello")
'(#\h #\e #\l #\l #\o)
EDIT 2
I see you are still struggling with my answer. Here's a solution that should be as minimal as you requested, I hope this is it:
(define (f lst (prev #f))
(unless (null? lst)
(when (equal? (car lst) prev) (display "5"))
(display (car lst))
(f (cdr lst) (car lst))))
or even
(define (f lst)
(unless (null? lst)
(display (car lst))
(when (and (not (null? (cdr lst))) (equal? (car lst) (cadr lst)))
(display "5"))
(f (cdr lst))))
Testing:
> (f '(h e l l o))
hel5lo
> (f '(h e l o))
helo
> (f '(h e l o o))
helo5o
I have found a solution:
(define (func lisT)
(if (empty? (cdr lisT))
(display (car lisT))
(begin
(if (eq? (car lisT) (car (cdr lisT)))
(begin
(display (car lisT))
(display 5)
)
(display (car lisT))
)
(func (cdr lisT))
)
))
Here's a solution including just one, top-level recursive function:
(define (insert list item)
(if (< (length list) 2) ;; not enough elements to compare?
list ;; then just return the input
(let ((first (car list)) ;; capture the first element,
(second (cadr list)) ;; the second element,
(rest (insert (cdr list) item))) ;; and the recursively processed tail
(cons first ;; construct a list with the first element
(if (eq? first second) ;; compare the first two and return either
(cons item rest) ;; the item before the rest
rest))))) ;; or just the rest
It takes as input a list and an item to be inserted between each two consecutive identical elements. It does not display anything, but rather returns another list with the result of the insertion. For example,
(insert '(1 2 2 3 3 3 2 2 1) 0)
results in
(1 2 0 2 3 0 3 0 3 2 0 2 1)
This hopefully solves your problem and seeds further experimentation.
Here is a straightforward function from a list to a list:
(define (add5s s)
(cond ((null? s) s)
((null? (cdr s)) s)
((equal? (car s) (cadr s)) (cons (car s) (cons 5 (add5s (cdr s)))))
(else (cons (car s) (add5s (cdr s))))
)
)
A list either:
is null
has one element
begins with two equal elements
begins with two unequal elements
A list with a 5 put between consecutive equal elements is respectively:
the list
the list
the first element followed by a 5 followed by the rest of it with a 5 put between consecutive equal elements
the first element followed by the rest of it with a 5 put between consecutive equal elements
A Scheme string is not a list of characters or a list of symbols. If you want to input and output strings then you should use the corresponding string operators. Or write a function that defines this one, calls it with string->list of an input string and outputs list->string of this one's result list. Or a function like this one but that branches on string->list of its input string and outputs list->string of what this one returns.
(It is really not clear what code is to be written. You say "enters a string", but your "tested" code is a function that takes a list as argument, rather than reading from a port. And you say "put a 5" but you print argument list elements or a 5 via display to a port, rather than returning a value of the type of the argument. And you give an example passing an argument that is a list of quoted symbols rather than just symbols let alone characters. (If you want to pass a list of symbols then use '(h e l l o) or (list 'h 'e 'l 'l 'o).) Say exactly what is to be produced, eg, a function with what arguments, return value and effect on ports.)

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 define last in scheme?

how can I write a function to take the last element of the list?
find the last of a list:
(define (last l)
(cond ((null? (cdr l)) (car l))
(else (last (cdr l)))))
use map to map last to a list:
(map last '((a b) (c d) (e f)))
==> (b d f)
so a new function:
(define (last-list l)
(map last l)
)
(last-list '((a b) (c d) (e f)))
==> (b d f)
May not be the most efficient, but certainly one of the simplest:
(define (last lst)
(car (reverse lst)))
Examples:
(last '(1 2 3 4)) => 4
(last '((a b) (b c) (d e))) => (d e)
The code you've written - to take the last element of a list - is correctly returning the last element of the list. You have a list of lists. There is an outer list
(x y z)
where
x = (a b)
y = (c d)
z = (e f)
So you're getting the last element of the list, z, which is (e f)
Did you want your last function to do something different? If you want it to return the last element of the last nested list, you need to change your base case. Right now you return the car. Instead, you want to check if the car is a list and then call your nested-last function on that.
Make sense?
Your last function is good, but you have to think about what you want to do with it now.
You have a list of lists, and you want to take the last of all those.
So recurse down your list applying it each time:
(define (answer lst)
(cond ((null? (cdr l)) null)
(else (cons (last (car l)) (answer (cdr lst))))
Yet another possibility:
(define (last thelist)
(if
(null? (cdr thelist)) (car thelist)
(last (cdr thelist))))
(define (all-last lists) (map last lists))
Edit: just saw that you don't know map, and want a solution without it:
(define (all-last lists)
(if
(null? lists) `()
(cons (last (car lists)) (all-last (cdr lists)))))
As far as getting an empty list goes, I'd guess you're trying to use this map-like front-end with your original definition of last, whereas it's intended to work with the definition of last I gave above. Try the following definitions:
(define (last thelist) (if
(null? (cdr thelist)) (car thelist)
(last (cdr thelist))))
(define (all-last lists) (if
(null? lists) `()
(cons (last (car lists)) (all-last (cdr lists)))))
and running a quick test:
(all-last `((a b) (c d) (e f)))
The result should be:
(b d f)
(define last
(lambda (ls)
(list-ref ls (- (length ls) 1))))
I like short, sweet, fast, tail-recursive procedures.
Named let is my friend.
This solves the original problem and returns #f if the list has no last element.
(define (last L) (let f ((last #f) (L L)) (if (empty? L) last (f (car L) (cdr L)))))
The best way to get what you want:
(define (last lst)
(cond [(empty? lst) empty]
[(empty? (rest lst)) (first lst)]
[else (last (rest lst))]))

Resources