세 포인터! 그러나 어떤 종류?


24

에서 http://en.wikipedia.org/wiki/Triangle : 여기에 이미지 설명을 입력하십시오


세 개의 2 차원 좌표 튜플 (Cartesian)을 취하고이 세 점이 어떤 모양을 나타내는 지 분류하는 프로그램을 작성하십시오.

거의 모든 경우에이 점은 다양한 유형의 삼각형을 나타냅니다. 일부 퇴보 된 경우 점은 단일 점 또는 직선을 나타냅니다. 프로그램은 다음 중 어떤 태그가 설명 된 모양에 적용되는지 결정합니다.

  • 포인트 (3 포인트 동시 대응)
  • 선 (3 점은 직선 상에 있음-2 점을 초과 할 수 없음)
  • 등변 (3면 동일, 3 각 동일)
  • 이등변 (2 변이 같고 2 각이 같음)
  • Scalene (0 변이 같고 0 각이 같음)
  • 오른쪽 (1 각 정확히 π / 2 (또는 90 °))
  • 비스듬한 각도 (0 각 정확히 π / 2 (또는 90 °))
  • 둔각 (1 개 각도> π / 2 (또는 90 °))
  • 예각 (3 각 <π / 2 (또는 90 °))

설명 된 모양의 경우 위의 태그 중 하나 이상이 적용됩니다. 예를 들어, 직각은 이등변 또는 스케일입니다.

입력

  • 이 프로그램은 STDIN, 명령 행, 환경 변수 또는 선택한 언어에 편리한 모든 방법에서 3 개의 입력 좌표를 읽을 수 있습니다.
  • 입력 좌표는 형식이 지정되어 있지만 선택한 언어에 편리합니다. 사용하는 데이터 유형과 관련하여 모든 입력 번호의 형식이 올바른 것으로 가정 할 수 있습니다.
  • 입력 좌표의 순서에 대해서는 아무것도 가정 할 수 없습니다.

산출

  • 프로그램은 STDOUT, 대화 상자 또는 선택한 언어에 편리한 표시 방법으로 출력됩니다.
  • 출력은 입력 좌표로 설명 된 모양에 적용 가능한 모든 태그를 표시합니다.
  • 태그는 어떤 순서로도 출력 될 수 있습니다.

다른 규칙

  • 귀하의 언어 삼각법 라이브러리 / API는 허용되지만 삼각형 유형을 구체적으로 계산하는 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 (및 삼항 연산자는 if / else로 대체 됨) :

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 1 1 2 0 이등변의 경우


./triangle <<< "1 2 1 2 1 2"따옴표와 함께 @digitaltrauma를 사용해야합니다.
es1024

예, 물론 미안합니다. 좋은 대답입니다. 나는 특히 수레를 피할 수 있었기 때문에 1 % 이내의 평등 규칙에 대해 걱정할 필요가 없습니다. +1
디지털 외상

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 si= 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]두 선의 기울기가 같고 삼각형이 선 또는 점인 경우 방정식 분할을 피하기 위해 프로그램에서 재 배열됩니다.

r제곱에 사용되는 중간 값입니다.

z길이가 0 인 변의 개수를 계산합니다. 루프는에서 3 개의 빈 셀을 읽으므로 +3의 오프셋을 갖습니다 t[].

c길이가 같은 변의 개수를 계산합니다. 또한 오프셋은 +3입니다. a = b, b = c, c = a를 확인할 수 있도록 side at[]두 번 기록됩니다 .

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

골프 스크립트 (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 % 내에서 "평등"에 대한 규칙을 의미하는 값을 포함하는 이유는
디지털 외상을

내가 실수하지 않으면 정수가 아닌 수레에 대해 이것을 말했다. ".. 부동 소수점 값을 비교하게 될 것입니다. 두 값 중 하나가 다른 값의 1 % 내에 있으면 '동일'한 것으로 간주됩니다 "
Kyle McCormick

0

매스 매 티카 ( 313307 자)

골프 :

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

언 골프 드 :

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

나는 수학 신인입니다. 인터프리터 / 컴파일러를 어디에서 다운로드하거나 온라인에서 무료로 사용해 볼 수 있습니까 (물론 ;-))?
디지털 외상

나는 그것을 사용한 적이 없지만 Wolfram에는 CDF 형식으로 저장된 Mathematica 파일을 실행한다고 주장하지만 일반 노트북은 아닌 'CDF Player'브라우저 응용 프로그램이 있습니다. 여기에서 찾을 수 있습니다 : wolfram.com/cdf-player 그 외에도 30 일 동안 무료로 사용할 수있는 주요 프로그램이 있습니다.
phosgene
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.