JavaScript (ES6), 316 323 347
p=>[1,2,4].some(x=>(d=D(Q=[[x&1,x&2,x&4,0,0,0],...p.map(([x,y])=>[x*x,x*y,y*y,x,y,1])]))?[a,b,c]=Q.map((v,i)=>D(Q.map((r,j)=>(r=[...r],r[i]=x*!j,r)))/d):0,D=m=>m[1]?m[0].reduce((r,v,i)=>r+(i&1?-v:v)*D(m.slice(1).map(r=>r.filter((a,j)=>j-i))),0):m)&&(d=b*b-4*a*c)?d<0?!b&c==a?'Circle':'Ellipse':'Hyperbola':'Parabola'
ภาษาใดที่เหมาะกับการจัดการเมทริกซ์และดีเทอร์มิแนนต์ควรมีคะแนนที่ดีกว่า (APL, J, CJAM, Jelly)
อ้างอิง: รูปแบบทั่วไปของรูปกรวย , ห้าจุดที่กำหนดรูปกรวย , ระบบสมการเชิงเส้น , ปัจจัย
ในระนาบคาร์ทีเซียนสมการทั่วไปของรูปกรวยคือ
A*x*x + B*x*y + C*y*y + D*x + E*y + F = 0
มี A หรือ B หรือ C ไม่เท่ากับ 0 (ไม่เช่นนั้นจะเป็นเส้นตรง)
A ... F เป็นสิ่งแปลกปลอมที่พบได้หกแห่ง ด้วยห้าคู่ (x, y) เราสามารถสร้างระบบเชิงเส้นที่มีสมการห้าแบบและปรับขนาดลบหนึ่งมิติ นั่นคือเราสามารถตั้งค่าหนึ่งใน A, B หรือ C เป็น 1 ถ้าไม่ใช่ 0 (และเรารู้ว่าอย่างน้อยหนึ่งไม่ใช่ 0)
ฉันสร้างและลองแก้ปัญหา 3 ระบบก่อนอื่นให้ลอง A = 1 หากไม่สามารถแก้ไขได้แล้ว B = 1 ก็จะเป็น C (อาจเป็นวิธีที่ดีกว่า
มีค่าของ A, B, C เราสามารถจำแนกรูปกรวยที่ดู discriminant d=B*B-4*A*C
- d == 0 -> พาราโบลา
- d> 0 -> ไฮเปอร์โบลา
- d <0 -> วงรีโดยเฉพาะ (A == C และ B == 0) -> วงกลม
น้อย golfed
F=p=>(
// Recursive function to find determinant of a square matrix
D=m=>m[1]
?m[0].reduce((r,v,i)=>r+(i&1?-v:v)*D(m.slice(1).map(r=>r.filter((a,j)=>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 => (
// matrix to calc the determinant, last coefficient is missing at this stage
Q = [
[x&1, x&2, x&4, 0,0,0] // first one is different
// all other equations built from the params
,...p.map( ([x,y]) => [x*x, x*y, y*y, x, y, 1] )
],
d = D(Q), // here d is the determinant
d && ( // 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=> (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)=>D(Q.map(r=>(r=[...r],r[i]=r.pop(),r))) / d),
d = b*b - 4*a*c, // now reuse d for discriminant
d = d<0 ? !b&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
)
)
ทดสอบ
F=p=>[1,2,4].some(x=>(d=D(Q=[[x&1,x&2,x&4,0,0,0],...p.map(([x,y])=>[x*x,x*y,y*y,x,y,1])]))?[a,b,c]=Q.map((v,i)=>D(Q.map((r,j)=>(r=[...r],r[i]=x*!j,r)))/d):0,D=m=>m[1]?m[0].reduce((r,v,i)=>r+(i&1?-v:v)*D(m.slice(1).map(r=>r.filter((a,j)=>j-i))),0):m)&&(d=b*b-4*a*c)?d<0?!b&c==a?'Circle':'Ellipse':'Hyperbola':'Parabola'
console.log=(...x)=>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=>console.log(t.join`|`+' => '+F(t)))
<pre id=O></pre>
circleโฟลตเอาต์พุตดูเหมือนจะต้องมีการตรวจสอบความเท่าเทียมกันแบบลอยเพื่อแยกความแตกต่างจากวงรีที่กลมมาก เราควรคาดเดาสิ่งที่แม่นยำที่นี่