多角形の穴の数


11

問題:接続されたポリゴンの穴の数を数えます。ポリゴンの接続性は、入力三角形分割のすべての三角形が少なくとも1つの辺を別の三角形と共有し、そのような接続された三角形のセットが1つしかないという条件によって保証されます。

入力は、平面内Ln点のリストと、Tからのエントリを含む3タプルのリストです0...n-1Tタプル内の各アイテムは、三角形分割の三角形(t_1,t_2,t_3)の3つの頂点(リストからL)を表します。これは、「ポリゴンの三角形分割」の意味で三角形分割であることに注意してください。このため、Tそのオーバーラップに2つの三角形が存在することはありません。追加の規定は、あなたが入力をサニタイズする必要はないだろう、ということである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
「ポリゴンの接続性は、入力三角形分割のすべての三角形が少なくとも1つの辺を別の三角形と共有するという条件によって保証されます。」 - 番号。それは十分な条件ではありません。例えば、取りますT=1,2,3/1,2,4/5,6,7/5,6,8。すべての三角形は別の三角形とエッジを共有しますが、三角形分割は切断されます
ジョンドヴォルザーク

入力が有効な部分三角形分割を表し(2つの三角形が重複せず、三角形が2回存在しない)、三角形分割が接続されていると仮定できますか?
ジョンドヴォルザーク


また、形状の接続を切断するために有限の点のセットを削除することができないという意味で、入力がエッジ接続されていると仮定できますか?(例:T=1,2,3/1,4,5接続されているが、エッジ接続されていない)
ジョンドヴォルザーク

2
終了日に関するこのビジネスが最近現れ始めた理由はわかりません。受け入れられた回答を変更できるため、終了日を設定する必要はありません。最初の回答は無敵だと思わせないように、回答を選択する前に1週間待つという精神的な考えを持つことは理にかなっていますが、サイトでアクティブである限り、選択した回答を変更できます誰かがより良いものを投稿した場合。関連するメタディスカッションには、meta.codegolf.stackexchange.com / q
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

Python、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を使用、zip(以前に使用したとは言えないため、自分自身を知る必要があります。)
カヤ

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

説明、右から左へ:

  • ⍴⍺,⍵2つの入力ベクトルを連結し、それらの長さ(V + F)を返します
  • 次のブロック内に足を踏み入れる:
    • ¨⍵ 左側の関数を右側の引数のすべての要素に適用し、結果を返します
    • ⍵,⍵ 自身と連結された正しい引数を返します
    • 3 2⍴ベクトル引数を3つのペアに整形します。この場合、ベクトルの1番目と2番目、3番目と1番目、2番目と3番目のアイテムをペアにします。
    • ,/ ベクトル引数を結合します
    • ⍵[⍋⍵] 正しい引数をソートします
    • ∪/ 重複を除外します
    • ⍴⊃ ネストされたスカラーをベクトルに変換し、その長さを返します。
    • 関数全体が形状のエッジの数を返します(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)を持つ三角形または穴に依存していませんか?
ジョンドヴォルザーク

@JanDvorakおそらく間違っているかもしれませんが、無限精度の算術演算を使用しない限り、特定の最小サイズに達するまでソリューションは機能すると思います(3つのポイントが整列するかどうかを判断する必要があります)。この種のソリューションでは、問題が明示的に述べられているだけです。
ベリサリウス博士13年

トポロジカルアプローチを使用する場合、その必要はありません。同一線上に3つの点がある場合、そこにゼロ面積の三角形が必要です。それ以外の場合は、穴があります。
ジョン・ドヴォルザーク

@belisarius。結果の不一致についてWolframテクニカルサポートから受け取った回答は次のとおりです。この問題について開発者に報告書を提出しました。この問題について開発者から得た有用な情報は必ずお伝えします。ご質問がある場合はお知らせください。 、Inc。」
DavidC

@DavidCarraher 「はい、さらに質問があります。各バグのチェックを送ってもらえますか?」
ベリサリウス博士13年

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

イェーラー、オイラー特性アプローチ。それは私がPythonでそれをやった方法です。
カヤ

2
@カヤ。(コロンブスの卵en.wikipedia.org/wiki/Egg_of_Columbusを参照してください)誰かがあなたの質問にオイラーの答えを与えると、他の人がフォローする可能性が非常に高くなります。オイラーの多面体との関係を確立した後で初めて、自分自身でアプローチを発見することははるかに困難で満足のいくものであると確信できます。
DavidC

2

Mathematica 76 73 72 67 62

何度も実験を重ねた結果、頂点の正確な位置は問題ではないことに気づき、グラフで問題を表現しました。本質的な不変量、三角形の数、エッジ、および頂点は不変のままでした(ただし、ラインの交差は回避されました)。

グラフには2種類の内部「三角形」がありました。それらはおそらく顔、つまり「塗りつぶされた」三角形があったものとそうでないものでした。内部フェースの数は、エッジまたは頂点とは関係がありませんでした。つまり、完全に「塗りつぶされた」グラフに穴を開けると、面の数が減っただけです。三角形のバリエーションを体系的に使用して、顔、頂点、およびエッジを追跡しました。最終的に、穴の数は常に1-#faces-#vertices + #edgesに等しいことに気付きました。これは、1からオイラー特性(通常の多面体のコンテキストでのみ知っていたもの)であることが判明しました(ただし、エッジの長さは明らかに重要ではありませんでした。

以下の関数は、頂点と三角形が入力されたときに穴の数を返します。私の以前の提出とは異なり、画像のスキャンに依存しません。1-オイラーの特性、つまり1-(F + V -E)と考えることができます。ここで、F= #faces、V=#vertices、E=#edgesです。この関数は、1 - (F + V -E)実際の面(三角形)と頂点を指定すると、穴の数を返します。

複合体の外側の三角形を削除しても、他の三角形と1辺または2辺を共有するかどうかに関係なく、オイラー特性に影響を与えないことが簡単にわかります。

注:元の定式化のv代わりに小文字が使用されLます。つまり、頂点自体を含みます(V、頂点の数ではありません)

fT元の定式化に使用されます。つまり、頂点インデックスの順序付きトリプルとして表される三角形が含まれています。

コード

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

(置換ルールを削除することにより5文字を削除したMr. Wizardに感謝します。)


例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つの穴があります。


あなたは基本的に三角形分割をラスタライズし、その画像にグラフィックライブラリをダンプしていますか?穴が小さすぎると失敗しませんか?
ジョン・ドヴォルザーク

1
2番目の例はここで0を返します(だから私は使用していませんMorphologicalEulerNumber[])。Mma 9.01、Win XP。
ベリサリウス博士13年

9.0.1も使用していますが、Macで使用しています。Windows上でMathematicaが私の答えとは異なる答えを返すと言っているのですか?もしそうなら、それはバグのように聞こえます(Windows XPバージョンで)。
DavidC

@DavidCarraherうん:i.stack.imgur.com/LKcr1.png
博士13年

@Jan Dvorak。 MorphologicalEulerNumber画像が必要な場合があります。グラフィックスオブジェクトの受け入れを拒否します。これらの場合、穴のサイズと解像度が重要です(codegolf.stackexchange.com/questions/8706/…を参照)。ただし、ここでは、すべての頂点が明示的に含まれているGraphicsオブジェクトで直接動作します。イメージに依存しないアプローチを使用することを想像しました(または期待していました)。この問題をどのように解決しようとしたかを知っていればいいのですが。おそらく、関数のソースコードの一部を調べることで問題が明確になるでしょう。
DavidC

1

Python、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]))

Python、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.