Pascal's triangle: Difference between revisions

Content added Content deleted
(→‎{{header|Common Lisp}}: improve the last version to be a bit more idiomatic, really print n lines and not n+1)
Line 1,512: Line 1,512:


<lang lisp>(defun pascal (n)
<lang lisp>(defun pascal (n)
(genrow n '(1)))
(genrow n '(1)))


(defun genrow (n l)
(defun genrow (n l)
(when (< 0 n)
(when (< 0 n)
(print l)
(print l)
(genrow (1- n) (cons 1 (newrow l)))))
(genrow (1- n) (cons 1 (newrow l)))))


(defun newrow (l)
(defun newrow (l)
(if (> 2 (length l))
(if (> 2 (length l))
'(1)
'(1)
(cons (+ (car l) (cadr l)) (newrow (cdr l)))))</lang>
(cons (+ (car l) (cadr l)) (newrow (cdr l)))))</lang>
Line 1,527: Line 1,527:


<lang lisp>(defun pascal-next-row (a)
<lang lisp>(defun pascal-next-row (a)
(loop :for q :in a
(loop :for q :in a
:and p = 0 :then q
:and p = 0 :then q
:as s = (list (+ p q))
:as s = (list (+ p q))
:nconc s :into a
:nconc s :into a
:finally (rplacd s (list 1))
:finally (rplacd s (list 1))
(return a)))
(return a)))


(defun pascal (n)
(defun pascal (n)
(loop :for a = (list 1) :then (pascal-next-row a)
(loop :for a = (list 1) :then (pascal-next-row a)
:repeat n
:repeat n
:collect a))</lang>
:collect a))</lang>


Another iterative solution, this time using pretty-printing to automatically print the triangle in the shape of a triangle in the terminal. The pascal-print function determines the length of the final row and uses it to decide how wide the triangle should be.
Another iterative solution, this time using pretty-printing to automatically print the triangle in the shape of a triangle in the terminal. The print-pascal-triangle function computes and uses the length of the printed last row to decide how wide the triangle should be.


<lang lisp>
<lang lisp>
(defun next-pascal (l)
(defun next-pascal-triangle-row (list)
`(1
`(1 ,@(loop for i from 0 to (- (length l) 2)
collect (+ (nth i l) (nth (1+ i) l)))
,.(mapcar #'+ list (rest list))
1))
1))


(defun pascal-print (r)
(defun pascal-triangle (number-of-rows)
(loop repeat number-of-rows
(let* ((pasc (loop with p = (list (list 1))
repeat r do (nconc p (list (apply #'next-pascal (last p))))
for row = '(1) then (next-pascal-triangle-row row)
finally (return p)))
collect row))

(len (length (format nil "~A" (car (last pasc))))))
(defun print-pascal-triangle (number-of-rows)
(format t (format nil "~~{~~~D:@<~~{~~A ~~}~~>~~%~~}" len) pasc)))
(let* ((triangle (pascal-triangle number-of-rows))
(max-row-length (length (write-to-string (first (last triangle))))))
(format t
(format nil "~~{~~~D:@<~~{~~A ~~}~~>~~%~~}" max-row-length)
triangle)))
</lang>
</lang>


For example:
For example:


<lang lisp>(pascal-print 4)</lang>
<lang lisp>(print-pascal-triangle 4)</lang>
<lang>
<lang>
1
1
1 1
1 1
1 2 1
1 2 1
1 3 3 1
1 3 3 1
1 4 6 4 1
</lang>
</lang>
<lang lisp>(pascal-print 8)</lang>
<lang lisp>(print-pascal-triangle 8)</lang>
<lang>
<lang>
1
1
1 1
1 1
1 2 1
1 2 1
1 3 3 1
1 3 3 1
1 4 6 4 1
1 4 6 4 1
1 5 10 10 5 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
</lang>
</lang>