This refuses to compile. Commenting out the (setf roll line lets it compile. However, (setf roll... itself evaluates correctly in the REPL.
Program:
;; loop n times
; sum up number of hits over value v
(defun num-hits (n v)
(let
((roll)
(table))
(setq table (make-hash-table))
;;until i == n
(loop for i from 1 to n
(setf roll (rolld6))
; (if (nilp (view_hash table))
; (oxuassign_hash table roll 1)
; (assign_hash table (+ 1 (view_hash table roll))))
)
(+ (view_hash table 5) (view_hash table 6))))
Message:
*** - LOOP: illegal syntax near (SETF ROLL (ROLLD6)) in (LOOP FOR I FROM 1 TO N (SETF ROLL (ROLLD6)))
The loop macro requires "do" before the loop body. You have
(loop for i from 1 to n
(stuff)
and you need
(loop for i from 1 to n do
(stuff))
Related
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)))))
UPDATED: The code should compile now without errors or warnings. Sorry about the previous one. The problem I have now is that when a run (or with any other integer)
(NxNqueen-solver 10)
The function getqueencol will return nil because there are no queens on the board in the first place, hence there will be a (= number nil) in the queen-can-be-placed-here because tcol will be nil. I think this will happen everytime there is no queen in the row passed as argument to the queen-can-be-placed-here function.
Please share some advice on how to fix this problem. Thank you in advance.
Here is the code
(defvar *board* (make-array '(10 10) :initial-element nil))
(defun getqueencol (row n)
"Traverses through the columns of a certain row
and returns the column index of the queen."
(loop for i below n
do (if (aref *board* row i)
(return-from getqueencol i))))
(defun print-board (n)
"Prints out the solution, e.g. (1 4 2 5 3),
where 1 denotes that there is a queen at the first
column of the first row, and so on."
(let ((solutionlist (make-list n)))
(loop for row below n
do (loop for col below n
do (when (aref *board* row col)
(setf (nth row solutionlist) col))))
(print solutionlist)))
(defun queen-can-be-placed-here (row col n)
"Returns t if (row,col) is a possible place to put queen, otherwise nil."
(loop for i below n
do (let ((tcol (getqueencol i n)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil)))))
(defun backtracking (row n)
"Solves the NxN-queen problem with backtracking"
(if (< row n)
(loop for i below n
do (when (queen-can-be-placed-here row i n)
(setf (aref *board* row i) 't)
(return-from backtracking (backtracking (+ row 1) n))
(setf (aref *board* row i) 'nil))
(print-board n))))
(defun NxNqueen-solver (k)
"Main program for the function call to the recursive solving of the problem"
(setf *board* (make-array '(k k) :initial-element nil))
(backtracking 0 k))
You say that you compiled your code. That can't be the case, since then you would have see the compiler complaining about errors. You want to make sure that you really compile the code and correct the code, such that it compiles without errors and warnings.
You might want to get rid of the errors/problems in the code (see Renzo's comment) and then look at the algorithmic problem. I makes very little sense to look into an algorithmic problem, when the code contains errors.
SETQ does not introduce a variable, the variable has to be defined somewhere
DEFVAR makes no sense inside a function.
Something like (let (x (sin a)) ...) definitely looks wrong. The syntax of LET requires a pair of parentheses around the bindings list.
RETURN-FROM takes as first argument the name of an existing block to return from. The optional second argument is a return value. Get the syntax right and return from the correct block.
in a call to MAKE-ARRAY specify the default value: (make-array ... :initial-element nil), otherwise it's not clear what it is.
The variable *board* is undefined
Style
in LOOP: for i to (1- n) is simpler for i below n
you don't need to quote NIL and T.
(if (eq foo t) ...) might be simpler written as (if foo ...). Especially if the value of foo is either NIL or T.
(if foo (progn ...)) is simply (when foo ...)
I'm not sure what you are doing to claim that your code compiles. It does not compile.
Every function has compiler warnings. You should check the compiler warnings and fix the problems.
(defun getqueencol (row)
"Traverses through the columns of a certain row
and returns the column index of the queen."
(loop for i below n
do (if (aref board row i)
(return-from getqueencol i))))
The compiler complains:
;;;*** Warning in GETQUEENCOL: N assumed special
;;;*** Warning in GETQUEENCOL: BOARD assumed special
Where is n defined? Where is board coming from?
(defun print-board (board)
"Prints out the solution, e.g. (1 4 2 5 3),
where 1 denotes that there is a queen at the first
column of the first row, and so on."
(let (solutionlist)
(setq solutionlist (make-list n)))
(loop for row below n
do (loop for col below n
do (when (aref board row col)
(setf (nth row solutionlist) col))))
(print solutionlist))
The LET makes no sense. (let (foo) (setq foo bar) ...) is (let ((foo bar)) ...).
Why is solutionlist not defined? Look at the LET... it does not make sense.
Where is n coming from?
(defun queen-can-be-placed-here (row col)
"Returns t if (row,col) is a possible place to put queen, otherwise nil."
(loop for i below n
do (let (tcol)
(setq tcol (getqueencol i)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil))))
where is n coming from? The LET makes no sense.
(defun backtracking (row)
"Solves the NxN-queen problem with backtracking"
(if (< row n)
(loop for i below n
do (when (queen-can-be-placed-here row i)
(setf (aref board row i) 't)
(return-from backtracking (backtracking (+ row 1)))
(setf (aref board row i) 'nil))
(print-board board))))
Where is n coming from? Where is board defined?
(defun NxNqueen-solver (k)
"Main program for the function call to the recursive solving of the problem"
(let (n board)
(setq n k)
(setq board (make-array '(k k) :initial-element nil)))
(backtracking 0))
Why use setq when you have a let? The local variables n and board are unused.
MAKE-ARRAY expects a list of numbers, not a list of symbols.
I propose you use a basic Lisp introduction (Common Lisp: A Gentle Introduction to Symbolic Computation - free download) and a Lisp reference (CL Hyperspec).
We are tasked to print out the values in the pascal triangle in this manner
(pascal 2)
(1 2 1)
(pascal 0)
(1)
I copied the code for the binomial thereom somewhere in the internet defined as follows:
(defun choose(n k)
(labels ((prod-enum (s e)
(do ((i s (1+ i)) (r 1 (* i r))) ((> i e) r)))
(fact (n) (prod-enum 1 n)))
(/ (prod-enum (- (1+ n) k) n) (fact k))))
Now I'm trying to create a list out of the values here in my pascal function:
(defun pascal (start end)
(do ((i start (+ i 1)))
((> i end) )
(print (choose end i) ))
)
The function produces 1 2 1 NIL if I test it with (pascal 0 2). How can I eliminate the NIL and create the list?
Note: I explicitly didn't provide an implementation of pascal, since the introductory “we are tasked…” suggests that this is a homework assignment.
Instead of printing the result of (choose end i) on each iteration, just collect the values produced by (choose end i) into a list of results, and then return the results at the end of the loop. It's a common idiom to construct a list in reverse order by pushing elements into it, and then using nreverse to reverse it to produce the final return value. For instance, you might implement range by:
(defun range (start end &optional (delta 1) &aux (results '()))
(do ((i start (+ i delta)))
((>= i end) (nreverse results))
(push i results)))
or (It always feels satisfying to write a do/do* loop that doesn't need any code in the body.)
(defun range (start end &optional (delta 1))
(do* ((results '() (list* i results))
(i start (+ i delta)))
((>= i end) (nreverse results))))
so that
(range 0 10 3)
;=> (0 3 6 9)
However, since the rows in Pascal's triangle are palidromes, you don't need to reverse them. Actually, since the rows are palindromes, you should even be able to adjust the loop to generate just half the list return, e.g.,
(revappend results results)
when there are an even number of elements, and
(revappend results (rest results))
when there are an odd number.
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/
Is it possible to write a Common Lisp macro that takes a list of dimensions and variables, a body (of iteration), and creates the code consisting of as many nested loops as specified by the list?
That is, something like:
(nested-loops '(2 5 3) '(i j k) whatever_loop_body)
should be expanded to
(loop for i from 0 below 2 do
(loop for j from 0 below 5 do
(loop for k from 0 below 3 do
whatever_loop_body)))
Follow up
As huaiyuan correctly pointed out, I have to know the parameters to pass to macro at compile time. If you actually need a function as I do, look below.
If you are ok with a macro, go for the recursive solution of 6502, is wonderful.
You don't need the quotes, since the dimensions and variables need to be known at compile time anyway.
(defmacro nested-loops (dimensions variables &body body)
(loop for range in (reverse dimensions)
for index in (reverse variables)
for x = body then (list y)
for y = `(loop for ,index from 0 to ,range do ,#x)
finally (return y)))
Edit:
If the dimensions cannot be decided at compile time, we'll need a function
(defun nested-map (fn dimensions)
(labels ((gn (args dimensions)
(if dimensions
(loop for i from 0 to (car dimensions) do
(gn (cons i args) (cdr dimensions)))
(apply fn (reverse args)))))
(gn nil dimensions)))
and to wrap the body in lambda when calling.
CL-USER> (nested-map (lambda (&rest indexes) (print indexes)) '(2 3 4))
(0 0 0)
(0 0 1)
(0 0 2)
(0 0 3)
(0 0 4)
(0 1 0)
(0 1 1)
(0 1 2)
(0 1 3)
(0 1 4)
(0 2 0)
(0 2 1)
...
Edit(2012-04-16):
The above version of nested-map was written to more closely reflect the original problem statement. As mmj said in the comments, it's probably more natural to make index range from 0 to n-1, and moving the reversing out of the inner loop should improve efficiency if we don't insist on row-major order of iterations. Also, it's probably more sensible to have the input function accept a tuple instead of individual indices, to be rank independent. Here is a new version with the stated changes:
(defun nested-map (fn dimensions)
(labels ((gn (args dimensions)
(if dimensions
(loop for i below (car dimensions) do
(gn (cons i args) (cdr dimensions)))
(funcall fn args))))
(gn nil (reverse dimensions))))
Then,
CL-USER> (nested-map #'print '(2 3 4))
Sometimes an approach that is useful is writing a recursive macro, i.e. a macro that generates code containing another invocation of the same macro unless the case is simple enough to be solved directly:
(defmacro nested-loops (max-values vars &rest body)
(if vars
`(loop for ,(first vars) from 0 to ,(first max-values) do
(nested-loops ,(rest max-values) ,(rest vars) ,#body))
`(progn ,#body)))
(nested-loops (2 3 4) (i j k)
(print (list i j k)))
In the above if the variable list is empty then the macro expands directly to the body forms, otherwise the generated code is a (loop...) on the first variable containing another (nested-loops ...) invocation in the do part.
The macro is not recursive in the normal sense used for functions (it's not calling itself directly) but the macroexpansion logic will call the same macro for the inner parts until the code generation has been completed.
Note that the max value forms used in the inner loops will be re-evaluated at each iteration of the outer loop. It doesn't make any difference if the forms are indeed numbers like in your test case, but it's different if they're for example function calls.
Hm. Here's an example of such a macro in common lisp. Note, though, that I am not sure, that this is actually a good idea. But we are all adults here, aren't we?
(defmacro nested-loop (control &body body)
(let ((variables ())
(lower-bounds ())
(upper-bounds ()))
(loop
:for ctl :in (reverse control)
:do (destructuring-bind (variable bound1 &optional (bound2 nil got-bound2)) ctl
(push variable variables)
(push (if got-bound2 bound1 0) lower-bounds)
(push (if got-bound2 bound2 bound1) upper-bounds)))
(labels ((recurr (vars lowers uppers)
(if (null vars)
`(progn ,#body)
`(loop
:for ,(car vars) :upfrom ,(car lowers) :to ,(car uppers)
:do ,(recurr (cdr vars) (cdr lowers) (cdr uppers))))))
(recurr variables lower-bounds upper-bounds))))
The syntax is slightly different from your proposal.
(nested-loop ((i 0 10) (j 15) (k 15 20))
(format t "~D ~D ~D~%" i j k))
expands into
(loop :for i :upfrom 0 :to 10
:do (loop :for j :upfrom 0 :to 15
:do (loop :for k :upfrom 15 :to 20
:do (progn (format t "~d ~d ~d~%" i j k)))))
The first argument to the macro is a list of list of the form
(variable upper-bound)
(with a lower bound of 0 implied) or
(variable lower-bound upper-bounds)
With a little more love applied, one could even have something like
(nested-loop ((i :upfrom 10 :below 20) (j :downfrom 100 :to 1)) ...)
but then, why bother, if loop has all these features already?