Computing the sum of the first n numbers in lisp - lisp

(defun sum(n)
(cond
((= n 0) 0)
((= n 1) 1)
(T (+ n sum (- n 1)))))
If I call (sum 4) it should show 10 but it gives me an error : Variable SUM has no value

Common Lisp is a Lisp-2, which means that variables and functions are in distinct namespaces.
There is a function sum, but there is no variable sum, at the point where you're using it as a variable: (+ n sum (- n 1)).
Your intention may have been to write (+ n (sum (- n 1))) instead, calling the function sum recursively:
(defun sum (n)
(cond ((= n 0) 0)
((= n 1) 1)
(T (+ n (sum (- n 1))))))
(If you wanted to refer to the function sum as a value, e.g. to pass it to another function, you would write #'sum.)

Related

Common Lisp - type checking two variables

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

Common Lisp: Function returns function name

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.

Lisp recursive square use one variables

This is Trying code
(defun f (a n)
(if (zerop n)
1
(* a (f a (- n 1)))))
(f 3) should return 27, (f 4) should return 256
I tried using two variables, but it be against the rules.
Is it possible to use only one variable using recursive?
Thanks for any ideas
I don't know CL, but I do know Clojure and other languages that use recursion.
In cases where a recursive function has 1 parameter acting as an accumulator, but is only set on the first call, the typical way around this is to wrap f in another function. There are 2 (basically the same) ways of doing this:
(defun g (a n)
(if (zerop n)
1
(* a (g a (- n 1)))))
(defun f (n)
; I'm assuming you want the initial value of "a" to be 1
(g 1 n))
Or, more succinctly:
(defun f (n)
(let (g (fn (n)
(if (zerop n)
1
(* a (g a (- n 1))))))))
; Instead of f being recursive, f calls g, which is recursive
(g 1 n))
Excuse any syntax errors.
Using an additional variable to count down would be the sane choice, but you don't need to change the contract of just one numeric argument input just for this. You can make a helper to do that:
(defun exptnn (n)
"Get the (expt n n)"
(check-type n integer)
(labels ((helper (acc count)
(if (zerop count)
acc
(helper (* acc n) (1- count)))))
(if (< n 0)
(/ 1 (helper 1 (- n)))
(helper 1 n))))
Now to solve with without any helpers just with one argument is possible since there is a solution doing that already, but I must say that is like programming in Brainf*ck without the joy!
CL-USER 15 > (defun f (n)
(labels ((g (m)
(if (zerop m)
1
(* n (g (1- m))))))
(g n)))
F
CL-USER 16 > (f 0)
1
CL-USER 17 > (f 1)
1
CL-USER 18 > (f 2)
4
CL-USER 19 > (f 3)
27
CL-USER 20 > (f 4)
256
CL-USER 21 > (loop for i below 10 collect (f i))
(1 1 4 27 256 3125 46656 823543 16777216 387420489)
This is a solution where no functions with more than one parameter are used (except for =, +, *, logand, ash; note also that logand and ash always take a constant as second parameter so they can be implemented as unary functions too).
The idea is to "hide" the two parameters needed for the obvious recursive approach in a single integer using odd/even bits.
(defun pair (n)
(if (= n 0)
0
(+ (* 3 (logand n 1))
(ash (pair (ash n -1)) 2))))
(defun pair-first (p)
(if (= p 0)
0
(+ (logand p 1)
(ash (pair-first (ash p -2)) 1))))
(defun pair-second (p)
(pair-first (ash p -1)))
(defun subsec (p)
(if (= 2 (logand p 2))
(- p 2)
(+ (logand p 1) 2 (ash (subsec (ash p -2)) 2))))
(defun pairpow (p)
(if (= (pair-second p) 1)
(pair-first p)
(* (pair-first p)
(pairpow (subsec p)))))
(defun f (n)
(pairpow (pair n)))
No reasonable real use, of course; but a funny exercise indeed.
Yes, this is possible:
(defun f (n)
(cond
((numberp n)
(f (cons n n)))
((zerop (car n))
1)
(t
(* (cdr n)
(f (cons (1- (car n))
(cdr n)))))))
The trick is that you can store any data structure (including a pair of numbers) in a single variable.
Alternatively, you can use helpers from the standard library:
(defun f (n)
(apply #'*
(loop repeat n collect n)))
But that doesn't use recursion. Or simply:
(defun f (n)
(expt n n))

Return the sum of odd digits of a number

For class, I have to write a function that takes positive integer n and returns the sum of n’s odd digits in scheme. So far, I have my base case such that if n equals 0 then 0. But I am not sure on how to continue.
(define sumOddDigits
(lambda (n)
(if (= n 0)
0
Test cases:
(sumOddDigits 0) → 0
(sumOddDigits 4) → 0
(sumOddDigits 3) → 3
(sumOddDigits 1984) → 10
You could do it efficiently using one functional loop:
(define (sumOddDigits n)
(let loop ([n n])
(cond [(zero? n) 0]
[else
(let-values ([(q r) (quotient/remainder n 10)])
(+ (if (odd? r) r 0)
(loop q)))])))
One can get list of digits using following function which uses 'named let':
(define (getDigits n)
(let loop ((ol '()) ; start with an empty outlist
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
Then one can apply a filter using odd? function to get all odd elements of list- and then apply 'apply' function with '+' to add all those elements:
(apply + (filter
(lambda(x)
(odd? x))
digitList))
Together following can be the full function:
(define (addOddDigits N)
(define (getDigits n)
(let loop ((ol '())
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
(define digitList (getDigits N))
(println digitList)
(apply + (filter
(lambda(x)
(odd? x))
digitList)))
Testing:
(addOddDigits 156)
Output:
'(1 5 6)
6
Your basecase is if n < 10. Because you are then on the last digit.
You then need to check if it's odd, and if so return it. Else, return the addition qualifier(0).
If n > 10, you remainder off the first digit, then test it for odd.
If odd, then add it to a recursive call, sending in the quotient of 10(shaves off the digit you just added).
Else, you recursively call add-odds with the quotient of 10, without adding the current digit.
Here it is in a recursive form(Scheme LOVES recursion) :
(define add-odds
(lambda (n)
(if(< n 10)
(if(= (remainder n 2) 1)
n
0)
(if(= (remainder (remainder n 10) 2) 1)
(+ (remainder n 10) (add-odds (quotient n 10)))
(add-odds(quotient n 10))))))
First get a (reversed) list of digits with simple recursive implementation:
(define (list-digits n)
(if (zero? n) '()
(let-values ([(q r) (quotient/remainder n 10)])
(cons r (list-digits q)))))
then filter the odd ones and sum them:
(define (sum-of-odd-digits n)
(apply + (filter odd? (list-digits n))))
Note: (list-digits 0) returns '() but it is ok for later usage.
More accurate list-digits iterative implementation (produce list of digits in right order):
(define (list-digits n)
(define (iter n acc)
(if (zero? n) acc
(let-values ([(q r) (quotient/remainder n 10)])
(iter q (cons r acc)))))
(iter n '()))

"application: not a procedure" while computing binomial

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