My recursive call seems to not be working, I am trying to make a triangle given an integer, and with the help of you guys I was finally able to make the string print on the same line, the correct amount of times for 1 line. At the end of printing the line, I have a recursive call that calls on triangle to make another line, one character shorter. This call seems to never be reached for some reason. Please find the code below, thank you all in advance for any and all help, it is all greatly appreciated!
Note: On a side note, is there any way to stop a function in Lisp similar to a return statement? I would like for the recursion to stop at k = 1, and not continue to k = 0.
(defun newTriangle (k)
(cond ((<= k 0) (princ '(Nope)))
((or (= k 1) (= k -1)) (princ 'a))
((> k 0) (make-string k :initial-element #\a))
(newTriangle (- k 1))))
(print (newTriangle 3))
sample output triangle(3)
aaa
aa
a
sample output triangle(-3)
aaa
aa
a
First, you need to decide exactly what it is that newTriangle is doing. The call (print (newTriangle 3)) suggests that newTriangle should return a string, which is then printed by the call to print. But, the OP definition of newTriangle is both printing output, and returning a single line of the triangle as a string.
The recursive call to newTriangle is never reached because all possible cases for the value of k are exhausted before this line is reached. Since k can only be less than zero, equal to zero, or greater than zero, and since all of these cases are tested for before reaching the recursive call, it is never reached. Also note that the OP code has the syntax wrong for the final part of the cond statement. The first expression in a cond branch is a test, and the convention is to use t here for a branch that will always be evaluated if reached. But, this many cases are not needed here.
Assuming the newTriangle function should not return a string, but should print a triangle as a side-effect, what should it do? If the input number is greater than 0, it should print a line with a number of characters equal to the input number and then call itself with the input reduced by one; otherwise it should do nothing:
(defun print-triangle (k)
(when (> k 0)
(princ (make-string k :initial-element #\a))
(terpri)
(print-triangle (- k 1))))
This definition is named print-triangle to emphasize that it prints a triangle as a side-effect, and because kebab-case is idiomatic in Lisps, and camelCase is not. Note that each time that print-triangle is called with input greater than zero, a string of the correct length is printed, and then a newline is printed (with the obscurely-named terpri, which just writes a newline to the current output stream), before calling print-triangle again with k reduced by 1.
Sample REPL interaction:
CL-USER> (print-triangle 3)
aaa
aa
a
NIL
If the goal is instead to return a string, one approach would be to call a helper function that keeps the result in a parameter:
(defun new-triangle (k)
(build-triangle k ""))
(defun build-triangle (k result)
(if (> k 0)
(build-triangle (- k 1)
(concatenate 'string
result
(make-string k :initial-element #\a)
(string #\newline)))
result))
Here, new-triangle takes an integer argument, and calls build-triangle, passing both the integer argument and an empty string in the result position. The build-triangle function operates much the same as print-triangle before, but instead of printing the lines, they are concatenated with result, along with a string containing a newline. When build-triangle is finished, the result string is returned to new-triangle. Note that simply calling new-triangle from the REPL will print the resulting string as data (i.e., with quotation marks); calling print on the result of new-triangle will both print the string as data, and return the string. To see the string printed without quotation marks, format can be used; or you could use princ which will print the string without quotation marks, and return the string itself:
CL-USER> (new-triangle 3)
"aaa
aa
a
"
CL-USER> (print (new-triangle 3))
"aaa
aa
a
"
"aaa
aa
a
"
CL-USER> (format t "~A" (new-triangle 3))
aaa
aa
a
NIL
CL-USER> (princ (new-triangle 3))
aaa
aa
a
"aaa
aa
a
"
Related
I am trying to understand how the count-even function given in my textbook works and I'm not sure if I completely understand it.
I have provided my understanding of the function in comments next to code. Can someone explain what is happening and correct me in each step of this function.
And I don't understand how this function is recursive. What is the base case ?
(define (ce x) ; x is an argument that takes in a list
(if (pair? x) ; I don't understand why this is here
(+ (ce (car x)) ; Add the resuls of recursive call together (0 or 1)
(ce (cdr x)))
(if (and (number? x) (even? x)) ; if x is a number and x is even then return 1 ? Else return 0 ?
1
0) ) )
In a recursive function there are usually two cases:
The result is a call to the same function
The result is a simple value, the base case
You choose between the two cases with an if.
Hence the base case is:
(if (and (number? x) (even? x))
1
0) ) )
And the recursive case is:
(+ (count-evens (car x))
(count-evens (cdr x)))
Comments:
The argument x doesn't need to be a list. pairs? tests for a list. If it is just a value then we have the base case. If an even number then result is one, else zero.
If the argument x is a list, we split it into two parts, the head (car) and the tail (cdr). The head is just a value, and so when we rerun count-evens on it we end up with the base case.
The tail is passed to count-evens which keeps slicing off a value at a time until we have a value in the car and empty list in cdr. In the base case, the first value is assessed for an even number, and the empty list is always evaluated as zero.
Ok, I'm been learning COMMON LISP programming and I'm working on a very simple program to calculate a factorial of a given integer. Simple, right?
Here's the code so far:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
)
(factorial x)
Problem is, when I run this on either CodeChef or Rexter.com, I get a similar error: "NIL is NOT a number."
I've tried using cond instead of an if to no avail.
As a side note, and most bewildering of all, I've seen a lot of places write the code like this:
(defun fact(n)
(if (= n 1)
1
(* n (fact (- n 1)))))
Which doesn't even make sense to me, what with the 1 just floating out there with no parentheses around it. However, with a little tinkering (writing additional lines outside the function) I can get it to execute (equally bewildering!).
But that's not what I want! I'd like the factorial function to print/return the values without having to execute additional code outside it.
What am I doing wrong?
One actually needs to flush the I/O buffers in portable code with FINISH-OUTPUT - otherwise the Lisp may want to read something and the prompt hasn't yet been printed. You better replace SETQ with LET, as SETQ does not introduce a variable, it just sets it.
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(finish-output) ; this makes sure the text is printed now
(let ((x (read)))
(format t "~D! is ~D" x (factorial x)))
Before answering your question, I would like to tell you some basic things about Lisp. (Neat fix to your solution at the end)
In Lisp, the output of every function is the "last line executed in the function". Unless you use some syntax manipulation like "return" or "return-from", which is not the Lisp-way.
The (format t "your string") will always return 'NIL as its output. But before returning the output, this function "prints" the string as well.
But the output of format function is 'NIL.
Now, the issue with your code is the output of your function. Again, the output would be the last line which in your case is:
(format t "~D! is ~D" n a)
This will return 'NIL.
To convince yourself, run the following as per your defined function:
(equal (factorial 1) 'nil)
This returns:
1! is 1
T
So it "prints" your string and then outputs T. Hence the output of your function is indeed 'NIL.
So when you input any number greater than 1, the recursive call runs and reaches the end as input 1 and returns 'NIL.
and then tries to execute this:
(setq a (* n (factorial (- n 1))))
Where the second argument to * is 'NIL and hence the error.
A quick fix to your solution is to add the last line as the output:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
a ;; Now this is the last line, so this will work
)
(factorial x)
Neater code (with Lisp-like indentation)
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(setq x (read))
(format t "~D! is ~D" x (factorial x))
Common Lisp is designed to be compiled. Therefore if you want global or local variables you need to define them before you set them.
On line 2 you give x a value but have not declared the existence of a variable by that name. You can do so as (defvar x), although the name x is considered unidiomatic. Many implementations will give a warning and automatically create a global variable when you try to set something which hasn’t been defined.
In your factorial function you try to set a. This is a treated either as an error or a global variable. Note that in your recursive call you are changing the value of a, although this wouldn’t actually have too much of an effect of the rest of your function were right. Your function is also not reentrant and there is no reason for this. You can introduce a local variable using let. Alternatively you could add it to your lambda list as (n &aux a). Secondarily your factorial function does not return a useful value as format does not return a useful value. In Common Lisp in an (implicit) progn, the value of the final expression is returned. You could fix this by adding a in the line below your format.
For tracing execution you could do (trace factorial) to have proper tracing information automatically printed. Then you could get rid of your format statement.
Finally it is worth noting that the whole function is quite unidiomatic. Your syntax is not normal. Common Lisp implementations come with a pretty printer. Emacs does too (bound to M-q). One does not normally do lots of reading and setting of global variables (except occasionally at the repl). Lisp isn’t really used for scripts in this style and has much better mechanisms for controlling scope. Secondarily one wouldn’t normally use so much mutating of state in a function like this. Here is a different way of doing factorial:
(defun factorial (n)
(if (< n 2)
1
(* n (factorial (1- n)))))
And tail recursively:
(defun factorial (n &optional (a 1))
(if (< n 2) a (factorial (1- n) (* a n))))
And iteratively (with printing):
(defun factorial (n)
(loop for i from 1 to n
with a = 1
do (setf a (* a i))
(format t “~a! = ~a~%” i a)
finally (return a)))
You can split it up into parts, something like this:
(defun prompt (prompt-str)
(write-line prompt-str *query-io*)
(finish-output)
(read *query-io*))
(defun factorial (n)
(cond ((= n 1) 1)
(t (* n
(factorial (decf n)))))
(defun factorial-driver ()
(let* ((n (prompt "Enter a number: "))
(result (factorial n)))
(format *query-io* "The factorial of ~A is ~A~%" n result)))
And then run the whole thing as (factorial-driver).
Sample interaction:
CL-USER 54 > (factorial-driver)
Enter a number:
4
The factorial of 4 is 24
I'm a beginner with functional programming and I try to pretty print a maze.
Here is my function
(defn pprint-maze
[arr row col]
(loop [coll arr idx 0]
(match [idx]
[(_ :guard #(= (mod idx col) 0))] (println "") ; write a \n
:else (print "-")) ; write a wall
(when (next coll)
(recur (next coll) (inc idx)))))
My function takes the collection and the size of the maze and for now, just print a dash and a \n at the end of the row.
The problem I've it's :
Exception in thread "main" clojure.lang.ArityException: Wrong number of args (1) passed to: core/pprint-maze/fn--4873/fn--4874
I think the function pointed out is my loop function, and the problem is related to match (because when I comment the match block, everything work). I think that match try to call the loop function with nil as argument (the return of the println function).
How to solve that ?
The function passed to :guard should take exactly one argument, the value being guarded. Your function takes zero arguments.
I often want to output lists and also print their position in the list e.g.
'(a b c) would become "1:A 2:B 3:C"
As FORMAT already supports iterating over a given list, I was wondering whether it also provides some sort of counting directive?
E.g. the FORMAT string could look like this: "~{~#C:~a~}" whereas ~#C would be the counter.
If you want a boring answer, here you go:
(format T "~:{~a:~a ~}" (loop for i from 0 for e in '(x y z) collect (list i e)))
And now for a more interesting one! Similarly to #Renzo's answer, this uses the Tilde directive to achieve its work.
(defvar *count* 0)
(defvar *printer* "~a")
(defun iterate-counting (stream arg c at)
(declare (ignore c))
(let ((*count* (if at -1 0)))
(destructuring-bind (*printer* delimiter &rest args) arg
(format stream (format NIL "~~{~~/iterate-piece/~~^~a~~}" delimiter) args))))
(defun iterate-piece (stream arg &rest dc)
(declare (ignore dc))
(incf *count*)
(format stream *printer* *count* arg))
This uses two special variables to make it both thread-safe and to allow nesting. I won't say that it's handy to use though. The first item of the argument to list has to be a format string that denotes how to print the argument and counter. For such a format list, the first argument is the counter, and the second argument is the actual item to list. You can switch those around if you need to using the asterisk directive. The second item should be a string to print as the delimiter between each item. Finally, the rest of the list has to be the actual items to print.
(format T "~/iterate-counting/" '("~a:~a" " " x y z))
=> 1:X 2:Y 3:Z
(format T "~/iterate-counting/" '("~a:~/iterate-counting/" " " ("~a>~a" "," 0 1 2) ("~a>~a" "," a b c) ("~a>~a" "," x y z)))
=> 1:1>0,2>1,3>2 2:1>A,2>B,3>C 3:1>X,2>Y,3>Z
If you want it to start counting from zero, add an # modifier to the iterate-counting:
(format T "~#/iterate-counting/" '("~a:~a" " " x y z))
=> 0:X 1:Y 2:Z
I wouldn't personally use this, as it's far less than obvious what is going on if you stumble across the directive uninitiated. It would probably be much less confusing for the potential future reader to write a tailored function for this, than trying to ab/use format.
A not so simple but reusable way of producing a numbered list is by using the ~/ directive (Tilde Slash: Call Function) with a user-defined function. For instance:
(let ((position 0))
(defun init-pos(str arg col at)
(declare (ignore str arg col at))
(setf position 0))
(defun with-pos(str arg col at)
(declare (ignore col at))
(format str "~a:~a" (incf position) arg)))
and then write format like this one:
(format nil "~/init-pos/~{~/with-pos/~^ ~}" nil '(a b c))
Note that, as said in a comment, this solution has two limitations:
You cannot use it if you need to format objects in concurrent threads, and
you cannot use it for nested lists.
Is there a repeat directive for (format) in Common lisp, something like(I know this won't work):
(format t "~5C" #\*)
Just wondering if there isn't a more elegant way to do it than this:(from rosettacode
)
(defun repeat-string (n string)
(with-output-to-string (stream)
(loop repeat n do (write-string string stream))))
(princ (repeat-string 5 "hi"))
(defun write-repeated-string (n string stream)
(loop repeat n do (write-string string stream)))
(write-repeated-string 5 "hi" *standard-output*))
Generally you can use the format iteration:
(format t "~v#{~A~:*~}" 5 "hi")
~A can output all kinds of items, not just characters. For more information see uselpa's linked answers.
Above takes the iteration number from the first argument. Thus the v behind the tilde.
The rest of the arguments will be consumed by the iteration. Thus the #.
Inside the iteration we go back one element. Thus ~:*.
It's similar to (format t "~v{~A~:*~}" 5 '("hi")), which might be simpler to understand.