삼각형 식별


11

그림에서 삼각형의 양을 세는 것은 뇌 검사에서 일반적으로 사용되는 작업입니다. 삼각형으로 구성된 도형이 포함 된 그림이 제공됩니다. 그런 다음 그림에서 가능한 모든 삼각형을 찾아야합니다.

직무

선택한 형식으로 줄 목록이 제공됩니다. 그런 다음 해당 삼각형의 목록을 출력해야합니다.

입력

각 네 개의 정수 좌표 (예 :)로 줄 목록이 제공됩니다 x1 y1 x2 y2. 명확하게 문서화되어있는 한 입력 형식을 선택할 수 있습니다. 예 :

0 4 8 1
0 4 9 5
8 1 9 5
2 8 0 4
9 5 2 8

[[0, 4, 8, 1], [0, 4, 9, 5], [8, 1, 9, 5], [2, 8, 0, 4], [9, 5, 2, 8]]

다음은 이미지와 동일한 입력입니다.

삼각형 그리기

교차로가있는 다른 하나 (공간을 절약하기 위해 한 형식으로 만) :

[[2, 1, 5, 0], [2, 1, 2, 7], [5, 0, 6, 6], [5, 0, 2, 7], [6, 6, 2, 1], [2, 7, 6, 6]]

삼각형 그리기

산출

x1 y1 x2 y2 x3 y3입력으로 지정된 그림에 각각 6 개의 부동 소수점 좌표 (예 :)로 지정된 모든 삼각형의 목록을 출력해야합니다 . 선은 어느 시점에서나 교차 할 수 있으므로 정수가 아닐 수 있습니다. 명확하게 문서화되어있는 한 출력 형식을 선택할 수 있습니다. 위의 예제 입력에 대한 예제 출력 :

0 4 8 1 9 5
0 4 9 5 2 8

[[0, 4, 8, 3, 9, 5], [0, 4, 9, 5, 2, 8]]
[[2, 1, 5, 0, 2, 7], [2, 1, 5, 0, 6, 6], [5, 0, 6, 6, 2, 7], [2, 1, 6, 6, 2, 7], [2, 1, 5, 0, 3.674, 3.093], [5, 0, 6, 6, 3.674, 3.093], [6, 6, 2, 7, 3.674, 3.093], [2, 7, 2, 1, 3.674, 3.093]]

당신은 가정 할 수 있습니다

  • 선이 교차점을 통과하지만 선이 아닌 모서리가있는 경우는 없습니다.

    [[0, 9, 1, 8], [1, 8, 2, 9], [2, 9, 3, 8], [3, 8, 4, 9], [4, 9, 0, 9]]
    
  • 179도 이상의 각도는 없습니다.

    [[0, 0, 0, 1], [0, 1, 0, 2], [0, 2, 0, 0]]
    

규칙

  • 원하는 언어를 사용할 수 있습니다.
  • 외부 리소스를 사용하지 않아야합니다.
  • 표준 허점이 적용됩니다.

채점

이것은 이므로 바이트 단위 의 최단 답변이 이깁니다.


3주기를 식별하는 것이 충분합니까, 아니면 더 복잡한 사례를 처리해야합니까? 예를 들어로 정의 된 "펜타곤" [0,9],[1,8],[2,9],[3,8],[4,9]은 실제로 선이 위에있는 W입니다. 삼각형이나 삼각형이 없습니까?
레벨 리버 세인트

@steveverrill 에지 케이스를 무시할 수 있다고 가정 해 봅시다.
PurkkaKoodari

확인. 그리고 [0,0],[1,0],[2,0],[1,2]한 각도 180도 "사변형". 삼각형이나 삼각형이 없습니까?
Level River St

그것은 삼각형이 아니지만 그것이 오지 않는다고 가정 할 수도 있습니다.
PurkkaKoodari

답변:


1

PostGIS, 162

나는 이것이 PostgreSQL의 확장 인 PostGIS에 대한 쿼리라는 규칙을 준수한다고 생각합니다. 입력은 L이라는 각 선의 좌표 테이블 인 것으로 가정합니다. 출력은 형성된 삼각형에 대한 다각형 정의가있는 행 집합입니다.

SELECT ST_AsText(D)FROM(SELECT(ST_Dump(ST_Polygonize(B))).geom D FROM(SELECT ST_Union(ST_MakeLine(ST_Point(A,B),ST_Point(C,D)))B FROM L)A)B WHERE ST_NPoints(D)=4;

사용 중에는 다음과 같습니다

-- Create a table for the input
CREATE TABLE L (A INT, B INT, C INT,D INT);
INSERT INTO L VALUES(2, 1, 5, 0), (2, 1, 2, 7), (5, 0, 6, 6), (5, 0, 2, 7), (6, 6, 2, 1), (2, 7, 6, 6);

SELECT ST_AsText(D)FROM(SELECT(ST_Dump(ST_Polygonize(B))).geom D FROM(SELECT ST_Union(ST_MakeLine(ST_Point(A,B),ST_Point(C,D)))B FROM L)A)B WHERE ST_NPoints(D)=4;

-- Cleanup
DROP TABLE L;

출력은 다음과 같습니다

POLYGON((5 0,2 1,3.67441860465116 3.09302325581395,5 0))
POLYGON((6 6,5 0,3.67441860465116 3.09302325581395,6 6))
POLYGON((3.67441860465116 3.09302325581395,2 7,6 6,3.67441860465116 3.09302325581395))
POLYGON((2 7,3.67441860465116 3.09302325581395,2 1,2 7))

7

매쓰 915 395 401 405

최신 정보

이 프로그래밍 과제는 처음보다 훨씬 어렵습니다.

본 접근법은 임의의 선분의 길이를 따라 단일 교차점이있는 단순한 경우에 적용된다. 하나의 세그먼트를 따라 여러 개의 교차점이있는 경우 각 선을 따라 모든 교차점을 추적하고 새 교차점을 대상 선을 따라 모든 교차점에 연결하는 새로운 하위 세그먼트 (따라서 추가 그래프 모서리)를 작성해야합니다.

이러한 제한에도 불구하고 현재 접근 방식의 기본 논리를 공유 할 가치가 있습니다.


입력 라인 세그먼트는 영역으로 취급됩니다. 이들이 교차하면 중심이 교차점의 좌표가됩니다. 선분의 정점에서 발생하는 교차점을 제거해야합니다. 교차하지 않는 선은 불확실한 중심을 갖습니다.

각 교차점에 대해 4 개의 새로운 모서리가 작성됩니다. 교차점을 두 교차 선의 네 정점에 연결합니다.

오른쪽과 같은 그래프는 이전 가장자리와 새 가장자리를 모두 사용하여 생성됩니다.

꼭짓점은 각 점의 좌표입니다. 3 개의 꼭짓점이 동일 선상에 있지 않으면 3 개의 꼭짓점의 닫힌 루프는 삼각형이됩니다.

현재 우리는 "삼각형"에 불확정 영역이 있는지 확인합니다. (어떤 이유로 3 개의 공선 점에 대해 0의 영역을 반환하지 않습니다.)


간단한 예

아래는 (a) 좌표 평면에 그려진 그림과 (b) 교차점뿐만 아니라 주어진 노드를 보여주는 그래프 {114/23, 314/69}입니다. 후자의 정점은 각각의 직교 좌표에 위치하지 않습니다.

오른쪽 그림에서 왼쪽보다 가장자리가 더 많을 수 있습니다. 그러나 왼쪽에 겹치는 그래프 가장자리가 있다는 것을 기억하십시오. 각 대각선은 실제로 3 개의 그래프 모서리에 해당합니다!


그래프

    f@w_ :=(h@{a_, b_, c_, d_} := (r = RegionCentroid@RegionIntersection[Line@{a, b}, Line@{c, d}];
     {r <-> a, r <-> b, r <-> c, r <-> d});
      Cases[FindCycle[Graph[Union@Join[w /. {{a_, b_Integer}, {c_, d_}} :> {a, b} <-> {c, d},
      Cases[Flatten[h /@ Cases[{Length[Union@#] < 4, #} & /@ (FlattenAt[#, {{1}, {2}}] & /@ 
      Subsets[w, {2}]),{False, c_} :> c]], Except[{Indeterminate, _} <-> _]]]], {3}, 50],
      x_ /; NumericQ[RegionMeasure@Triangle[x[[All, 1]]]]][[All, All, 1]]//N//Grid)

아래의 각 행은 삼각형입니다.

f[{{{2,8},{8,1}},{{0,4},{8,1}},{{0,4},{9,5}},{{8,1},{9,5}},{{2,8},{0,4}},{{9,5},{2,8}}}]

조정


더 복잡한 예

f@{{{9, 5}, {0, -10}}, {{9, 5}, {0, 2}},  {{9, 5}, {2, -1}}, {{0, -10}, {2, -1}}, {{0, -10}, {-2, -1}}, {{-9, 5}, {0, -10}}, {{-9, 5}, {0, 2}}, {{-9, 5}, {-2, -1}}, {{0, 2}, {0, -10}}, {{-9, 5}, {2, -1}}, {{9, 5}, {-2, -1}}, {{-9, 5}, {9, 5}}}

입력 좌표에 해당하는 그래프는 다음과 같습니다 . 꼭짓점은 예상되는 데카르트 좌표에 있습니다. (골프 코드를 실행하면 정점 레이블과 가장자리를 고려하면서 다른 곳에 정점이 표시됩니다. 가독성을 위해 솔루션에 필요하지 않은 추가 코드를 사용하여 정점 좌표를 할당했습니다.)

graph2


다음은 파생 그래프입니다.
여기에는 (0,1/11)일부 입력 선 이 교차하는 파생 교차점이 포함됩니다 .

십구

코드는 19 개의 삼각형을 찾았습니다. 그 중 9 개 (0,1/11)는 꼭짓점 중 하나로 지적 합니다.

nineteen2


확인. 이제 함수 형태입니다.
DavidC

4

자바, 1051 1004

(완전히 작동하는 프로그램)

나는 이것이 일부 코드를 골프화하는 것이 아니라 주로 수학 함수 작성을 연습하는 것이 좋은 도전이라고 생각했습니다.

그리고 "기준선"을 그리기 위해 Java로 이것을 작성했습니다 . * 모든 사람들이 웃기 시작합니다 * .

암호

import java.util.*;class P{double x,y;static P l(double... i){double a=i[0],b=i[1],c=i[2],d=i[3],e=i[4],f=i[5],k,l,x=(k=i[7]-f)*(c-a)-(l=i[6]-e)*(d-b),n=(l*(b-f)-k*(a-e))/x,m=((c-a)*(b-f)-(d-b)*(a-e))/x;P p=new P();p.x=a+n*(c-a);p.y=b+n*(d-b);return(n>=0&n<=1&m>=0&m<=1&x!=0)?p:null;}public static void main(String[]p){Set<String>v=new HashSet();P q,w,e;Integer a,b,c,d,k,f,g,h,i,j,m,l,r,t,y,z;int[][]x=new int[l=p.length/4][4];for(c=0;c<l;c++){for(d=0;d<4;){x[c][d]=l.parseInt(p[c*4+d++]);}}z=x.length;for(r=0;r<z;r++){a=x[r][0];b=x[r][1];c=x[r][2];d=x[r][3];for(t=0;t<z;t++){if(t!=r){k=x[t][0];f=x[t][1];g=x[t][2];h=x[t][3];q=l(a,b,c,d,k,f,g,h);if(q!=null){for(y=0;y<z;y++){if(y!=r&y!=t){i=x[y][0];j=x[y][1];m=x[y][2];l=x[y][3];w=l(a,b,c,d,i,j,m,l);e=l(k,f,g,h,i,j,m,l);if(w!=null&&e!=null&&q.x!=e.x&q.y!=e.y&!v.contains(""+r+y+t)){v.add(""+r+t+y);v.add(""+r+y+t);v.add(""+t+r+y);v.add(""+t+y+r);v.add(""+y+r+t);v.add(""+y+t+r);System.out.printf("%s %s %s %s %s %s\n",q.x,q.y,w.x,w.y,e.x,e.y);}}}}}}}}}

입력

공백으로 구분 된 정수 4 쌍 (x1, y1, x2, y2)

2 1 5 0 2 1 2 7 5 0 6 6 5 0 2 7 6 6 2 1 2 7 6 6

출력 (실제 출력은 소수점 3 자리로 반올림되지 않습니다)

각 선은 하나의 삼각형을 포함합니다. 각 선은 공간적으로 분리 된 부동 소수점으로 2 쌍 (x1, y1, x2, y2, x3, y3)으로 구성됩니다. (참고 : 삼각형을 형성하는 3 점의 순서는 정의되어 있지 않습니다.)

5.0 0.0 2.0 1.0 6.0 6.0
5.0 0.0 2.0 1.0 2.0 7.0
5.0 0.0 2.0 1.0 3.674 3.093
2.0 7.0 2.0 1.0 3.674 3.093
2.0 1.0 2.0 7.0 6.0 6.0
5.0 0.0 6.0 6.0 3.674 3.093
5.0 0.0 6.0 6.0 2.0 7.0
3.674 3.093 2.0 7.0 6.0 6.0

설명

무한대의 두 선 사이의 교차점을 찾는 방법을 쓰기 시작했습니다. 결과적인 메소드는 Java 스타일을위한 것입니다 (246). 메소드 입력을 8 개의 double 또는 2 개의 Points (P)로 구성하는 대신 임의의 매개 변수를 사용하여 대량의 문자를 안전하게 보호합니다. 배열 연산자 사용을 최소화하기 위해 2 번 이상 사용 된 각 매개 변수는 자체 변수에 배치됩니다.

static P l(double... i){double a=i[0],b=i[1],c=i[2],d=i[3],e=i[4],f=i[5],k,l,x=(k=i[7]-f)*(c-a)-(l=i[6]-e)*(d-b),n=(l*(b-f)-k*(a-e))/x,m=((c-a)*(b-f)-(d-b)*(a-e))/x;P p=new P();p.x=a+n*(c-a);p.y=b+n*(d-b);return(n>=0&n<=1&m>=0&m<=1&x!=0)?p:null;}

더 많은 설명이 추가 될 것입니다 ... (이 답변은 아마도 더 많은 골프를 칠 수 있습니다)


0

BBC 기본

http://www.bbcbasic.co.uk/bbcwin/bbcwin.html의 에뮬레이터

나는 이것이 400 년대로 골프화 될 것으로 예상하고있다.

입출력

사용자가 새 줄을 입력 할 때마다 프로그램은 새 삼각형이 만들어 졌는지 확인하고 즉시 출력합니다 (아래 참조).

새로운 선이 서로 교차하는 두 개의 기존 선과 교차 할 때마다 새 삼각형이 만들어집니다 (세 개의 선이 한 지점에서 교차하는 경우는 예외).

여기에 이미지 설명을 입력하십시오

암호

주요 프로그램은 가능한 한 간단합니다. 마지막에는 http://en.wikipedia.org/wiki/Line%E2%80%93line_intersection 의 공식에 따라 교차점을 감지하는 복잡한 작업을 수행하는 함수가 있습니다 .

이 함수는 교점이없는 경우 0을, 부동 소수점 수가 0이 아닌 경우 0을 반환합니다. 교차점의 좌표가 문자열 z $에 추가됩니다. 또한 BBC 기본에서 주 프로그램에 동일한 이름의 변수가없는 경우 (함수가 완료된 후에도) 함수의 변수가 주 프로그램에 표시됩니다.

따라서 메인 프로그램은 변수에 대한 액세스를 보유 x하고 y, 그리고 mn현재 및 이전의 교점의 좌표를 저장. 이것은 우리가 실제로 한 지점에서 교차하는 세 개의 선이 아닌 삼각형을 발견했는지 감지하는 데 사용됩니다.

  DIM a(99),b(99),c(99),d(99)                                                    :REM declare 4 arrays to hold the ata
  y=0                                                                            :REM x and y are only initialized
  x=0                                                                            :REM to avoid a no such varialbe error later
  FOR i=0 TO 99                                                                  :REM for each input line
    INPUT a(i),b(i),c(i),d(i)
    FOR j=0 TO i-1                                                               :REM iterate through all combinations of 2 previous lines
      FOR k=0 TO j-1
        z$=""                                                                    :REM clear z$, three function calls on next line will write the triangle (if found) to it
        IF i>j AND j>k AND FNf(i,j)*FNf(i,k)*FNf(j,k)<>0 IF x<>m OR y<>n PRINT z$:REM to avoid printing the same triangle twice, print only if j,k,i in lexicographic order. Also reject if x,y (3rd FNf call) and m,n (2nd FNf call) are the same: this means a point, not a triangle.
      NEXT
    NEXT
  NEXT

  DEF FNf(g,h)                                                                   :REM returns zero if no intersection found, otherwise a floating point value
  m=x                                                                            :REM backup previous x and y
  n=y                                                                            :REM to use in test for point versus triangle
  p=a(g)-c(g)
  q=b(g)-d(g)
  r=a(h)-c(h)
  s=b(h)-d(h)
  t=a(g)*d(g)-b(g)*c(g)
  u=a(h)*d(h)-b(h)*c(h)
  e=p*s-q*r                                                                      :REM following method in wikipedia, calculate denominator of expression
  IF e<>0 x=(t*r-u*p)/e : y=(t*s-u*q)/e: z$=z$+" "+STR$(x)+" "+STR$(y)           :REM if denominator not zero, calculate x and y and append a string copy to z$
  IF (a(g)-x)*(c(g)-x)>0 OR (b(g)-y)*(d(g)-x)>0 OR(a(h)-x)*(c(h)-x)>0 OR(b(h)-y)*(d(h)-y)>0 e=0
  =e          :REM return e                                                      :REM previous line sets e to zero if the intersection falls outside the line segment. This is detected when both are on the same side of the intersection, which yields a positive multiplication result.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.