다각형의 구멍 수


11

문제 : 연결된 다각형의 구멍 수를 셉니다. 입력 삼각 분할의 모든 삼각형이 다른 삼각형과 하나 이상의면을 공유하고 연결된 삼각형 세트가 하나만 있어야한다는 조건으로 다각형의 연결이 보장됩니다.

입력은 평면 Ln점 목록 과의 항목 T이 포함 된 3 개의 튜플 목록 입니다 0...n-1. T튜플의 각 항목 에 대해 삼각 측량에서 삼각형 (t_1,t_2,t_3)의 3 개의 꼭짓점 (목록에서 L)을 나타냅니다 . 이것은 '다각형 삼각 분할' 이라는 의미에서 삼각 분할이라는 점에 유의하십시오. 이것 때문에 T겹치는 두 개의 삼각형은 절대 없을 것 입니다. 추가 규정은 입력을 소독 할 필요가 없습니다, 것입니다 LT모든 반복이 포함되어 있지 않습니다.

실시 예 1 다음의 경우 L = {{0,0},{1,0},{0,1},{1,2}}와는 T = {{0,1,2},{1,2,3}}다음에 지정된 다각형 0 정공 수있다.

그림 1

실시 예 2 : 경우 L = {{0,0},{1,0},{2,0},{2,1},{2,2},{1,2},{0,2},{0,1},{.5,.5},{1.5,.5},{1.5,1.5},{.5,1.5}}T = {{5,6,11},{5,10,11},{4,5,10},{3,8,10},{2,3,9},{2,8,9},{1,2,8},{0,1,8},{0,8,11},{0,7,11},{6,7,11},{3,4,10}}다각형 입력 2 출력 후 발생한다.

그림 2

태스크 걸리는 짧은 프로그램 (또는 함수) 작성하는 것 LT입력으로서 구멍의 수를 반환한다. '우승자'는 문자 수가 가장 적은 항목 (가칭 종료 날짜 6 월 1 일)으로 인식됩니다.

샘플 입력 형식 (인덱싱 0 참고) :

0,0
1,0
0,1
1,2
0,1,2
1,2,3    

1
"입력 삼각 분할의 모든 삼각형이 다른 삼각형과 적어도 한면을 공유하는 조건에 의해 다각형의 연결성이 보장됩니다." -- 아니. 그것은 충분한 조건이 아닙니다. 예를 들어 보자 T=1,2,3/1,2,4/5,6,7/5,6,8. 모든 삼각형은 다른 삼각형과 모서리를 공유하지만 삼각 분할이 끊어집니다
John Dvorak

입력이 유효한 부분 삼각 분할 (두 개의 삼각형이 겹치지 않고 삼각형이 두 번 존재하지 않음)을 나타내고 삼각 분할이 연결되었다고 가정 할 수 있습니까?
John Dvorak


입력이 가장자리 연결되어 있다는 가정하에 유한 한 점 세트를 제거하여 모양을 분리 할 수 ​​없습니까? (예는 : T=1,2,3/1,4,5연결되어 있지만 에지 연결)
존 드보르작에게

2
종료 날짜에 대한이 비즈니스가 최근에 시작된 이유를 잘 모르겠습니다. 허용 된 답변을 변경할 수 있으므로 종료 날짜를 설정할 필요가 없습니다. 사람들이 첫 번째 답변이 타의 추종을 불허한다고 생각하지 않도록 답변을 선택하기 전에 일주일 동안 기다릴 것이라 생각하는 것이 합리적이지만 사이트에서 활동하는 한 선택한 답변을 변경할 수 있습니다 누군가가 더 나은 게시물을 올린다면 관련 메타 토론에는 meta.codegolf.stackexchange.com/q/542/194meta.codegolf.stackexchange.com/q/193/194
Peter Taylor

답변:


5

GolfScript (23 자)

~.{2*2/~}%{$}%.&,@@+,-)

GolfScript 배열 표기법과 인용 (또는 정수) 좌표를 사용하여 입력 형식을 가정합니다. 예 :

$ golfscript codegolf11738.gs <<<END
[["0" "0"] ["1" "0"] ["2" "0"] ["2" "1"] ["2" "2"] ["1" "2"] ["0" "2"] ["0" "1"] [".5" ".5"] ["1.5" ".5"] ["1.5" "1.5"] [".5" "1.5"]] [[5 6 11] [5 10 11] [4 5 10] [3 8 10] [2 3 9] [2 8 9] [1 2 8] [0 1 8] [0 8 11] [0 7 11] [6 7 11] [3 4 10]]
END
2

( 온라인 동등 )

또는

$ golfscript codegolf11738.gs <<<END
[[0 0] [1 0] [0 1] [1 2]] [[0 1 2] [1 2 3]]
END
0

( 온라인 동등 )


5

파이썬, 71

다음은 원하는 숫자를 계산 하는 프로그램 ( 함수가 아님)입니다.

len(set().union(*(map(frozenset,zip(t,t[1:]+t))for t in T)))-len(L+T)+1

사용법 예 :

>>> L = ((0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,1),(.5,.5),(1.5,.5),(1.5,1.5),(.5,1.5))
>>> T = ((5,6,11),(5,10,11),(4,5,10),(3,8,10),(2,3,9),(2,8,9),(1,2,8),(0,1,8),(0,8,11),(0,7,11),(6,7,11),(3,4,10))
>>> len(set().union(*(map(frozenset,zip(t,t[1:]+t))for t in T)))-len(L+T)+1
2

+1 지퍼, 플랫를 사용하여 frozenset을 대신 정렬 (필요 자신을 익히, 내가 전에 그것을 사용했습니다 말할 수 없습니다.)
가야

3

APL, 36

{1+(⍴⊃∪/{{⍵[⍋⍵]}¨,/3 2⍴⍵,⍵}¨⍵)-⍴⍺,⍵}

이 함수는 L왼쪽 인수와 T오른쪽으로 사용됩니다.

예를 들면 다음과 같습니다.

      L←(0 0)(1 0)(0 1)(1 2)
      T←(0 1 2)(1 2 3)
      L{1+(⍴⊃∪/{{⍵[⍋⍵]}¨,/3 2⍴⍵,⍵}¨⍵)-⍴⍺,⍵}T
0
      L←(0 0)(1 0)(2 0)(2 1)(2 2)(1 2)(0 2)(0 1)(.5 .5)(1.5 .5)(1.5 1.5)(.5 1.5)
      T←(5 6 11)(5 10 11)(4 5 10)(3 8 10)(2 3 9)(2 8 9)(1 2 8)(0 1 8)(0 8 11)(0 7 11)(6 7 11)(3 4 10)
      L{1+(⍴⊃∪/{{⍵[⍋⍵]}¨,/3 2⍴⍵,⍵}¨⍵)-⍴⍺,⍵}T
2

오른쪽에서 왼쪽으로 설명 :

  • ⍴⍺,⍵두 입력 벡터를 연결하고 길이 ( V + F)를 반환합니다.
  • 다음 블록으로 들어가기 :
    • ¨⍵ 왼쪽의 함수를 오른쪽 인수의 모든 요소에 적용하고 결과를 반환합니다.
    • ⍵,⍵ 자신과 연결된 올바른 인수를 반환
    • 3 2⍴벡터 인수를 세 쌍으로 만듭니다. 이 경우 벡터의 첫 번째, 두 번째, 세 번째 및 첫 번째, 두 번째 및 세 번째 항목을 함께 쌍으로 묶습니다.
    • ,/ 벡터 인수를 함께 결합
    • ⍵[⍋⍵] 올바른 논쟁을 정렬
    • ∪/ 중복을 걸러 내다
    • ⍴⊃ 중첩 스칼라를 벡터로 변환하고 길이를 반환합니다.
    • 전체 함수는 모양의 가장자리 수를 반환합니다 ( E)
  • 1 설명이 필요합니다 (희망합니다 ...)

그런 다음 전체 함수는 1+E-(V+F)또는 을 반환합니다 1-(F+V-E).


내 GolfScript 솔루션의 기능과 거의 같습니다. GolfScript보다 훨씬 길다는 것에 놀랐습니다.
피터 테일러

@PeterTaylor GolfScript 솔루션이 너무 짧아서 놀랐습니다! (하지만 다시, 그것은 이다 GolfScript)
변동성은

2

Mathematica, 93 (아직 골프는 많지 않음)

f[l_, t_] :=  Max@MorphologicalComponents[Erosion[Graphics[
                                                        GraphicsComplex[l, Polygon[t + 1]]], 1]] - 1

(명확성을 위해 공백이 추가됨)

테스트 :

f[{{0, 0}, {1, 0}, {0, 1}, {1, 2}}, {{0, 1, 2}, {1, 2, 3}}]
(*
 -> 0
*)

{l, t} = {{{0, 0}, {1,   0}, {2,    0}, {2,     1}, {2,    2}, {1, 2}, {0, 2}, 
           {0, 1}, {.5, .5}, {1.5, .5}, {1.5, 1.5}, {.5, 1.5}}, 

           {{5, 6, 11}, {5, 10, 11}, {4, 5, 10}, {3, 8, 10}, {2, 3,  9}, 
            {2, 8,  9}, {1,  2,  8}, {0, 1,  8}, {0, 8, 11}, {0, 7, 11}, {6, 7, 11}, {3, 4, 10}}};
f[l, t]
 (*
  -> 2
 *)

이것은 최소한의 특정 크기를 가진 삼각형이나 구멍에 의존하지 Erosion않습니까?
John Dvorak

@JanDvorak 아마도 틀렸을 것입니다.하지만 무한 정밀도 산술을 사용하지 않으면 특정 최소 크기에 도달 할 때까지 모든 솔루션이 작동한다고 생각합니다 (세 점이 정렬되는지 여부를 결정해야 함). 이런 종류의 솔루션에서 문제가 명시 적으로 언급되어 있습니다.
Dr. belisarius

토폴로지 접근 방식을 사용하면 필요하지 않습니다. 동일 선상에 3 개의 점이있는 경우 0 면적 삼각형이 필요합니다. 그렇지 않으면 구멍이 있습니다.
John Dvorak

@belisarius. 다음은 결과 간의 불일치에 대한 Wolfram 기술 지원팀으로부터받은 답변입니다. "안녕하세요. 이메일을 보내 주셔서 감사합니다. Mac과 Windows에서 코드가 다른 결과를 제공함을 확인했습니다. 이것이 의도 된 동작이라고 생각하지 않습니다. 이 문제에 대해 개발자에게 보고서를 제출했습니다.이 문제에 대해 개발자로부터 얻은 유용한 정보를 전달할 것입니다. 추가 질문이 있으면 알려주십시오. ... 기술 지원 Wolfram Research Inc. "
DavidC

@DavidCarraher "예, 추가 질문이 있습니다 : 각 버그에 대한 수표를 보내겠습니까?"
닥터 벨리 사리우스

2

루비, 239 자 (227 본문)

def f t
e=t.flat_map{|x|x.permutation(2).to_a}.group_by{|x|x}.select{|_,x|x.one?}.keys
n=Hash[e]
(u,n=n,n.dup;e.map{|x|a,b=*x;n[a]=n[n[a]]=n[b]})until n==u
n.values.uniq.size+e.group_by(&:last).map{|_,x|x.size}.reduce(-1){|x,y|x+y/2-1}
end

토폴로지 만 고려하고 있습니다. 어떤 식 으로든 정점 위치를 사용하지 않습니다.

발신자 (Mathematica 또는 JSON 형식의 T가 필요함) :

input = gets.chomp
input.gsub! "{", "["
input.gsub! "}", "]"
f eval(input)

테스트:

f [[0,1,2],[1,2,3]]
#=> 0
f [[5, 6, 11], [5, 10, 11], [4, 5, 10], [3, 8, 10], [2, 3, 9], [2, 8, 9], [1, 2, 8], [0, 1, 8], [0, 8, 11], [0, 7, 11], [6, 7, 11], [3, 4, 10]]
#=> 2
f [[1,2,3],[3,4,5],[5,6,1],[2,3,4],[4,5,6],[6,1,2]]
#=> 1

예 일러, 오일러 특성 접근 방식. 그것이 파이썬에서 그렇게 한 방법입니다.
카야

2
@카야. (Egg of Columbus en.wikipedia.org/wiki/Egg_of_Columbus 참조 ) 누군가 누군가 귀하의 질문에 대해 Eulerian 답변을 제공하면 다른 사람들이 따라갈 가능성이 크게 증가합니다. 유 일러의 다면체 작업과 연결 한 후에 만 ​​자신의 접근 방식을 발견하는 것이 훨씬 더 도전적이고 만족 스럽습니다.
DavidC

2

매스 매 티카 76 73 72 67 62

많은 실험 끝에 정점의 정확한 위치가 중요하지 않다는 것을 깨달았습니다. 그래서 문제를 그래프로 표현했습니다. 필수 불변량, 삼각형 수, 모서리 및 정점은 변하지 않은 상태로 유지되었습니다 (제공된 선 교차를 피함).

그래프에는 두 가지 종류의 내부 "삼각형"이있었습니다. 얼굴, 즉 "채워진"삼각형과없는 얼굴이 있었을 것입니다. 내부면의 수는 모서리 또는 정점과 관련이 없습니다. 그것은 완전히 "채워진"그래프에서 구멍을 파는 것은 단지 얼굴의 수를 줄였다는 것을 의미했습니다. 나는 얼굴, 정점 및 가장자리를 추적하면서 삼각형 사이의 변형으로 체계적으로 연주했습니다. 결국 나는 구멍의 수가 항상 1-#faces-# vertices + #edges와 동일하다는 것을 깨달았습니다. 이것은 오일러 특성에서 1을 뺀 것으로 판명되었습니다 (단지 다면체의 맥락에서만 알고 있었지만 가장자리의 길이는 중요하지 않았습니다.

아래 함수는 꼭짓점과 삼각형이 입력 될 때 구멍 수를 반환합니다. 이전의 제출과 달리 이미지 스캔에 의존하지 않습니다. 이것을 1-Euler의 특성, 즉 1-(F + V -E)로 생각할 수 있습니다. 여기서 F= #faces, V= # vertices, E= # edges. 이 함수는 1 - (F + V -E)실제면 (삼각형)과 정점을 고려하여 구멍 수를 반환합니다 .

복합체 외부의 삼각형을 제거해도 다른 삼각형과 한쪽 또는 2 개의면을 공유하는지 여부에 관계없이 오일러 특성에 영향을 미치지 않음을 쉽게 알 수 있습니다.

참고 : 소문자 vL원래 공식 대신 사용됩니다 . 즉, 정점 자체를 포함합니다 (V가 아닌 정점 수).

fT원래 제제로부터 사용되며 ; 즉, 정점 인덱스의 순서 트리플로 표시되는 삼각형을 포함합니다.

암호

z=Length;1-z@#2-z@#+z[Union@@(Sort/@{#|#2,#2|#3,#3|#}&@@@#2)]&

(교체 규칙을 제거하여 5 개의 문자를 제거해 주신 마법사에게 감사드립니다.)


실시 예 1

v = {{0, 0}, {1, 0}, {0, 1}, {1, 2}}; f = {{0, 1, 2}, {1, 2, 3}};

z=Length;1-z@#2-z@#+z[Union@@(Sort/@{#|#2,#2|#3,#3|#}&@@@#2)]&[v, f]

0

홀이 없습니다.


실시 예 2

v = {{0, 0}, {1, 0}, {2, 0}, {2, 1}, {2, 2}, {1, 2}, {0, 2}, {0, 1} , {.5, .5}, {1.5, .5}, {1.5, 1.5}, {.5, 1.5}}; f = {{5, 6, 11}, {5, 10, 11}, {4, 5, 10}, {3, 8, 10}, {2, 3, 9}, {2, 8, 9} , {1, 2, 8}, {0, 1, 8}, {0, 8, 11}, {0, 7, 11}, {6, 7, 11}, {3, 4, 10}};

z=Length;1-z@#2-z@#+z[Union@@(Sort/@{#|#2,#2|#3,#3|#}&@@@#2)]&[v, f]

2

따라서 2 개의 구멍이 예 2에 있습니다.


기본적으로 삼각 측량을 래스터 화하고 해당 이미지에 그래픽 라이브러리를 덤프합니까? 구멍이 너무 작아도 실패하지 않습니까?
John Dvorak

1
두 번째 예제는 여기에 0을 반환합니다 (그래서 내가 사용하지 않은 이유 MorphologicalEulerNumber[]). Mma 9.01, Win XP.
Dr. belisarius

9.0.1도 사용하고 있지만 Mac에서는 사용하고 있습니다. 당신은 Mathematica가 Windows에서 내 것과 다른 답변을 반환한다고 말하는 것입니까? 그렇다면 버그 인 것 같습니다 (Windows XP 버전).
DavidC

@DavidCarraher Yep : i.stack.imgur.com/LKcr1.png
박사

얀 드보락 MorphologicalEulerNumber때로는 이미지가 필요합니다. 그래픽스 객체를 수락하지 않습니다. 이 경우 구멍의 크기와 해상도가 중요합니다 ( codegolf.stackexchange.com/questions/8706/… 참조 ). 그러나 여기서는 모든 정점을 명시 적으로 포함하는 Graphics 객체와 직접 작동합니다. 나는 이미지에 의존하지 않는 접근법을 사용할 것이라고 상상했습니다 (또는 희망했습니다). 문제 해결 방법을 알고 싶습니다. 아마도 함수의 소스 코드에서 약간의 문제가 발생했을 것입니다.
DavidC

1

파이썬, 107

나는 페어를 직접받는 것이 from itertools import*타이핑 보다 짧다는 것을 깨달았습니다 combinations(). 그러나 나는 또한 내 솔루션이 정점을 일관된 순서로 나열한 입력 삼각형면에 의존한다는 것을 알았습니다. 따라서 문자 수의 이득은 그렇게 크지 않습니다.

f=lambda l,t:1-len(l+t)+len(set([tuple(sorted(m))for n in[[i[:2],i[1:],[i[0],i[2]]]for i in t]for m in n]))

파이썬, 115

오일러의 특징적인 접근 방식, itertools의 자세한 설명은 피할 수없는 것 같습니다. 정점 쌍을 만들기 위해보다 직접적인 기술을 사용하는 것이 더 저렴한 지 궁금합니다.

from itertools import*
f=lambda l,t:1-len(l+t)+len(set([m for n in[list(combinations(i,2)) for i in t]for m in n]))

사용 예 :

> f([[0,0],[1,0],[0,1],[1,2]],[[0,1,2],[1,2,3]])
> 0
> f([[0,0],[1,0],[2,0],[2,1],[2,2],[1,2],[0,2],[0,1],[.5,.5],[1.5,.5],[1.5,1.5],[.5,1.5]],[[5,6,11],[5,10,11],[4,5,10],[3,8,10],[2,3,9],[2,8,9],[1,2,8],[0,1,8],[0,8,11],[0,7,11],[6,7,11],[3,4,10]])
> 2
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.