Identify the Conic Section Given 5 distinct points on a two-dimensional plane, determine the type of conic section formed by the points. The output shall be one of circle, hyperbola, ellipse, or parabola.
Rules

The points will be in general linear position, meaning that no three points are collinear, and thus the conic passing through them will be unique.
The coordinates of the 5 points will be decimal numbers between -10 and 10, inclusive.
The precision for the decimal/float values should be the precision of your language's native float/decimal type. If your language/data type is arbitrary-precision, you may use 12 digits after the decimal point as the maximum required precision, rounding toward zero (e.g. 1.0000000000005 == 1.000000000000).
Capitalization of the output does not matter.
Outputting ellipse when the conic section is actually a circle is not allowed. All circles are ellipses, but you must output the most specific one.

On floating point inaccuracies and precision:

I'm trying to make this as simple as possible, so that issues with floating point inaccuracies don't get in the way. The goal is, if the data type was &quot;magical infinite precision value&quot; instead of float/double, then everything would work perfectly. But, since &quot;magical infinite precision value&quot; doesn't exist, you write code that assumes that your values are infinite precision, and any issues that crop up as a result of floating point inaccuracies are features, not bugs.

Test Cases
(0, 0), (1, 5), (2, 3), (4, 8), (9, 2) =&gt; hyperbola
(1.2, 5.3), (4.1, 5.6), (9.1, 2.5), (0, 1), (4.2, 0) =&gt; ellipse
(5, 0), (4, 3), (3, 4), (0, 5), (0, -5) =&gt; circle
(1, 0), (0, 1), (2, 1), (3, 4), (4, 9) =&gt; parabola
JavaScript (ES6), 316 323 347



p=&gt;[1,2,4].some(x=&gt;(d=D(Q=[[x&amp;1,x&amp;2,x&amp;4,0,0,0],...p.map(([x,y])=&gt;[x*x,x*y,y*y,x,y,1])]))?[a,b,c]=Q.map((v,i)=&gt;D(Q.map((r,j)=&gt;(r=[...r],r[i]=x*!j,r)))/d):0,D=m=&gt;m[1]?m[0].reduce((r,v,i)=&gt;r+(i&amp;1?-v:v)*D(m.slice(1).map(r=&gt;r.filter((a,j)=&gt;j-i))),0):m)&amp;&amp;(d=b*b-4*a*c)?d&lt;0?!b&amp;c==a?'Circle':'Ellipse':'Hyperbola':'Parabola'


Any language better suited for handling matrix and determinant should score better (APL, J, CJAM, Jelly)

References: General form of a conic, Five points determine a conic, System of linear equations, Determinant

In the cartesian plane, the general equation of a conic is

A*x*x + B*x*y + C*y*y + D*x + E*y + F = 0 


having A or B or C not equal to 0 (otherwise it's a straight line)

A ... F are six unknowns to be found. With five pairs of (x,y) we can build a linear system with five equations, and scaling remove one dimension. That is, we can set one of A,B or C to 1 if it's not 0 (and we know that at least one is not 0).

I build and try to solve 3 systems: first trying A=1. If not solvable then B=1, then C. (There could be a better way, but that's my best at the time)

Having the values of A,B,C we can classify the conic looking at the discriminant d=B*B-4*A*C


d == 0 -> parabola  
d > 0 -> hyperbola  
d &lt; 0 -> ellipse, particularly (A == C and B == 0) -> circle


Less golfed

F=p=&gt;(
  // Recursive function to find determinant of a square matrix
  D=m=&gt;m[1]
    ?m[0].reduce((r,v,i)=&gt;r+(i&amp;1?-v:v)*D(m.slice(1).map(r=&gt;r.filter((a,j)=&gt;j-i))),0)
    :m,
  // Try 3 linear systems, coefficients in Q
  // Five equation made from the paramaters in p
  // And a first equation with coefficient like k,0,0,0,0,0,1 (example for A)  
  [1,2,4].some(
    x =&gt; (
      // matrix to calc the determinant, last coefficient is missing at this stage
      Q = [ 
        [x&amp;1, x&amp;2, x&amp;4, 0,0,0] // first one is different
        // all other equations built from the params 
        ,...p.map( ([x,y]) =&gt; [x*x, x*y, y*y, x, y, 1] )
      ],
      d = D(Q), // here d is the determinant
      d &amp;&amp; ( // if solvable  then d != 0
        // add missing last coefficient to Q
        // must be != 0 for the first row, must be 0 for the other
        Q.map( r=&gt; (r.push(x), x=0) ),
        // solve the system (Cramer's rule), I get all values for A...F but I just care of a,b,c
        [a,b,c] = Q.map((v,i)=&gt;D(Q.map(r=&gt;(r=[...r],r[i]=r.pop(),r))) / d),
        d = b*b - 4*a*c, // now reuse d for discriminant
        d = d&lt;0 ? !b&amp;c==a ? 'Circle' : 'Ellipse' // now reuse d for end result
        : d ? 'Hyperbola' : 'Parabola'
      ) // exit .some if not 0
    ), d // .some exit with true, the result is in d
  )  
)


Test



F=p=&gt;[1,2,4].some(x=&gt;(d=D(Q=[[x&amp;1,x&amp;2,x&amp;4,0,0,0],...p.map(([x,y])=&gt;[x*x,x*y,y*y,x,y,1])]))?[a,b,c]=Q.map((v,i)=&gt;D(Q.map((r,j)=&gt;(r=[...r],r[i]=x*!j,r)))/d):0,D=m=&gt;m[1]?m[0].reduce((r,v,i)=&gt;r+(i&amp;1?-v:v)*D(m.slice(1).map(r=&gt;r.filter((a,j)=&gt;j-i))),0):m)&amp;&amp;(d=b*b-4*a*c)?d&lt;0?!b&amp;c==a?'Circle':'Ellipse':'Hyperbola':'Parabola'

console.log=(...x)=&gt;O.textContent+=x+'\n'

;[
 [[0, 0], [1, 5], [2, 3], [4, 8], [9, 2]]
,[[1.2, 5.3],[4.1, 5.6], [9.1, 2.5], [0, 1], [4.2, 0]]
,[[5, 0], [4, 3], [3, 4], [0, 5], [0, -5]]
,[[1, 0], [0, 1], [2, 1], [3, 4], [4, 9]]
].forEach(t=&gt;console.log(t.join`|`+' =&gt; '+F(t)))
&lt;pre id=O&gt;&lt;/pre&gt;