Ba con trỏ! Nhưng loại nào?


24

Từ http://en.wikipedia.org/wiki/Trigin : nhập mô tả hình ảnh ở đây


Viết chương trình có ba bộ dữ liệu tọa độ 2d (Cartesian) và phân loại hình dạng mà ba điểm này mô tả.

Trong hầu hết các trường hợp, các điểm này sẽ mô tả một tam giác gồm nhiều loại khác nhau. Trong một số trường hợp suy biến, các điểm sẽ mô tả một điểm đơn hoặc một đường thẳng. Chương trình sẽ xác định thẻ nào sau đây áp dụng cho hình dạng được mô tả:

  • Điểm (3 điểm là đồng sự cố)
  • Đường thẳng (3 điểm nằm trên một đường thẳng - không quá 2 điểm có thể là sự cố)
  • Bình đẳng (3 cạnh bằng nhau, 3 góc bằng nhau)
  • Isosceles (2 cạnh bằng nhau, 2 góc bằng nhau)
  • Scalene (0 cạnh bằng nhau, 0 góc bằng nhau)
  • Phải (1 góc chính xác là π / 2 (hoặc 90 °))
  • Xiên (0 góc chính xác là π / 2 (hoặc 90 °))
  • Obtuse (1 góc> π / 2 (hoặc 90 °))
  • Cấp tính (3 góc <π / 2 (hoặc 90 °))

Lưu ý rằng đối với một số hình dạng được mô tả, nhiều hơn một trong các thẻ trên sẽ được áp dụng. Ví dụ, bất kỳ góc phải nào cũng sẽ là isosceles hoặc scalene.

Đầu vào

  • Chương trình có thể đọc 3 tọa độ đầu vào từ STDIN, dòng lệnh, biến môi trường hoặc bất kỳ phương thức nào thuận tiện cho ngôn ngữ bạn chọn.
  • Tuy nhiên, đầu vào phối hợp với tôi được định dạng thuận tiện cho ngôn ngữ bạn chọn. Có thể giả định rằng tất cả các số đầu vào được định dạng tốt đối với các kiểu dữ liệu mà bạn kết thúc sử dụng.
  • Không có gì có thể được giả định về thứ tự của tọa độ đầu vào.

Đầu ra

  • Chương trình sẽ xuất ra STDOUT, hộp thoại hoặc bất kỳ phương thức hiển thị nào thuận tiện cho ngôn ngữ bạn chọn.
  • Đầu ra sẽ hiển thị tất cả các thẻ áp dụng cho hình dạng được mô tả bởi tọa độ đầu vào.
  • Thẻ có thể là đầu ra theo thứ tự bất kỳ.

Các quy tắc khác

  • Thư viện / API lượng giác của ngôn ngữ của bạn được cho phép, nhưng bất kỳ API nào tính toán cụ thể các loại hình tam giác đều bị cấm.
  • Khi xác định sự bằng nhau của các góc hoặc độ dài của các cạnh, bạn có thể sẽ kết thúc việc so sánh các giá trị của dấu phẩy động. Hai giá trị như vậy được coi là "bằng nhau" nếu một giá trị nằm trong khoảng 1% của giá trị kia.
  • Lỗ hổng tiêu chuẩn của người Viking không còn buồn cười
  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng.

Ví dụ

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
Tôi đã định sử dụng " Thẻ tam giác " này nhưng nó đã giảm tối thiểu 15 ký tự.
Chấn thương kỹ thuật số

Nếu hai điểm giống hệt nhau thì sao?
Ypnypn

@Ypnypn Trong trường hợp đó là một dòng.
Chấn thương kỹ thuật số

Thẻ tam giác
Derek 朕 會

2
Có một vấn đề với định nghĩa "Cấp tính"? Không thể nào tất cả các góc đều lớn hơn PI / 2?
Arnaud

Câu trả lời:


10

C (451 byte)

Chỉ sử dụng chiều dài bình phương và độ dốc.

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 (và toán tử ternary được thay thế bằng if / other):

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
}

Định dạng đầu vào (thông qua stdin): xyxyxy

ví dụ 0 0 1 1 2 0 cho Isosceles Phải


@digitaltrauma ./triangle <<< "1 2 1 2 1 2"nên được sử dụng, với dấu ngoặc kép.
es1024

Vâng, tất nhiên, xin lỗi về điều đó. Câu trả lời tốt đẹp. Tôi đặc biệt thích rằng bạn có thể tránh nổi, và do đó không phải lo lắng về điều luật bình đẳng trong vòng 1%. +1
Chấn thương kỹ thuật số

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");
}

Tôi rời khỏi khoảng trắng trong lúc này. Điều này hoạt động nhưng có lẽ có thể làm với một số dọn dẹp và chơi golf. Toán học tương tự như @es1024câu trả lời, nhưng sử dụng một vòng lặp và mảng. định dạng đầu vàox y x y x y

Biến

t[]lưu trữ cả đầu vào và bình phương của độ dài. Vào cuối chương trình, nó trông giống như bảng bên dưới (tăng số lần lặp của vòng lặp sẽ dẫn đến sự lặp lại vô hạn của độ dài bình phương.) Khi bắt đầu các ô vuông có độ dài (rác vì không phải tất cả dữ liệu đều có sẵn ) đều không cần thiết được lưu trữ trong các tế bào 1,3 và 5, nhưng được ghi đè phản ánh kịp thời scanf.dữ liệu hữu ích được ghi vào z,b,cahd skhi i= 9,11,13 ( t[i]t[i-2]được truy cập.)

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

g[]đã được thêm vào muộn để giữ các giá trị dx và dy cần thiết cho tính toán độ dốc. Các ô duy nhất được sử dụng là 6 đến 9 (0 đến 5 là không đáng tin cậy vì không phải tất cả dữ liệu đều có sẵn khi chúng được viết.) Nếu g[6]/g[7]==g[8]/g[9]độ dốc của 2 dòng bằng nhau và tam giác chỉ là một đường (hoặc một điểm.) Phương trình được sắp xếp lại trong chương trình để tránh phân chia.

rlà một giá trị trung gian được sử dụng cho bình phương

zđếm số cạnh của chiều dài bằng không. Nó có độ lệch +3 vì vòng lặp đọc 3 ô trống trong t[].

cđếm số cạnh có độ dài giống hệt nhau. Nó cũng có độ lệch +3. Lưu ý rằng bên ađược viết thành t[]hai lần để có thể kiểm tra a = b, b = c, c = a.

blà chiều dài lớn nhất của một bên, bình phương. slà tổng bình phương của tất cả các cạnh.

Lưu ý rằng so sánh độ dài cạnh A ^ 2 + B ^ 2 + C ^ 2 với 2 * B ^ 2 giống như so sánh A ^ 2 + C ^ 2 với B ^ 2 (chỉ trừ B ^ 2 từ cả hai bên.) nếu B ^ 2 = A ^ 2 + C ^ 2 thì đó là tam giác vuông. nếu B ^ 2 càng lớn thì càng khó, nếu nhỏ hơn thì cấp tính.


Dựa trên sơ đồ trong câu hỏi, một tam giác đều cũng nên được phân loại thành một tam giác cân. (Mặt khác, không thể tạo ra một tam giác đều có tọa độ nguyên.)
es1024

@ es1024 tam giác (0,0) (4,7) (8,0) rất gần (bình phương cạnh dài 64,65,65). Đó là một phép tính gần đúng nếu bạn muốn vẽ các góc 60 độ (vẽ những bông tuyết theo một trong những câu trả lời khác của tôi, làm giấy chấm isometric của riêng bạn hoặc vẽ đồng hồ.) Có lẽ bạn cũng không thể có được một kết hợp hoàn hảo với phao. Nếu và khi tôi sửa lại mã này, tôi có thể thêm dung sai 1% vào so sánh, như được mô tả trong câu hỏi.
Cấp sông St

2

Golfscript (175 byte)

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

Bạn có thể kiểm tra nó ở đây (bao gồm bộ kiểm tra).

Định dạng đầu vào:

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

Phiên bản đã bình luận:

~                       # 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

CHÚ THÍCH:

Lý do mã của tôi không chứa đầu ra "bằng nhau" là vì:

  • OP cho biết "tất cả các số đầu vào được định dạng tốt đối với các kiểu dữ liệu mà bạn kết thúc bằng cách sử dụng"
  • Golfscript không có số dấu phẩy động - dù sao không phải là bản chất
  • Không thể (trong lưới 2 chiều) không thể có tam giác đều có tọa độ nguyên, như đã được chứng minh ở đây .

Ghi chú của bạn là chính xác - đó là lý do tại sao tôi bao gồm quy tắc về các giá trị "bình đẳng" có nghĩa là trong vòng 1%
Chấn thương kỹ thuật số

Nếu tôi không nhầm, bạn đã nói điều này với số float, không phải cho số nguyên: ".. bạn có thể sẽ kết thúc việc so sánh các giá trị dấu phẩy động. Hai giá trị như vậy sẽ được coi là" bằng nhau "nếu một trong số 1% khác . "
Kyle McCormick

0

Toán học ( 313 307 ký tự)

Chơi gôn

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"]]]])

Ung dung:

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"
      ]
     ]
    ]
   ]
  )

Định dạng đầu vào là danh sách các điểm, theo đó hàm được gọi là:

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

Tôi là một tân binh toán học. Tôi có thể tải xuống trình thông dịch / trình biên dịch ở đâu hoặc dùng thử trực tuyến (tất nhiên là miễn phí ;-))?
Chấn thương kỹ thuật số

Tôi chưa bao giờ sử dụng nó, nhưng Wolfram có ứng dụng trình duyệt Player CDF Player, ứng dụng này yêu cầu chạy các tệp Mathicala được lưu trữ ở định dạng CDF, nhưng không phải là sổ ghi chép thông thường. Tìm thấy ở đây: wolfram.com/cdf-player Ngoài ra, có chương trình chính mà tôi tin là miễn phí trong 30 ngày.
phosgene
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.