สามตัวชี้! แต่อะไรล่ะ


24

จากhttp://en.wikipedia.org/wiki/Triangle : ป้อนคำอธิบายรูปภาพที่นี่


เขียนโปรแกรมที่ใช้ tuples พิกัด 2d (คาร์ทีเซียน) สามมิติและจำแนกประเภทของจุดสามจุดที่อธิบาย

ในเกือบทุกกรณีจุดเหล่านี้จะอธิบายรูปสามเหลี่ยมชนิดต่าง ๆ ในบางกรณีความเสื่อมคะแนนจะอธิบายจุดเอกพจน์หรือเส้นตรง โปรแกรมจะพิจารณาว่าแท็กใดต่อไปนี้ที่ใช้กับรูปร่างที่อธิบายไว้:

  • จุด (3 คะแนนเป็นเหตุการณ์ร่วม)
  • เส้น (3 คะแนนอยู่ในแนวเส้นตรง - อาจมีเหตุการณ์ร่วมไม่เกิน 2 จุด)
  • ด้านเท่ากันหมด (3 ด้านเท่ากัน 3 มุมเท่ากัน)
  • หน้าจั่ว (2 ด้านเท่ากัน 2 มุมเท่ากัน)
  • Scalene (0 ด้านเท่ากัน, 0 มุมเท่ากัน)
  • ขวา (1 มุมทั้งหมดπ / 2 (หรือ 90 °))
  • เอียง (0 มุมทั้งหมด exactly / 2 (หรือ 90 °))
  • ป้าน (1 มุม> π / 2 (หรือ 90 °))
  • เฉียบพลัน (3 มุม <π / 2 (หรือ 90 °))

โปรดทราบว่าสำหรับรูปร่างที่อธิบายไว้บางส่วนจะใช้แท็กมากกว่าหนึ่งรายการด้านบน ตัวอย่างเช่นมุมฉากใด ๆ ก็จะเป็นหน้าจั่วหรือย้วย

อินพุต

  • โปรแกรมอาจอ่านค่าพิกัด 3 ค่าจาก STDIN, บรรทัดคำสั่ง, ตัวแปรสภาพแวดล้อมหรือวิธีการใดก็ได้ที่สะดวกสำหรับภาษาที่คุณเลือก
  • การป้อนข้อมูลพิกัดจะจัดรูปแบบของฉัน แต่สะดวกสำหรับภาษาที่คุณเลือก สามารถสันนิษฐานได้ว่าหมายเลขอินพุตทั้งหมดมีรูปแบบที่ถูกต้องตามประเภทข้อมูลที่คุณใช้
  • ไม่มีสิ่งใดสามารถคาดเดาได้เกี่ยวกับการเรียงลำดับของพิกัดอินพุต

เอาท์พุต

  • โปรแกรมจะส่งออกไปยัง STDOUT, กล่องโต้ตอบหรือวิธีการแสดงผลใด ๆ ที่สะดวกสำหรับภาษาที่คุณเลือก
  • เอาต์พุตจะแสดงแท็กทั้งหมดที่ใช้กับรูปร่างที่อธิบายโดยพิกัดอินพุต
  • แท็กอาจถูกส่งออกในลำดับใด ๆ

กฎอื่น ๆ

  • ไลบรารี่ตรีโกณมิติในภาษาของคุณได้รับอนุญาต แต่ API ใด ๆ ที่คำนวณเฉพาะประเภทสามเหลี่ยมจะถูกแบน
  • เมื่อพิจารณาความเท่าเทียมกันของมุมหรือความยาวของด้านคุณอาจจะสิ้นสุดการเปรียบเทียบค่าจุดลอย สองค่าดังกล่าวจะได้รับการพิจารณาว่า "เท่ากัน" หากค่านั้นอยู่ภายใน 1% ของค่าอื่น ๆ
  • “ ช่องโหว่” มาตรฐานซึ่งไม่ตลกอีกต่อไป
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ

ตัวอย่าง

Input                   Output
(1,2) (1,2) (1,2)       Point
(1,2) (3,4) (5,6)       Line
(0,0) (1,1) (2,0)       Isosceles Right
(0,0) (2,1) (10,1)      Scalene Oblique Obtuse

4
ฉันกำลังจะให้สิทธิ์ " Triangle Tag " นี้ แต่มันสั้นลงจากจำนวนขั้นต่ำ 15 ตัวอักษร
บาดเจ็บทางดิจิตอล

เกิดอะไรขึ้นถ้าจุดสองจุดเหมือนกัน?
Ypnypn

@Ypnypn ในกรณีนั้นมันเป็นเส้น
บาดเจ็บทางดิจิตอล

Triangle Tag
Derek 朕會功夫

2
มีปัญหากับคำจำกัดความ "เฉียบพลัน" หรือไม่? เป็นไปไม่ได้หรือว่าทุกมุมมีค่ามากกว่า PI / 2?
Arnaud

คำตอบ:


10

C (451 ไบต์)

ใช้ความยาวและความลาดเอียงเท่านั้น

p[2],q[2],r[2];z(c){char*y[]={"Line","Point","Isosceles ","Equilateral ","Scalene ","Right","Oblique ","Acute","Obtuse"};printf(y[c]);}d(int*a,int*b){int c=*a++-*b++,e=*a-*b;return c*c+e*e;}main(){scanf("%d%d%d%d%d%d",p,p+1,q,q+1,r,r+1);int a=d(p,q),b=d(q,r),c=d(r,p),e=!a+!b+!c,f=(a==b)+(b==c)+(c==a),g=a>b&&b>c?a:b>c?b:c,h=g^a?g^b?a+b:c+a:b+c;e?z(e/2):(1[q]-1[p])*(*r-*q)^(1[r]-1[q])*(*q-*p)?f?z(2+f/2),f-1&&z(2):z(4),h^g?z(6),z(7+(h<g)):z(5):z(0);}

Ungolfed (และผู้ประกอบการที่ประกอบไปด้วยแทนที่ด้วยถ้า / อื่น ๆ ):

int p[2],q[2],r[2];

void print(c){
    char *y[]={"Line","Point","Isosceles ","Equilateral ","Scalene ","Right","Oblique ","Acute","Obtuse"};
    printf(y[c]);
}
squared_distance(int *a,int *b){
    int c = *a++ - *b++, e = *a - *b;
    return c*c+e*e;
}
main(){
    scanf("%d%d%d%d%d%d",p,p+1,q,q+1,r,r+1); // read in coordinates
    int a = squared_distance(p,q),b = squared_distance(q,r),c = squared_distance(r,p),
    e=!a+!b+!c, // number of sides of length 0
    f=(a==b)+(b==c)+(c==a), // number of equal-length pairs
    g = a > b && b > c ? a : (b > c ? b : c), // longest side
    h = g != a ? g != b ? a + b : c + a : b + c; // sum of squares of length of other two sides
    if(e)
        print(e/2); // 1 side of len 0: line, 3 sides: point
    // comparing slopes PQ and QR
    else if((q[1]-p[1])*(*r-*q) != (r[1]-q[1])*(*q-*p)){ // not line
        if(f){
            print(2+f/2); // 1 pair of equal length sides: isosceles, 3: equilateral
            if(f-1) print(2); // equilateral therefore also isosceles
        }else print(4); // 0: scalene
        if(h!=g){ // a^2+b^2!=c^2: not right
            print(6); // oblique
            print(7+(h<g)); // a^2+b^2<c^2:obtuse, acute otherwise 
        }else print(5); // right
    }else
        print(0); // line
}

อินพุต (ถึง stdin) รูปแบบ: xyxyxy

อดีต 0 0 1 1 2 0 สำหรับ Isosceles Right


@digitaltrauma ./triangle <<< "1 2 1 2 1 2"ควรใช้พร้อมคำพูด
es1024

ใช่แน่นอนขอโทษด้วย คำตอบที่ดี โดยเฉพาะอย่างยิ่งฉันชอบที่คุณสามารถหลีกเลี่ยงการลอยตัวและดังนั้นจึงไม่ต้องกังวลเกี่ยวกับสิ่งที่กฎความเท่าเทียมกันภายใน 1% +1
Digital Trauma

3

C, 333

z,c,r,b,s,i,t[14],g[14];
main(){ 
  for(;i<14;i++){
    g[i]=r=t[(i+2)%6]-t[i%6];r*=r;t[i|1]+=r;
    i<6&&scanf("%d",t+i);
    i>7&&(b<t[i]&&(b=t[i]),s+=t[i],z+=!t[i],c+=t[i]==t[i-2]);  
  }

  if(g[6]*g[9]==g[8]*g[7])puts(z==6?"point":"line");else
    printf(b*2==s?"right ":"oblique %s",b*2>s?"obtuse ":"acute "),puts(c>3?c>5?"equilateral":"isosceles":"scalene");
}

ฉันออกจากช่องว่างในขณะนี้ วิธีนี้ใช้ได้ผล แต่อาจเกี่ยวข้องกับการจัดระเบียบและเล่นกอล์ฟ คณิตศาสตร์คล้ายกับ@es1024คำตอบของ แต่ใช้วนและอาร์เรย์ รูปแบบอินพุตx y x y x y

ตัวแปร

t[]เก็บทั้งอินพุตและกำลังสองของความยาว ในตอนท้ายของโปรแกรมดูเหมือนว่าตารางด้านล่าง (การเพิ่มจำนวนการวนซ้ำของลูปจะนำไปสู่การทำซ้ำความยาวไม่ จำกัด ของความยาวกำลังสอง) ณ จุดเริ่มต้นของความยาววงสแควร์ (ขยะเนื่องจากไม่มีข้อมูลทั้งหมด ) ถูกเก็บไว้ในเซลล์ 1,3 และ 5 โดยไม่จำเป็น แต่จะถูกเขียนทับโดยscanf.ข้อมูลที่เป็นประโยชน์จะถูกเขียนไปยังz,b,cahd sเมื่อi= 9,11,13 ( t[i]และt[i-2]เข้าถึงได้)

01 23 45 67 89 1011 1213
aa bb cc  a  b    c    a
xy xy xy  L  L    L    L

g[]ถูกเพิ่มสายเพื่อเก็บค่า dx และ dy ที่จำเป็นสำหรับการคำนวณความชัน เซลล์เดียวที่ใช้คือ 6 ถึง 9 (0 ถึง 5 ไม่น่าเชื่อถือเนื่องจากข้อมูลทั้งหมดจะไม่สามารถใช้ได้เมื่อมีการเขียน) หากg[6]/g[7]==g[8]/g[9]ความชันของ 2 บรรทัดมีค่าเท่ากันและสามเหลี่ยมเป็นเพียงเส้น (หรือจุด) สมการ ถูกจัดเรียงใหม่ในโปรแกรมเพื่อหลีกเลี่ยงการหาร

rเป็นค่ากลางที่ใช้สำหรับการจัดกำลังสอง

zนับจำนวนด้านยาวเป็นศูนย์ จะได้ชดเชย 3 เพราะห่วงอ่าน 3 t[]เซลล์ว่างใน

cนับจำนวนด้านที่มีความยาวเท่ากัน นอกจากนี้ยังมีออฟเซ็ตของ +3 โปรดทราบว่าด้านaนั้นเขียนขึ้นt[]สองครั้งเพื่อให้สามารถตรวจสอบ a = b, b = c, c = a

bคือความยาวที่ใหญ่ที่สุดของด้าน, กำลังสอง sคือผลรวมของกำลังสองของทุกด้าน

โปรดทราบว่าการเปรียบเทียบความยาวด้าน A ^ 2 + B ^ 2 + C ^ 2 กับ 2 * B ^ 2 จะเหมือนกับการเปรียบเทียบ A ^ 2 + C ^ 2 กับ B ^ 2 (เพียงลบ B ^ 2 จากทั้งสองด้าน) ถ้า B ^ 2 = A ^ 2 + C ^ 2 มันเป็นรูปสามเหลี่ยมมุมฉาก ถ้า B ^ 2 มากกว่านั้นมันจะป้านถ้าเล็กกว่านั้นมันจะรุนแรง


จากแผนภาพในคำถามสามเหลี่ยมด้านเท่ากันหมดควรจัดเป็นสามเหลี่ยมหน้าจั่ว (ในทางกลับกันมันเป็นไปไม่ได้ที่จะสร้างรูปสามเหลี่ยมด้านเท่ากับพิกัดจำนวนเต็ม)
es1024

@ es1024 สามเหลี่ยม (0,0) (4,7) (8,0) เข้าใกล้มาก (ความยาวด้าน 64,65,65) มันเป็นการประมาณที่มีประโยชน์ถ้าคุณต้องการวาดมุม 60 องศา (วาดเกล็ดหิมะต่อหนึ่งในคำตอบอื่น ๆ ของฉันทำกระดาษไอโซเมตริกดอทหรือนาฬิการูปวาดของคุณเอง) มันคงเป็นไปไม่ได้เลยที่จะจับคู่กับลอยได้อย่างสมบูรณ์ หากและเมื่อฉันแก้ไขรหัสนี้ฉันอาจเพิ่มความอดทน 1% ในการเปรียบเทียบดังที่อธิบายไว้ในคำถาม
เลเวลริเวอร์เซนต์

2

Golfscript (175 ไบต์)

~..|,({.)2$([\;\]@(;]{{~}/@- 2?@@- 2?+}%$.{2-1??100*}/-+abs 1<{;"Line"}{.[]|,((["Isosceles ""Scalene "]=\~-+.!["Oblique ""Right "]=\.!\0>-)["Acute ""Obtuse "]=}if}{;"Point "}if

คุณสามารถทดสอบได้ที่นี่ (รวมชุดทดสอบ)

รูปแบบอินพุต:

"[x y][x y][x y]"

รุ่นที่แสดงความคิดเห็น:

~                       # evaluates input string          
..|,(                   # pushes the number of unique coords - 1
{
  .)2$([\;\]@(;]        # makes all 3 possible pairings of coords
  {{~}/@- 2?@@- 2?+}%$  # gets all squares of side lengths 
  .{2-1??100*}/-+abs 1< # 0 if triangle, 1 if line
  {;"Line"}
  {
     .[]|,((["Isosceles ""Scalene "]=\   # removes duplicate side-squares,
                                         #   and use the count to determine
                                         #   if isosceles or scalene (no
                                         #   equilaterals will exist)
     ~-+.!["Oblique ""Right "]=\         # compute a^2 + b^2 - c^2. Use to
                                         #   determine if oblique or right.
                                         #   c = max side length 
     .!\0>-)["Acute ""Obtuse "]=         # use same value to determine if
                                         #   acute, obtuse, or right
  }
  if
}
{;"Point "}
if

บันทึก:

สาเหตุที่รหัสของฉันไม่มีผลลัพธ์ "ด้านเท่ากันหมด" เป็นเพราะ:

  • OP กล่าวว่า "หมายเลขอินพุตทั้งหมดมีรูปแบบที่ถูกต้องเกี่ยวกับประเภทข้อมูลที่คุณใช้งานอยู่"
  • Golfscript ไม่มีหมายเลขพอยท์ - โดยเนื้อแท้แล้ว
  • มันเป็นไปไม่ได้ (ในตาราง 2 มิติ) ที่จะมีรูปสามเหลี่ยมด้านเท่ากับจำนวนเต็มพิกัดเป็นที่พิสูจน์แล้วที่นี่

บันทึกย่อของคุณถูกต้อง - นั่นคือเหตุผลที่ฉันรวมกฎเกี่ยวกับ "ความเท่าเทียมกัน" ความหมายค่าภายใน 1%
บาดเจ็บดิจิตอล

ถ้าฉันไม่เข้าใจผิดคุณพูดแบบนี้สำหรับการลอยไม่ใช่สำหรับจำนวนเต็ม: ".. คุณน่าจะเปรียบเทียบค่า floating-point ได้ค่าสองค่านี้จะถูกพิจารณาว่า 'เท่ากัน' ถ้าอยู่ภายใน 1% ของอีกอัน ."
Kyle McCormick

0

Mathematica ( 313 307 ตัวอักษร)

แข็งแรงเล่นกอล์ฟ:

f@p_:=(P=Print;R=RotateLeft;L=Length;U=Union;If[L@U@p==1,P@"Point",If[Det[Join[#,{1}]&/@p]==0,P@"Line",v=p-R@p;a=MapThread[VectorAngle[#,#2]&,{-v,R@v}];u=L@U[Norm/@v];If[u==1,P@"Equilateral",If[u==2,P@"Isosceles",P@"Scalene"]];If[MemberQ[a,Pi/2],P@"Right",P@"Oblique";If[Max@a>Pi/2,P@"Obtuse",P@"Acute"]]]])

Ungolfed:

f@p_ := (
  P = Print;    (* make aliases for functions used more than once *)
  R = RotateLeft;
  L = Length;
  U = Union;
  If[L@U@p == 1,    (* if all points identical *)
   P@"Point",
   If[Det[Join[#, {1}] & /@ p] == 0,    (* if area is zero *)
    P@"Line",
    v = p - R@p;    (* cyclic vectors *)
    a = MapThread[VectorAngle[#, #2] &, {-v, R@v}];    (* interior angles *)
    u = L@U[Norm /@ v];    (* number of unique side lengths *)
    If[u == 1,
     P@"Equilateral",
     If[u == 2,
      P@"Isosceles",
      P@"Scalene"
      ]
     ];
    If[MemberQ[a, Pi/2],
     P@"Right",
     P@"Oblique";
     If[Max@a > Pi/2,
      P@"Obtuse",
      P@"Acute"
      ]
     ]
    ]
   ]
  )

รูปแบบการป้อนข้อมูลเป็นรายการของจุดซึ่งฟังก์ชั่นที่เรียกว่า:

points = {{x1,y1},{x2,y2},{x3,y3}};
f@points

ฉันเป็นนักคณิตศาสตร์มือใหม่ ฉันจะดาวน์โหลดล่าม / ผู้แปลหรือลองออนไลน์ได้ที่นี่ (แน่นอน ;-) ฟรี)
Digital Trauma

ฉันไม่เคยใช้มันมาก่อน แต่ Wolfram มีแอปพลิเคชั่นเบราว์เซอร์ 'CDF Player' ซึ่งอ้างว่าใช้ไฟล์ Mathematica ที่จัดเก็บในรูปแบบ CDF แต่ไม่ใช่โน้ตบุ๊กทั่วไป พบที่นี่: wolfram.com/cdf-player นอกเหนือจากนั้นมีโปรแกรมหลักซึ่งฉันเชื่อว่าฟรี 30 วัน
ฟอสจีน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.