#|
Explanation:
The function takes as input the lines of the triangle, where each line
is represented as a list consisting of the points on that line. Now,
for every pair of lines, there will be a unique intersection point.
The main iteration consists of three loops which basically iterates
through all ways of picking three lines out of the seven, without
replacement and without regard to order. For every iteration, the
pairwise intersections of the three lines are found. If those three
points are distinct, we have found a triangle, which is stored in the
result variable.
Finally the number of obtained results is returned.
Remarks:
1. I could have written it to increase the triangle count within the
loop, but this way seemed nicer to me, since it is easy now to make
it return the actual triangles instead.
2. I took some liberty in choosing the representation of the
trianble/points. The problem description was not very detailed, so
I think it is OK. My representation accomodates for the case where
another line is added, according to the specification.
|#
(defvar *lines* '((p0 p1) (p0 p2 p4 p6) (p0 p3 p7 p9) (p0 p5 p8 p10)
(p1 p2 p3 p5) (p1 p4 p7 p8) (p1 p6 p9 p10)))
(defun triangles (lines)
(loop with result = nil for (line1 . rest1) on lines do
(loop for (line2 . rest2) on rest1 do
(loop for (line3 . rest3) on rest2 do
(let ((p1 (first (intersection line1 line2)))
(p2 (first (intersection line2 line3)))
(p3 (first (intersection line1 line3))))
(unless (and (eq p1 p2) (eq p1 p3))
(push (list p1 p2 p3) result)))))
finally (return (length result))))