I'm pretty new to Common Lisp. And I try to build my own operator functions.
In the first function I tried to add one to the given number.
The second function we do a recursive use of the first in the frequency of m.
When I enter totaladd ( 5 3 ) I expect an 8.
What can I do about the undefined funciton k?
(defun add1(n)
(+ n 1)
)
(write (add1 5))
(defun totaladd (k m)
(if (eq m 0)
0
(totaladd(add1(k) (- m 1)))
)
)
(write (totaladd 5 3))
There are three errors in the next line:
(totaladd(add1(k) (- m 1)))
Let's look at it:
(totaladd ; totaladd is a function with two parameters
; you pass only one argument -> first ERROR
(add1 ; add1 is a function with one parameter
; you pass two arguments -> second ERROR
(k) ; K is a variable, but you call it as a function,
; but the function K is undefined -> third ERROR
(- m 1)))
(defun add1 (n) (+ n 1))
(defun totaladd (k m)
(if (= m 0)
k
(add1 (totaladd k (- m 1)))))
There is a extra function for (= ... 0) called zerop which asks whether a number os zero or not. Very frequently used when recursing over numbers as the break condition out of the recursion.
There is also an extra function for (- ... 1) or (+ ... 1) because these are common steps when recursing with numbers: (1- ...) and (1+ ...), respectively.
(Their destructive forms are (incf ...) and (decf ...), but these are not needed for recursion.)
So, using this, your form becomes:
(defun totaladd (k m)
(if (zerop m)
k
(add1 (totaladd k (1- m)))))
Related
I'm new to CHICKEN and Scheme. In my quest to understanding tail recursion, I wrote:
(define (recsum x) (recsum-tail x 0))
(define (recsum-tail x accum)
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum))))
This does what I expect it to. However, this seems a little repetitive; having an optional argument should make this neater. So I tried:
(define (recsum x . y)
(let ((accum (car y)))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
However, in CHICKEN (and maybe in other scheme implementations), car cannot be used against ():
Error: (car) bad argument type: ()
Is there another way to implement optional function arguments, specifically in CHICKEN 5?
I think you're looking for a named let, not for optional procedure arguments. It's a simple way to define a helper procedure with (possibly) extra parameters that you can initialize as required:
(define (recsum x)
(let recsum-tail ((x x) (accum 0))
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum)))))
Of course, we can also implement it with varargs - but I don't think this looks as elegant:
(define (recsum x . y)
(let ((accum (if (null? y) 0 (car y))))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
Either way, it works as expected:
(recsum 10)
=> 55
Chicken has optional arguments. You can do it like this:
(define (sum n #!optional (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
However I will vote against using this as it is non standard Scheme. Chicken say they support SRFI-89: Optional positional and named parameters, but it seems it's an earlier version and the egg needs to be redone. Anyway when it is re-applied this should work:
;;chicken-install srfi-89 # install the egg
(use srfi-89) ; imports the egg
(define (sum n (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
Also your idea of using rest arguments work. However keep in mind that the procedure then will build a pair on the heap for each iteration:
(define (sum n . acc-lst)
(define acc
(if (null? acc-lst)
0
(car acc-lst)))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
All of these leak internal information. Sometimes it's part of the public contract to have an optional parameter, but in this case it is to avoid writing a few more lines. Usually you don't want someone to pass a second argument and you should keep the internals private. The better way would be to use named let and keep the public contract as is.
(define (sum n)
(let loop ((n n) (acc 0))
(if (= n 0)
acc
(loop (- n 1) (+ acc n))))
I am trying to check if a number is prime using recursion. I was required to use a recursive helper function, but I am not sure how I should implement it.
I think I know the algorithm, but I've never tried to use a recursive helper function in Racket. This is my current thoughts:
See if n is divisible by i = 2
Set i = i + 1
If i^2 <= n continue.
If no values of i evenly divided n, then it must be prime.
This is what I have so far...
(define (is_prime n)
(if (<= n 1)
#f
(if (= (modulo n 2) 0)
#f
)
What would be a good approach using a recursive helper function??
Thanks!
Using a helper simply means that you should split your program in smaller parts, and possibly encapsulate loops with extra parameters in separate procedures - and in Scheme loops are frequently implemented via recursive calls. One (naïve) way to implement the is_prime procedure would be:
(define (is_prime n)
(cond ((<= n 1) #f)
((= n 2) #t)
((= (modulo n 2) 0) #f)
(else (check 3 n))))
; recursive helper
(define (check i n)
(cond ((> (* i i) n) #t)
((= (modulo n i) 0) #f)
(else (check (+ i 2) n))))
There are many ways to implement this procedure, and many possible optimizations; the above should be enough get you started.
(define (isPrimeHelper x k)
(if (= x k) #t
(if (= (remainder x k) 0) #f
(isPrimeHelper x (+ k 1)))))
(define ( isPrime x )
(cond
(( = x 0 ) #f)
(( = x 1 ) #f)
(( = x 2 ) #t)
( else (isPrimeHelper x 2 ) )))
I prefer this version.
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 want to count the number of moves of the diskc. but Instead As a result I get something else.
(setq x 0)
(defun towersOfHanoi (n from to help)
(if (> n 0)
;progn evaluates multiple forms and returns the result from the last one.*/
(progn
(towersOfHanoi (- n 1) from help to)
(format t "~d ----> ~d~%" from to)
(towersOfHanoi (- n 1) help to from)
(+ 1 x)
)
))
;(towersOfHanoi 3 'A 'B 'C)
When I run it I get
(towersOfHanoi 3 'A 'B 'C)
A ----> B
A ----> C
B ----> C
A ----> B
C ----> A
C ----> B
A ----> B
1
why it is one instead of 7, I guess with every recursive call is resetting the value of x to 0 but, how can I get the number of moves of the disks. Thanks.
In lisp if takes at most three arguments; the condition, the form to evaluate when the condition is true, and the form to evaluate if it is false.
Se http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm for details.
In order to evaluate more than one form in a branch, you can use progn that evaluates multiple forms and returns the result from the last one.
Also, princ expects just one argument to be printed. In order to print several things at once, you may use format
In your case (remark also the placement of the parentheses):
(defun towersOfHanoi (n from to help)
(if (> n 0)
(progn
(towersOfHanoi (1- n) from to help)
(format t "~d ----> ~d~%" from to)
(towersOfHanoi (1- n) help to from))))
Having no false branch, you may also use when that can evaluate more than one form:
(defun towersOfHanoi (n from to help)
(when (> n 0)
(towersOfHanoi (1- n) from to help)
(format t "~d ----> ~d~%" from to)
(towersOfHanoi (1- n) help to from)))
In order to count the moves, you can use a local counting variable (introduced with let), and an inner working function (introduced with labels) that updates this variable:
(defun towers-of-hanoi (n &optional (from 1) (to 2) (help 3))
(let ((counter 0)) ; local variable
(labels ((towers-of-hanoi-core (n from to help) ; local function
(when (> n 0)
(towers-of-hanoi-core (1- n) from to help)
(incf counter)
(format t "~d ----> ~d~%" from to)
(towers-of-hanoi-core (1- n) help to from))))
(towers-of-hanoi-core n from to help)) ; leave work to inner function
(format t "Moves: ~d ~%" counter)))
Here, from, to, and help is made optional as well, defaulting to 1, 2, and 3.
Again: The details are found in the Hyperspec: http://www.lispworks.com/documentation/HyperSpec/Front/
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.