I have the following 2 functions that I wish to combine into one:
(defun fib (n)
(if (= n 0) 0 (fib-r n 0 1)))
(defun fib-r (n a b)
(if (= n 1) b (fib-r (- n 1) b (+ a b))))
I would like to have just one function, so I tried something like this:
(defun fib (n)
(let ((f0 (lambda (n) (if (= n 0) 0 (funcall f1 n 0 1))))
(f1 (lambda (a b n) (if (= n 1) b (funcall f1 (- n 1) b (+ a b))))))
(funcall f0 n)))
however this is not working. The exact error is *** - IF: variable F1 has no value
I'm a beginner as far as LISP goes, so I'd appreciate a clear answer to the following question: how do you write a recursive lambda function in lisp?
Thanks.
LET conceptually binds the variables at the same time, using the same enclosing environment to evaluate the expressions. Use LABELS instead, that also binds the symbols f0 and f1 in the function namespace:
(defun fib (n)
(labels ((f0 (n) (if (= n 0) 0 (f1 n 0 1)))
(f1 (a b n) (if (= n 1) b (f1 (- n 1) b (+ a b)))))
(f0 n)))
You can use Graham's alambda as an alternative to labels:
(defun fib (n)
(funcall (alambda (n a b)
(cond ((= n 0) 0)
((= n 1) b)
(t (self (- n 1) b (+ a b)))))
n 0 1))
Or... you could look at the problem a bit differently: Use Norvig's defun-memo macro (automatic memoization), and a non-tail-recursive version of fib, to define a fib function that doesn't even need a helper function, more directly expresses the mathematical description of the fib sequence, and (I think) is at least as efficient as the tail recursive version, and after multiple calls, becomes even more efficient than the tail-recursive version.
(defun-memo fib (n)
(cond ((= n 0) 0)
((= n 1) 1)
(t (+ (fib (- n 1))
(fib (- n 2))))))
You can try something like this as well
(defun fib-r (n &optional (a 0) (b 1) )
(cond
((= n 0) 0)
((= n 1) b)
(T (fib-r (- n 1) b (+ a b)))))
Pros: You don't have to build a wrapper function. Cond constructt takes care of if-then-elseif scenarios. You call this on REPL as (fib-r 10) => 55
Cons: If user supplies values to a and b, and if these values are not 0 and 1, you wont get correct answer
Related
what is the required recursive function(s) in Scheme programming language to compute the following series?? Explanation needed
1^2/2^1 + 3^4/4^3 + 5^6/6^5 + 7^8/8^7 + 9^10/10^9
So, well, what does each term look like? It's n^(n+1)/(n+1)^n. And you want to stop when you reach 10 (so if n > 10, stop). So write a function of a single argument, n, which either:
returns 0 if n > 10;
adds n^(n+1)/(n+1)^n to the result of calling itself on n + 2.
Then this function with argument 1 will compute what you want. Going backwards may be easier:
return 0 if n < 1;
add n^(n+1)/(n+1)^n to the result of calling itself on n - 2;
then the function with argument 10 is what you want.
Or you could do this which is more entertaining:
(define s
(λ (l)
((λ (c i a)
(if (> i l)
a
(c c
(+ i 2)
(+ a (/ (expt i (+ i 1))
(expt (+ i 1) i))))))
(λ (c i a)
(if (> i l)
a
(c c
(+ i 2)
(+ a (/ (expt i (+ i 1))
(expt (+ i 1) i))))))
1 0)))
But I don't recommend it.
//power function
(define (power a b)
(if (zero? b) //base case
1
(* a (power a (- b 1))))) //or return power of a,b
// sum function for series
(define (sum n)
(if (< n 3) //base case
0.5
(+ (/ (power (- n 1) n) (power n (- n 1))) (sum (- n 2 )) ))) //recursion call
>(sum 10) // call sum function here .
I am reading sicp, there's a problem (practice 1.29), I write a scheme function to solve the the question, but it seems that the recursive call of the function get the wrong answer. Really strange to me. The code is following:
(define simpson
(lambda (f a b n)
(let ((h (/ (- b a) n))
(k 0))
(letrec
((sum (lambda (term start next end)
(if (> start end)
0
(+ (term start)
(sum term (next start) next end)))))
(next (lambda (x)
(let ()
(set! k (+ k 1))
(+ x h))))
(term (lambda (x)
(cond
((= k 0) (f a))
((= k n) (f b))
((even? k) (* 2
(f x)))
(else (* 4
(f x)))))))
(sum term a next b)))))
I didn't get the right answer.
For example, if I try to call the simpson function like this:
(simpson (lambda (x) x) 0 1 4)
I expected to get the 6, but it returned 10 to me, I am not sure where the error is.It seems to me that the function "sum" defined inside of Simpson function is not right.
If I rewrite the sum function inside of simpson using the iteration instead of recursive, I get the right answer.
You need to multiply the sum with h/3:
(* 1/3 h (sum term a next b))
I'm starting to get to grips with Lisp and I'm trying to write a procedure to approximate pi using the Leibniz formula at the moment; I think I'm close but I'm not sure how to proceed. The current behavior is that it makes the first calculation correctly but then the program terminates and displays the number '1'. I'm unsure if I can call a defined function recursively like this,
;;; R5RS
(define (pi-get n)
(pi 0 1 n 0))
(define (pi sum a n count)
;;; if n == 0, 0
(if (= n 0) 0)
;;; if count % 2 == 1, + ... else -, if count == n, sum
(cond ((< count n)
(cond ((= (modulo count 2) 1)
(pi (+ sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1)))
(pi
(- sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1))))))
(define (pi-calc a)
(/ 1.0 a))
Apologies if this is a little unreadable, I'm just learning Lisp a few weeks now and I'm not sure what normal formatting would be for the language. I've added a few comments to hopefully help.
As Sylwester mentioned it turned out to be a mistake on my part with syntax.
;;; R5RS
(define (pi-get n)
(pi 1 1 n 0))
(define (pi sum a n count)
(if (= n 0) 0)
(cond ((< count n)
(cond ((= (modulo count 2) 1)
(pi (+ sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1)))
((= (modulo count 2) 0)
(pi (- sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1))))
(display (* 4 sum)) (newline))))
(define (pi-calc a)
(/ 1.0 a))
I'm a newbie in LISP. I'm trying to write a function in CLISP to generate the first n numbers of Fibonacci series.
This is what I've done so far.
(defun fibonacci(n)
(cond
((eq n 1) 0)
((eq n 2) 1)
((+ (fibonacci (- n 1)) (fibonacci (- n 2))))))))
The program prints the nth number of Fibonacci series. I'm trying to modify it so that it would print the series, and not just the nth term.
Is it possible to do so in just a single recursive function, using just the basic functions?
Yes:
(defun fibonacci (n &optional (a 0) (b 1) (acc ()))
(if (zerop n)
(nreverse acc)
(fibonacci (1- n) b (+ a b) (cons a acc))))
(fibonacci 5) ; ==> (0 1 1 2 3)
The logic behind it is that you need to know the two previous numbers to generate the next.
a 0 1 1 2 3 5 ...
b 1 1 2 3 5 8 ...
new-b 1 2 3 5 8 13 ...
Instead of returning just one result I accumulate all the a-s until n is zero.
EDIT Without reverse it's a bit more inefficient:
(defun fibonacci (n &optional (a 0) (b 1))
(if (zerop n)
nil
(cons a (fibonacci (1- n) b (+ a b)))))
(fibonacci 5) ; ==> (0 1 1 2 3)
The program prints the nth number of Fibonacci series.
This program doesn't print anything. If you're seeing output, it's probably because you're calling it from the read-eval-print-loop (REPL), which reads a form, evaluates it, and then prints the result. E.g., you might be doing:
CL-USER> (fibonacci 4)
2
If you wrapped that call in something else, though, you'll see that it's not printing anything:
CL-USER> (progn (fibonacci 4) nil)
NIL
As you've got this written, it will be difficult to modify it to print each fibonacci number just once, since you do a lot of redundant computation. For instance, the call to
(fibonacci (- n 1))
will compute (fibonacci (- n 1)), but so will the direct call to
(fibonacci (- n 2))
That means you probably don't want each call to fibonacci to print the whole sequence. If you do, though, note that (print x) returns the value of x, so you can simply do:
(defun fibonacci(n)
(cond
((eq n 1) 0)
((eq n 2) 1)
((print (+ (fibonacci (- n 1)) (fibonacci (- n 2)))))))
CL-USER> (progn (fibonacci 6) nil)
1
2
1
3
1
2
5
NIL
You'll see some repeated parts there, since there's redundant computation. You can compute the series much more efficiently, however, by starting from the first two numbers, and counting up:
(defun fibonacci (n)
(do ((a 1 b)
(b 1 (print (+ a b)))
(n n (1- n)))
((zerop n) b)))
CL-USER> (fibonacci 6)
2
3
5
8
13
21
An option to keep the basic structure you used is to pass an additional flag to the function that tells if you want printing or not:
(defun fibo (n printseq)
(cond
((= n 1) (if printseq (print 0) 0))
((= n 2) (if printseq (print 1) 1))
(T
(let ((a (fibo (- n 1) printseq))
(b (fibo (- n 2) NIL)))
(if printseq (print (+ a b)) (+ a b))))))
The idea is that when you do the two recursive calls only in the first you pass down the flag about doing the printing and in the second call instead you just pass NIL to avoid printing again.
(defun fib (n a b)
(print (write-to-string n))
(print b)
(if (< n 100000)
(funcall (lambda (n a b) (fib n a b)) (+ n 1) b (+ a b)))
)
(defun fibstart ()
(fib 1 0 1)
)
I want to program a function to find C(n,k) using tail recursion, and I would greatly appreciate your help.
I have reached this:
(defun tail-recursive-binomial (n k)
(cond ((or (< n k) (< k 0)) NIL)
((or (= k 0) (= n k)) 1)
(T (* (tail-recursive-binomial (- n 1) (- k 1)) (/ n k)))))
Using the following property of the binomial coefficients.
But I don't know how to make the recursive call to be the last instruction executed by each instance, since there the last one is the product. I have been trying it by using an auxiliary function, which I think is the only way, but I haven't found a solution.
As starblue suggests, use a recursive auxiliary function:
(defun binom (n k)
(if (or (< n k) (< k 0))
NIL ; there are better ways to handle errors in Lisp
(binom-r n k 1)))
;; acc is an accumulator variable
(defun binom-r (n k acc)
(if (or (= k 0) (= n k))
acc
(binom-r (- n 1) (- k 1) (* acc (/ n k)))))
Or, give the main function an optional accumulator argument with a default value of 1 (the recursive base case):
(defun binom (n k &optional (acc 1))
(cond ((or (< n k) (< k 0)) NIL)
((or (= k 0) (= n k)) acc)
(T (binom (- n 1) (- k 1) (* acc (/ n k))))))
The latter option is slightly less efficient, since the error condition is checked in every recursive call.
You need an auxiliary function with an extra argument, which you use for computing and passing the result.