Reputation: 65
I'm new to lisp programming and I'm trying to create a program that accept six numbers and check whether each number is either odd or even number.
(princ"Input six number: ")
(setq a(read))
(setq b(read))
(setq c(read))
(setq d(read))
(setq e(read))
(setq f(read))
(format t "~% ~d" a)
(format t "~% ~d" b)
(format t "~% ~d" c)
(format t "~% ~d" d)
(format t "~% ~d" e)
(format t "~% ~d" f)
(if(= 0(mod a 2))
(print"even")
(print"odd"))
(if(= 0(mod b 2))
(print"even")
(print"odd"))
(if(= 0(mod c 2))
(print"even")
(print"odd"))
(if(= 0(mod d 2))
(print"even")
(print"odd"))
(if(= 0(mod e 2))
(print"even")
(print"odd"))
(if(= 0(mod f 2))
(print"even")
(print"odd"))
(terpri)
Upvotes: 1
Views: 751
Reputation: 38799
You have a lot of code that looks like this:
(if(= 0(mod ... 2))
(print"even")
(print"odd"))
(this might be a copy/paste problem but in your question they are indented more and more to the right. They are however not nested, they are all at the same depth (they are toplevel expressions) so by convention they should not be indented).
A first step would be to factor them using a function like this one:
(defun check-even-odd (number)
(if (= 0 (mod number 2))
(print "even")
(print "odd")))
The above defines a function named check-even-odd
of one parameter number
, and it applies the same logic you originally had for any arbitrary number.
The rest of your code can be simplified as:
(check-even-odd a)
(check-even-odd b)
(check-even-odd c)
(check-even-odd d)
(check-even-odd e)
(check-even-odd f)
Now, you can define two additional global variables:
(defparameter total-even 0)
(defparameter total-odd 0)
Each of them holds a sum, and is initialized to 0.
You can rewrite the check-even-odd
function as follows to update the counters. First of all, let's just rewrite the current code by using cond
, since we are going to need to perform multiple actions in each case, and if
only accepts one expression for each branch (the combination if
and progn
is a bit ugly):
(defun check-even-odd (number)
(cond
((= 0 (mod number 2))
(print "even"))
(t
(print "odd"))))
This above behaves as the original code.
In order to increment a variable by a certain amount, you can use INCF
:
(defun check-even-odd (number)
(cond
((= 0 (mod number 2))
(print "even")
(incf total-even number))
(t
(print "odd")
(incf total-odd number))))
When you execute your whole script, the total will be initialized to zero, then each call to check-even-odd
will add the number to the appropriate counter.
Notes:
defparameter
instead of setq
when initializing a
, b
, etc, because otherwise the variables are not declared and calling setq
on undeclared variables is not standardfinish-output
, clear-input
) otherwise you could experience strange behavior when the underlying stream is buffered.Upvotes: 3