## Solution to Quirk's challenge problem
## Written by M O'Brien. Copyright 2006.
## Licenced to others under GPL.
## Language is GNU Octave ([url]http://www.octave.org[/url])
## READ DATA FILE
fileid=fopen("data.dat","rt");
[x1,count]=fscanf(fileid,"%f",1);
[y1,count]=fscanf(fileid,"%f",1);
[x2,count]=fscanf(fileid,"%f",1);
[y2,count]=fscanf(fileid,"%f",1);
[numcircles,count]=fscanf(fileid,"%d",1);
for k=1:numcircles
[circledat,count]=fscanf(fileid,"%f %f %f",3);
circx(k)=circledat(1);
circy(k)=circledat(2);
radius(k)=circledat(3);
endfor
fclose(fileid);
## Start the interesting stuff
linelength=sqrt( (x2-x1)**2 + (y2-y1)**2);
totalpathlength=linelength;
numcirclesintersected=0;
for k=1:numcircles
##--------------------------------------------------------------------
## calculate distance between circle center and the line.
numerator=abs((x2-x1)*(y1-circy(k)) - \
(x1-circx(k))*(y2-y1) );
denominator=sqrt( (x2-x1)**2 + (y2-y1)**2 );
disttoline=numerator/denominator;
##--------------------------------------------------------------------
if (disttoline < radius(k))
## the line is intersecting the current circle, forming a chord.
## Only use less than because if it is equal, it is a tangent line
## and will not affect the path extension at all
numcirclesintersected=numcirclesintersected+1;
halfangle=acos(disttoline/radius(k));
chordlength=2*radius(k)*sin(halfangle);
arclength=2*halfangle*radius(k);
pathdifference=arclength-chordlength;
else
## Line does not interesect the circle.
pathdifference=0;
endif
totalpathlength=totalpathlength+pathdifference;
endfor
## final output comes now
disp("total number of circles intersected"),disp(numcirclesintersected);
disp("length of line w/o circles factored in"), disp(linelength);
disp("final path length after circles"), disp(totalpathlength);
fileid=fopen("output.dat","wt");
fprintf(fileid,"%f",totalpathlength);
fclose(fileid);
## end program