I try to factorial for in this code but, I did not get the answer.
(defun fact(n)
(if (= n 0)
(setq n 1)
(setq pr (* n ( fact (- n 1))))
(print pr)
)
The issue is that you are supplying too many arguments to the if expression in your code. An if statement will accept at most 3 arguments:
A test expression
A 'then' expression
An optional 'else' expression
In your code, you are supplying 4 arguments:
(= n 0)
(setq n 1)
(setq pr (* n ( fact (- n 1))))
(print pr)
You are also missing a closing parenthesis.
To correct your code, the final print expression can be moved outside of the if expression, and the pr variable should be declared as a local variable i.e.:
(defun fact ( n / pr )
(if (= n 0)
(setq n 1)
(setq pr (* n (fact (- n 1))))
)
(print pr)
)
However, whilst the code is syntactically correct, you will now receive the error:
; error: bad argument type: numberp: nil
This is because, when n is 0, the variable pr is not defined and so the print expression will return nil, causing the multiplication with the return of the recursive call to fail.
However, whilst the code could be modified to define pr when n=0, this variable is not actually required, and the code may become:
(defun fact ( n )
(if (< 0 n) (* n (fact (1- n))) 1)
)
The function will now return the value of the calculated factorial:
_$ (fact 5)
120
Related
CL-USER> (a-sum 0 3)
->> 6
I wrote this program :
(defun a-sum (x y)
(if (and (> x -1) (> y -1))
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1)))
(setq sum (+ sum num))
(setq num (+ num 1))
sum)
(print " NOPE")))
put if I run it in the terminal it returns nil and not the answer stated above;
can someone help with the problem so it returns the value then Boolean.
DO,DO* Syntax
The entry for DO,DO* says that the syntax is as follows:
do ({var | (var [init-form [step-form]])}*)
(end-test-form result-form*)
declaration*
{tag | statement}*
The body is used as a list of statements and no intermediate value in this body is used as the result form of the do form. Instead, the do form evaluates as the last expression in result-form*, which defaults to nil.
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1))
;;; RESULT FORMS HERE
)
(setq sum (+ sum num)) ;; (*)
(setq num (+ num 1)) ;; (*)
sum ;; (*)
)
All the expressions marked commented (*) above are used for side-effects only: the result of their evaluation is unused and discarded.
Problem statement
It is not clear to me what Σpi=ni means, and your code does not seem to compute something that could be expressed as that mathematical expression.
One red flag for example is that if (+ (- y x) 1) is negative (i.e. if y < x-1, for example y=1,x=3), then your loop never terminates because i, which is positive or null, will never be equal to the other term which is negative.
I would try to rewrite the problem statement more clearly, and maybe try first a recursive version of your algorithm (whichever is easier to express).
Remarks
Please indent/format your code.
Instead of adding setq statements in the body, try to see if you can define them in the iteration clauses of the loop (since I'm not sure what you are trying to achieve, the following example is only a rewrite of your code):
(do ((i 0 (1+ i))
(sum 0 (+ sum num)
(num x (1+ num))
(... sum))
Consider what value(s) a function returns. It's the value of the last form evaluated. In your case, that appears to be a do or maybe a setq or print (It's difficult to read as it's formatted now, and I don't have question edit privileges).
In short, the form that's returning the value for the function looks to be one evaluated for side-effects instead of returning a value.
trying to do a dr racket problem to tell if a number is apart of list. getting errors
#lang racket
(mymember (x, l))
if l=?null
then "false"
if x==car(l)
then "true"
mymember(x,l)
mymember 2' (1,3,4,5,6)
Racket uses prefix notation. This makes commas unnecessary. First, some syntax:
How to define a function?
( define ( name variable1 variable2 ) body )
Where name is the name of the function, and the variables are the parameters. Which are followed by the body expression.
Example:
; Number -> Number
; converts from fahrenheit to celsius.
(define (f2c f)
(* 5/9 (- f 32)))
How to call a function?
( name expression1 expression2 )
name is the name of the function and expression1 and expression2 are its arguments.
Example:
(sqr 3)
;; == 9
Similarly, to check if two values are equal: (equal? x y)
How to use the if expressions?
( if question-expression then-answer-expression else-answer-expression )
If the value of the question-expression is not false, the if evaluates the then-answer-expression, otherwise it evaluates the else-answer-expression.
Example:
;; Number -> Number
;; reciprocate all non-zero x, otherwise return 0.
(define (inverse-of-x x)
(if (= x 0) 0 (/ 1 x)))
... and so on. Read the Racket Guide for the essentials on syntax, semantics and datatypes in the language.
Fixing all the syntax still leads to one error: an infinite loop. That is because the recursive call doesn't call cdr on the list. So the recursive call is made on the same list (not a shorter list) forever. Wrapping a cdr and fixing the syntax leads to a correct function.
#lang racket
; [X] [List-of X] -> "true" U "false"
; is x an element of l?
(define (mymember x l)
(if (equal? l null)
"false"
(if (equal? x (car l))
"true"
(mymember x (cdr l)))))
(mymember 2 '()) ; = false
(mymember 2 '(1 3 4 5 6)) ; = false
(mymember 2 '(1 3 2 5 6)) ; = true
Hi I'm a beginner in Common Lisp. I want to check if two variables are integers. If both n and m are integers I want to it to return - if it is negative, 0 if it is zero, + if it is positive and NIL if it is not an integer for both n and m. I figured out how to do this with one variable but I can't seem to figure out how to do it with two variables. Thanks.
This is the code that takes a numeric argument and returns - if it is negative, 0 if it is zero, + if it is positive and NIL if its not an integer:
(defun sign (n)
(if(typep n 'integer)
(cond ((< n 0) '-)
((= n 0) 0)
((> n 0) '+))))
The output for each case is:
CL-USER> (sign 3)
+
CL-USER> (sign -3)
-
CL-USER> (sign 0)
0
CL-USER> (sign 3.3)
NIL
This is the code I have for checking two variables which I want it to check if n and m are integers and if n and m are positive, negative or a zero:
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond (and ((< n 0) '-) ((< m 0) '-))
(and ((= n 0) 0) ((= m 0) 0))
(and ((> n 0) '+) ((> m 0) '+)) ))))
Remember basic Lisp syntax. Function calls and some basic expressions are written as
(operator argument-0 argument-1 ... argument-n)
Right?
open parenthesis, operator, argument-0 argument-1 ... argument-n, closing parenthesis.
Now if we have (< n 0) and (< m 0) how would an AND expressions look like?
(and (< n 0) (< m 0))
But you write:
and ((< n 0) '-) ((< m 0) '-)
You have these mistakes:
no parentheses around the AND expression.
extra parenthesis around the argument expressions.
'- mixed into the argument expressions.
Now COND expects:
(COND (testa1 forma0 forma1 ... forman)
(testb1 formb1 formb1 ... formbn)
...
(testm1 formm0 formm1 ... formmn))
So instead of
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond (and ((< n 0) '-) ((< m 0) '-))
(and ((= n 0) 0) ((= m 0) 0))
(and ((> n 0) '+) ((> m 0) '+)))))
Btw, there was an extra parenthesis at the end.
We write:
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond ((and (< n 0) (< m 0)) '-)
.... )))
It's also possible to use predicates like integerp, minusp, zerop and plusp.
You can use the already functioning and tested sign definition - which is typical for the way, lispers program. The first naive solution would be:
(defun sign-for-two (n m)
(when (eql (sign n) (sign m))
(sign n))
;; (if (condition) return-value NIL)
;; is equivalent to
;; (when (condition) return-value)
Note, in common lisp it is important,
which equality test you choose:
;; only symbols - for object identity eq
;; symbols or numbers - for object identity eql
;; (in most tests the default)
;; eql for each component? also in lists equal
;; equal not only lists but also
;; arrays (vectors, strings), structures, hash-tables
;; however case-insensitive in case of strings
;; equalp
;; mathematical number equality =
;; specifically characters char=
;; case-sensitive string equality string=
In our case, eql is sufficient.
;; to avoid `(sign n)` to be evaluated twice,
;; you could store it using `let`
;; and call from then on the stored value
;; (which is less costly).
(defun sign-for-two (n m)
(let ((x (sign n)))
(when (eql x (sign m))
x)))
Or create an equality tester (default test function: #'eql)
which returns the equally tested value
and if not equal, NIL:
(defun equality-value (x y &key (test #'eql))
(when (funcall test z y) z)))
;; and apply this general solution to our case:
(defun sign-for-two (n m)
(equality-value (sign n) (sign m)))
and you can apply the equality-value function
in future for functions where you want to
return the value when tested as "equal"
and you can give the function via :test whatever equality
function other than eql is suitable for that case, like
(equality-value string1 string2 :test #'string=)
It looks like you have the right approach and just got lost in the parentheses. Each of your cond cases looks like
(and ((< n 0) '-) ((< m 0) '-))
I think you meant
((and (< n 0) (< m 0)) '-)
and the same thing for the other two cases.
Another compact way to write sign is to use the standard function signum which
returns one of -1, 0, or 1 according to whether number is negative,
zero, or positive
The code could look like:
(defun sign (n)
(when (integerp n)
(case (signum n)
(-1 '-)
(0 0)
(1 '+))))
I am currently trying to solve problem 1 from projecteuler.net. Evaluation of this function only returns the name of the function. What am I doing wrong?
(defun nSum (n sum)
(if ( n = 0) ( sum) )
(cond ( (mod n 5) = 0) ( nSum ( - n 1) (+ sum n)) ( (mod n 3) = 0) (nSum(- n 1) (+ sum n)) (nSum (- n 1) (+ sum n))
)
)
(setq sum (nSum 100 0))
(write sum)
Errors
Evaluation of this function only returns the name of the function.
I cannot replicate this, how did you test your code, under which environment?
With SBCL, here is what evaluating the defun form prints:
; in: DEFUN NSUM
; (N = 0)
;
; caught WARNING:
; undefined variable: =
The = symbol is being used in a position where it is evaluated as a variable. If you want to call the function bound to =, that is (function =), which can be written also #'=, then you have to write (= ... ...).
; caught STYLE-WARNING:
; undefined function: N
Since you wrote (N = 0), i.e. with N as the first element of a form under normal evaluation rules, the code tries to call function N. In your case, you have no such function defined.
; (COND ((MOD N 5) = 0) (NSUM (- N 1) (+ SUM N)) ((MOD N 3) = 0)
; (NSUM (- N 1) (+ SUM N)) (NSUM (- N 1) (+ SUM N)))
; --> IF
; ==>
; (IF NSUM
; (PROGN (- N 1) (+ SUM N))
; (IF (MOD N 3)
; (PROGN = 0)
; (IF NSUM
; (PROGN (- N 1) (+ SUM N))
; (IF NSUM
; (PROGN # #)
; NIL))))
;
; caught WARNING:
; undefined variable: NSUM
You are writing cond clauses, and in that context, each clause is supposed to be a list matching (test . body), i.e. a test expression followed by the case body (possibly empty). You wrote:
(cond ( (mod n 5) = 0) ( nSum ( - n 1) (+ sum n)) ...)
In the above, you have two clauses, one which (tries to) tests whether N is divisible by 5, and the other which test if nSum is true.
; (SUM)
;
; caught STYLE-WARNING:
; undefined function: SUM
You added parentheses around SUM, which means you want to call function SUM (currently undefined). Parentheses matter in Lisp.
Fixing errors and formatting
Here is your code after fixing the previous errors and formatting it according to Lisp style rules:
(defun nSum (n sum)
(if (= n 0)
sum
(cond
((= 0 (mod n 5)) (nSum (- n 1) (+ sum n)))
((= 0 (mod n 3)) (nSum (- n 1) (+ sum n)))
(t (nSum (- n 1) (+ sum n))))))
Your code does not compute the desired function. Please read Gwang-Jin Kim's answer to see how to compute it a tail-recursive way, or below for a loop-based one.
Some additional remarks w.r.t. style:
You are not supposed to use snakeCase in Lisp, use instead dashes to separate words, known humbly as lisp-case (and apparently, also as kebab-case).
Your if and cond can be merged together. Also, be careful about negative N.
You can do (or test1 test2) when both tests lead to the same code being executed. This avoids code duplication.
Alternative implementation
Use LOOP:
(defun euler-1 (n)
(loop
for i below n
when (or (zerop (mod i 3))
(zerop (mod i 5)))
sum i))
(defun nsum (n)
(labels ((inner-nsum (m sum) ; using `labels` define local recursive function
(cond ((= m 0) sum)
((= (mod m 3) 0) (inner-nsum (- m 1) (+ m sum)))
((= (mod m 5) 0) (inner-nsum (- m 1) (+ m sum)))
(t (inner-nsum (- m 1) sum)))))
(inner-nsum (- n 1) 0))) ; call it with n decremented by 1
; to implement "below n"
(nsum 10) ;; 23 ; test successful!
(nsum 1000) ;; 233168
You should use eq for equality test (or perhaps equal; for integers it is the same), or = for comparing numbers. And there is no infix operator in Common Lisp. So ( n = 0) should be something like (eq n 0) or (= n 0) etc.
I am defining a function binomial(n k) (aka Pascal's triangle) but am getting an error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 1
arguments...:
2
I don't understand the error because I thought this defined my function:
(define (binomial n k)
(cond ((or (= n 0) (= n k)) 1)
(else (+ (binomial(n) (- k 1))(binomial(- n 1) (- k 1))))))
In Scheme (and Lisps in general), parentheses are placed before a procedure application and after the final argument to the procedure. You've done this correctly in, e.g.,
(= n 0)
(= n k)
(- k 1)
(binomial(- n 1) (- k 1))
However, you've got an error in one of your arguments to one of your calls to binomial:
(define (binomial n k)
(cond ((or (= n 0) (= n k)) 1)
(else (+ (binomial(n) (- k 1))(binomial(- n 1) (- k 1))))))
***
Based on the syntax described above (n) is an application where n should evaluate to a procedure, and that procedure will be called with no arguments. Of course, n here actually evaluates to an integer, which is not a procedure, and can't be called (hence “application: not a procedure”). You probably want to remove the parentheses around n:
(binomial n (- k 1))
It's also worth pointing out that Dr. Racket should have highlighted the same portion of code that I did above. When I load your code and evaluate (binomial 2 1), I get the following results in which (n) is highlighted:
Your error is here:
binomial(n)
n is an integer, not a function. If you put parentheses around it like that, scheme tries to invoke an integer as a function, which naturally produces an error.
This is the correct code:
(define (binomial n k)
(cond ((or (= n 0) (= n k)) 1)
(else (+ (binomial n (- k 1))(binomial(- n 1) (- k 1))))))
Problem is at here:
(binomial (n) (- k 1))