Another LISP question, I am currently trying to write a function that will return a triangle, whose size will depend on the input of the user
ex: 7
aaaaaaa
aaaaaa
aaaaa
aaaa
aaa
aa
a
ex: -3
aaa
aa
a
I have the code for the positive integer part written, the logic at least, but I've run into a hurdle. I can't seem to have the loop print the letter on the same line. Every time the loop iterates, it goes to the next line. Is there any way to fix this? Also any comments/suggestions on my implementation would be greatly appreciated, I am very new at Lisp. Thanks a bunch everyone! You will find my code below
(defun triangle (k)
(if (or (= k 1) (= k -1))
(print 'a))
(if (> k 0)
(loop for n from 0 to k
do (print 'a))
(triangle (- k 1))))
(print (triangle 2))
Indeed, print
prints a newline. princ
does not.
To further control how you print stuff, there is format
. It works with directives that start with ~
. Thus, ~a
(or ~A
) prints the object given as argument æsthetically. ~&
prints a newline.
(format t "~a~&" 'a)
t
is for *standard-output*
.
See https://lispcookbook.github.io/cl-cookbook/strings.html#structure-of-format
This link also explains how to align strings to the right or to the left, which you might need (if you go the format route).
You can make your code shorter. There is make-string count :initial-element character
that can replace the loop. A character is written #\a
.
Also you could call triangle recursively only if k is > 0 (zerop
). With this and (format t "~a~&" (make-string k :initial-element #\a))
, my version has only one call to the print function and less "if" machinery:
(defun my-triangle (k)
(format t "~a~&" (make-string k :initial-element #\a))
(unless (zerop k)
(my-triangle (decf k))))