i have a function in scheme, this function calls another function many times, and every time this function appends return value of another function to result value.
but finally i want to get a result such that '(a b c), however i get a result such that '((a) (b) (c)) how can i fix this problem? i have searched but i couldn't find good solution.
my little code like that not all of them.
(append res (func x))
(append res (func y))
(append res (func z))
my code like this
(define (check a )
'(1)
)
(define bos '())
(define (func a)
(let loop1([a a] [res '()])
(cond
[(eq? a '()) res]
[else (let ([ x (check (car a))])
(loop1 (cdr a) (append res (list x)))
)]
)
))
Try this:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) res]
[else
(let ([ x (check (car a))])
(loop1 (cdr a) (append res x)))])))
Notice that the only change I made (besides improving the formatting) was substituting (list x) with x. That will do the trick! Alternatively, but less portable - you can use append* instead of append:
(append* res (list x))
As a side comment, you should use (null? a) for testing if the list is empty. Now if we test the procedure using the sample code in the question, we'll get:
(func '(a b c))
=> '(1 1 1)
It seems that instead of
(loop1 (cdr a) (cdr b) c (append res (list x)))
you want
(loop1 (cdr a) (cdr b) c (append res x))
Basically the trick is to use cons instead of list. Imagine (list 1 2 3 4) which is the same as (cons 1 (cons 2 (cons 3 (cons 4 '())))). Do you see how each part is (cons this-iteration-element (recurse-further)) like this:
(define (make-list n)
(if (zero? n)
'()
(cons n (make-list (sub1 n)))))
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Usually when you can choose direction you can always make it tail recursive with an accumulator:
(define (make-list n)
(let loop ((x 1) (acc '()))
(if (> x n)
acc
(loop (add1 x) (cons x acc))))) ; build up in reverse!
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Now this is a generic answer. Applied to your working code:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) (reverse res)]
[else
(let ([x (check (car a))])
(loop1 (cdr a) (cons (car x) res)))])))
(func '(a b c)) ; ==> (1 1 1)
append replaces the cons so why not put the car og your result to the rest of the list. Since you want the result in order I reverse the result in the base case. (can't really tell from the result, but I guessed since you ise append)
Related
i am trying to write a function in Scheme that takes in a list and an integer and outputs the same list minus all the members less than the integer... please help. I seem to be unable to add the numbers into a new list that can be outputed.
(define result '())
(display result)
(define nums-less-than-x
(lambda (lst x)
(define impl
(lambda (l1 b result)
(if (null? l1) result
(begin (if (> b (car l1))
(begin (cons (car l1) result)
;(display result)(newline)(newline)
(display (car l1) )(newline))
)
(impl (cdr l1) b result)
))
))
(impl lst x result)
))
(display (show-up '(4 6 3 -8 3 4) 5))
The code juss displays (), an empty list like that, when I run
(display (num-less-than-x '(some list) x))
Your result is never updated. usually I would expect that only when the element is not being a part of the result and otherwise a recursion like:
(impl (cdr l1) b (cons (car l1) result))
I notice that you have put debug output as the last expression in a begin, eg.
(begin
expression-that-does-something
(display ...)
(newline))
Note that the expressions result is not the result, but the result from the newline, typically some undefined value. You need to put your debug stuff first then as the tail the expression your function should return. Alternatively you could make a debug function:
(define (debug expr)
(display expr)
(newline)
expr))
My understanding is that you want the procedure to return the result, not to display it, which is the right way to do it:
(define show-up
(lambda (lst mx)
(if (null? lst)
lst
(let ((c (car lst)))
(if (> c mx)
(show-up (cdr lst) mx)
(cons c (show-up (cdr lst) mx)))))))
Testing:
> (show-up '(4 6 3 -8 3 4) 5)
'(4 3 -8 3 4)
When programming in a functional style, we try to use existing procedures to solve a problem. With that in mind, the preferred solution would be:
(define (show-up-to-n lst x)
(filter (lambda (n) (< n x))
lst))
Also notice that in truly functional code we avoid at all costs procedures that modify state (such as set!), it's a better idea to create a new list with the result.
I'm finishing up a Scheme assignment and I'm having some trouble with the recursive cases for two functions.
The first function is a running-sums function which takes in a list and returns a list of the running sums i.e (summer '(1 2 3)) ---> (1 3 6) Now I believe I'm very close but can't quite figure out how to fix my case. Currently I have
(define (summer L)
(cond ((null? L) '())
((null? (cdr L)) '())
(else (cons (car L) (+ (car L) (cadr L))))))
I know I need to recursively call summer, but I'm confused on how to put the recursive call in there.
Secondly, I'm writing a function which counts the occurrences of an element in a list. This function works fine through using a helper function but it creates duplicate pairs.
(define (counts L)
(cond ((null? L) '())
(else (cons (cons (car L) (countEle L (car L))) (counts (cdr L))))))
(define (countEle L x)
(if (null? L) 0
(if (eq? x (car L)) (+ 1 (countEle (cdr L) x)) (countEle (cdr L) x))))
The expected output is:
(counts '(a b c c b b)) --> '((a 1) (b 3) ( c 2))
But it's currently returning '((a . 1) (b . 3) (c . 2) (c . 1) (b . 2) (b . 1)). So it's close; I'm just not sure how to handle checking if I've already counted the element.
Any help is appreciated, thank you!
To have a running sum, you need in some way to keep track of the last sum. So some procedure should have two arguments: the rest of the list to sum (which may be the whole list) and the sum so far.
(define (running-sum L)
(define (rs l s)
...)
(rs L 0))
For the second procedure you want to do something like
(define (count-elems L)
(define (remove-elem e L) ...)
(define (count-single e L) ...)
(if (null? L)
'()
(let ((this-element (car L)))
(cons (list this-element (count-single this-element L))
(count-elems (remove-elem this-element (cdr L)))))))
Be sure to remove the elements you've counted before continuing! I think you can fill in the rest.
To your first problem:
The mistake in your procedure is, that there is no recursive call of "summer". Have a look at the last line.
(else (cons (car L) (+ (car L) (cadr L))))))
Here is the complete solution:
(define (summer LL)
(define (loop sum LL)
(if (null? LL)
'()
(cons (+ sum (car LL)) (loop (+ sum (car ll)) (cdr LL)))))
(loop 0 LL))
(defun filter-numbers-rec (inlist)
"This function filters out non-numbers from its input list and returns
the result, a list of numbers"
(cond
((not (listp inlist))
(princ "Argument must be a list")
(terpri)
())
((null inlist)
())
((not (numberp (car inlist)))
(filter-numbers-rec (cdr inlist)))
(t
(cons (car inlist)
(filter-numbers-rec (cdr inlist))))))
Well, the description of what the function does is that you want to remove each thing from the the list if it is not a number, so a good candidate here is remove-if-not, which you would use as follows:
(remove-if-not 'numberp '(1 a 2 b 3 c #\x (y 4)))
;=> (1 2 3)
If, for some reason, you want to write this in a way that (might) not use recursion, you could use do:
(do ((list '(1 a 2 b 3 c #\x (y 4)) (rest list))
(result '()))
((endp list) (nreverse result))
(when (numberp (car list))
(push (car list) result)))
;=> (1 2 3)
If you don't like the wordiness of do, you can use loop:
(loop :for x :in '(1 a 2 b 3 c #\x (y 4))
:when (numberp x)
:collect x)
;=> (1 2 3)
Given a recursive function in scheme how do I change that function to tail recursive, and then how would I implement it using streams? Are there patterns and rules that you follow when changing any function in this way?
Take this function as an example which creates a list of numbers from 2-m (this is not tail recursive?)
Code:
(define listupto
(lambda (m)
(if (= m 2)
'(2)
(append (listupto (- m 1)) (list m)))))
I'll start off by explaining your example. It is definitely not tail recursive. Think of how this function executes. Each time you append you must first go back and make the recursive call until you hit the base case, and then you pull your way back up.
This is what a trace of you function would look like:
(listupto 4)
| (append (listupto(3)) '4)
|| (append (append (listupto(2)) '(3)) '(4))
||| (append (append '(2) '(3)) '(4))
|| (append '(2 3) '(4))
| '(2 3 4)
'(2 3 4)
Notice the V-pattern you see pulling in and then out of the recursive calls. The goal of tail recursion is to build all of the calls together, and only make one execution. What you need to do is pass an accumulator along with your function, this way you can only make one append when your function reaches the base case.
Here is the tail recursive version of your function:
(define listupto-tail
(lambda (m)
(listupto m '())))
# Now with the new accumulator parameter!
(define listupto
(lambda (m accu)
(if (= m 2)
(append '(2) accu)
(listupto (- m 1) (append (list m) accu)))))
If we see this trace, it will look like this:
(listupto 4)
| (listupto (3) '(4)) # m appended with the accu, which is the empty list currently
|| (listupto (2) '(3 4)) # m appended with accu, which is now a list with 4
||| (append '(2) '(3 4))
'(2 3 4)
Notice how the pattern is different, and we don't have to traverse back through the recursive calls. This saves us pointless executions. Tail recursion can be a difficult concept to grasp I suggest taking a look here. Chapter 5 has some helpful sections in it.
Generally to switch to a tail recursive form you transform the code so that it takes an accumulator parameter which builds the result up and is used as the final return value. This is generally a helper function which your main function delegates too.
Something of the form:
(define listupto
(lambda (m)
(listupto-helper m '())))
(define listupto-helper
(lambda (m l)
(if (= m 2)
(append '(2) l)
(listupto-helper (- m 1) (append (list m) l)))))
As the comments point out, the helper function can be replaced with a named let which is apparently (haven't done much/enough Scheme!) more idiomatic (and as the comments suggest cons is much better than creating a list and appending.
(define listupto
(lambda (n)
(let loop ((m n) (l '()))
(if (= m 2)
(append '(2) l)
(loop (- m 1) (cons m l))))))
You also ask about streams. You can find a SICP styled streams used e.g. here or here which have a from-By stream builder defined:
;;;; Stream Implementation
(define (head s) (car s))
(define (tail s) ((cdr s)))
(define-syntax s-cons
(syntax-rules ()
((s-cons h t) (cons h (lambda () t)))))
;;;; Stream Utility Functions
(define (from-By x s)
(s-cons x (from-By (+ x s) s)))
Such streams creation relies on macros, and they must be accessed by special means:
(define (take n s)
(cond ; avoid needless tail forcing for n == 1 !
((= n 1) (list (head s))) ; head is already forced
((> n 1) (cons (head s) (take (- n 1) (tail s))))
(else '())))
(define (drop n s)
(cond
((> n 0) (drop (- n 1) (tail s)))
(else s)))
But they aren't persistent, i.e. take and drop recalculate them on each access. One way to make streams persistent is to have a tailing closure surgically altering the last cons cell on access:
(1 . <closure>)
(1 . (2 . <closure>))
....
like this:
(define (make-stream next this state)
(let ((tcell (list (this state)))) ; tail sentinel cons cell
(letrec ((g (lambda ()
(set! state (next state))
(set-cdr! tcell (cons (this state) g))
(set! tcell (cdr tcell))
tcell)))
(set-cdr! tcell g)
tcell)))
(define (head s) (car s))
(define (tail s)
(if (or (pair? (cdr s))
(null? (cdr s)))
(cdr s)
((cdr s))))
We can now use it like this
(define a (make-stream (lambda (i) (+ i 1)) (lambda (i) i) 1))
;Value: a
a
;Value 13: (1 . #[compound-procedure 14])
(take 3 a)
;Value 15: (1 2 3)
a
;Value 13: (1 2 3 . #[compound-procedure 14])
(define b (drop 4 a))
;Value: b
b
;Value 16: (5 . #[compound-procedure 14])
a
;Value 13: (1 2 3 4 5 . #[compound-procedure 14])
(take 4 a)
;Value 17: (1 2 3 4)
a
;Value 13: (1 2 3 4 5 . #[compound-procedure 14])
Now, what does (make-stream (lambda (i) (list (cadr i) (+ (car i) (cadr i)))) car (list 0 1)) define?
update: in Daniel Friedman's 1994 slides "The Joys of Scheme, Cont'd" we find simpler implementation of these "memoized streams" (as they are called there), making the tail function itself store the forced stream in the tail sentinel, as
(define (tail s)
(if (or (pair? (cdr s))
(null? (cdr s)))
(cdr s)
(let ((n ((cdr s))))
(set-cdr! s n)
(cdr s))))
;; can be used as e.g. (https://ideone.com/v6pzDt)
(define fibs
(let next-fib ((a 0) (b 1))
(s-cons a (next-fib b (+ a b)))))
Here's a tail recursive form -
(define (listupto n)
(let run
((m 0)
(return identity))
(if (> m n)
(return null)
(run (add1 m)
(lambda (r) (return (cons m r)))))))
(listupto 9)
; '(0 1 2 3 4 5 6 7 8 9)
And here it is as a stream -
(define (listupto n)
(let run
((m 0))
(if (> m n)
empty-stream
(stream-cons m
(run (add1 m))))))
(stream->list (listupto 9))
; '(0 1 2 3 4 5 6 7 8 9)
Given a list of numbers, say, (1 3 6 10 0), how do you compute differences (xi - xi-1), provided that you have x-1 = 0 ?
(the result in this example should be (1 2 3 4 -10))
I've found this solution to be correct:
(define (pairwise-2 f init l)
(first
(foldl
(λ (x acc-data)
(let ([result-list (first acc-data)]
[prev-x (second acc-data)])
(list
(append result-list (list(f x prev-x)))
x)))
(list empty 0)
l)))
(pairwise-2 - 0 '(1 3 6 10 0))
;; => (1 2 3 4 -10)
However, I think there should be more elegant though no less flexible solution. It's just ugly.
I'm new to functional programming and would like to hear any suggestions on the code.
Thanks.
map takes multiple arguments. So I would just do
(define (butlast l)
(reverse (cdr (reverse l))))
(let ((l '(0 1 3 6 10)))
(map - l (cons 0 (butlast l)))
If you want to wrap it up in a function, say
(define (pairwise-call f init l)
(map f l (cons init (butlast l))))
This is of course not the Little Schemer Way, but the way that avoids writing recursion yourself. Choose the way you like the best.
I haven't done scheme in dog's years, but this strikes me as a typical little lisper type problem.
I started with a base definition (please ignore misplacement of parens - I don't have a Scheme interpreter handy:
(define pairwise-diff
(lambda (list)
(cond
((null? list) '())
((atom? list) list)
(t (pairwise-helper 0 list)))))
This handles the crap cases of null and atom and then delegates the meat case to a helper:
(define pairwise-helper
(lambda (n list)
(cond
((null? list) '())
(t
(let ([one (car list)])
(cons (- one n) (pairwise-helper one (cdr list))))
))))
You could rewrite this using "if", but I'm hardwired to use cond.
There are two cases here: null list - which is easy and everything else.
For everything else, I grab the head of the list and cons this diff onto the recursive case. I don't think it gets much simpler.
After refining and adapting to PLT Scheme plinth's code, I think nearly-perfect solution would be:
(define (pairwise-apply f l0 l)
(if (empty? l)
'()
(let ([l1 (first l)])
(cons (f l1 l0) (pairwise-apply f l1 (rest l))))))
Haskell tells me to use zip ;)
(define (zip-with f xs ys)
(cond ((or (null? xs) (null? ys)) null)
(else (cons (f (car xs) (car ys))
(zip-with f (cdr xs) (cdr ys))))))
(define (pairwise-diff lst) (zip-with - (cdr lst) lst))
(pairwise-diff (list 1 3 6 10 0))
; gives (2 3 4 -10)
Doesn't map finish as soon as the shortest argument list is exhausted, anyway?
(define (pairwise-call fun init-element lst)
(map fun lst (cons init-element lst)))
edit: jleedev informs me that this is not the case in at least one Scheme implementation. This is a bit annoying, since there is no O(1) operation to chop off the end of a list.
Perhaps we can use reduce:
(define (pairwise-call fun init-element lst)
(reverse (cdr (reduce (lambda (a b)
(append (list b (- b (car a))) (cdr a)))
(cons (list init-element) lst)))))
(Disclaimer: quick hack, untested)
This is the simplest way:
(define (solution ls)
(let loop ((ls (cons 0 ls)))
(let ((x (cadr ls)) (x_1 (car ls)))
(if (null? (cddr ls)) (list (- x x_1))
(cons (- x x_1) (loop (cdr ls)))))))
(display (equal? (solution '(1)) '(1))) (newline)
(display (equal? (solution '(1 5)) '(1 4))) (newline)
(display (equal? (solution '(1 3 6 10 0)) '(1 2 3 4 -10))) (newline)
Write out the code expansion for each of the example to see how it works.
If you are interested in getting started with FP, be sure to check out How To Design Program. Sure it is written for people brand new to programming, but it has tons of good FP idioms within.
(define (f l res cur)
(if (null? l)
res
(let ((next (car l)))
(f (cdr l) (cons (- next cur) res) next))))
(define (do-work l)
(reverse (f l '() 0)))
(do-work '(1 3 6 10 0))
==> (1 2 3 4 -10)