2D空間内の頂点のリストによって定義される、潜在的に自己交差するポリゴンを考えてみましょう。例えば
{{0, 0}, {5, 0}, {5, 4}, {1, 4}, {1, 2}, {3, 2}, {3, 3}, {2, 3}, {2, 1}, {4, 1}, {4, 5}, {0, 5}}
このようなポリゴンの領域を定義する方法はいくつかありますが、最も興味深いのは偶奇規則です。平面内の任意の点を取り、その点から無限に(任意の方向に)線を引きます。その線が多角形を奇数回交差する場合、ポイントは多角形の領域の一部であり、多角形を偶数回交差する場合、ポイントは多角形の一部ではありません。上記のポリゴンの例では、輪郭と偶奇領域の両方があります。
通常、ポリゴンは直交しません。面積を数えやすくするために、このような単純な例を選択しただけです。
この例の領域は17
(他の定義または領域がもたらす可能性のあるものではない、24
または33
そうではない)です。
この定義では、多角形の面積はその巻き順とは無関係です。
チャレンジ
多角形を定義する整数座標を持つ頂点のリストが与えられたら、偶奇規則の下で面積を決定します。
関数またはプログラムを作成し、STDINまたは最も近い代替、コマンドライン引数または関数引数を介して入力を取得し、結果を返すか、STDOUTまたは最も近い代替に出力できます。
前処理されていない限り、任意の便利なリスト形式または文字列形式で入力を取得できます。
結果は、有効桁数が6桁(10進数)の浮動小数点数か、浮動小数点表現が有効桁数が6桁の有理数結果でなければなりません。(合理的な結果を生成する場合、それらは正確になる可能性が高いですが、参照用の正確な結果がないため、これを要求することはできません。)
適切なデスクトップマシンで、10秒以内に以下の各テストケースを解決できる必要があります。(このルールには多少の余裕がありますので、最善の判断をしてください。私のラップトップで20秒かかる場合、疑いの恩恵があります。1分かかる場合、私はしません)。非常に寛大なはずですが、十分に細かいグリッドでポリゴンを離散化してカウントするアプローチ、またはモンテカルロのような確率的アプローチを使用するアプローチを除外することになっています。優れたスポーツマンであり、いずれにしても制限時間を満たすことができるようにこれらのアプローチを最適化しようとしないでください。;)
ポリゴンに直接関連する既存の関数を使用しないでください。
これはコードゴルフであるため、最短の提出(バイト単位)が優先されます。
仮定
- すべての座標は、範囲内の整数です
0 ≤ x ≤ 100
、0 ≤ y ≤ 100
。 - 少なくとも
3
、多くても50
頂点があります。 - 頂点が繰り返されることはありません。また、頂点が別のエッジにあることもありません。(ただし、リストには同一直線上の点がある場合があります。)
テストケース
{{0, 0}, {5, 0}, {5, 4}, {1, 4}, {1, 2}, {3, 2}, {3, 3}, {2, 3}, {2, 1}, {4, 1}, {4, 5}, {0, 5}}
17.0000
{{22, 87}, {6, 3}, {98, 77}, {20, 56}, {96, 52}, {79, 34}, {46, 78}, {52, 73}, {81, 85}, {90, 43}}
2788.39
{{90, 43}, {81, 85}, {52, 73}, {46, 78}, {79, 34}, {96, 52}, {20, 56}, {98, 77}, {6, 3}, {22, 87}}
2788.39
{{70, 33}, {53, 89}, {76, 35}, {14, 56}, {14, 47}, {59, 49}, {12, 32}, {22, 66}, {85, 2}, {2, 81},
{61, 39}, {1, 49}, {91, 62}, {67, 7}, {19, 55}, {47, 44}, {8, 24}, {46, 18}, {63, 64}, {23, 30}}
2037.98
{{42, 65}, {14, 59}, {97, 10}, {13, 1}, {2, 8}, {88, 80}, {24, 36}, {95, 94}, {18, 9}, {66, 64},
{91, 5}, {99, 25}, {6, 66}, {48, 55}, {83, 54}, {15, 65}, {10, 60}, {35, 86}, {44, 19}, {48, 43},
{47, 86}, {29, 5}, {15, 45}, {75, 41}, {9, 9}, {23, 100}, {22, 82}, {34, 21}, {7, 34}, {54, 83}}
3382.46
{{68, 35}, {43, 63}, {66, 98}, {60, 56}, {57, 44}, {90, 52}, {36, 26}, {23, 55}, {66, 1}, {25, 6},
{84, 65}, {38, 16}, {47, 31}, {44, 90}, {2, 30}, {87, 40}, {19, 51}, {75, 5}, {31, 94}, {85, 56},
{95, 81}, {79, 80}, {82, 45}, {95, 10}, {27, 15}, {18, 70}, {24, 6}, {12, 73}, {10, 31}, {4, 29},
{79, 93}, {45, 85}, {12, 10}, {89, 70}, {46, 5}, {56, 67}, {58, 59}, {92, 19}, {83, 49}, {22,77}}
3337.62
{{15, 22}, {71, 65}, {12, 35}, {30, 92}, {12, 92}, {97, 31}, {4, 32}, {39, 43}, {11, 40},
{20, 15}, {71, 100}, {84, 76}, {51, 98}, {35, 94}, {46, 54}, {89, 49}, {28, 35}, {65, 42},
{31, 41}, {48, 34}, {57, 46}, {14, 20}, {45, 28}, {82, 65}, {88, 78}, {55, 30}, {30, 27},
{26, 47}, {51, 93}, {9, 95}, {56, 82}, {86, 56}, {46, 28}, {62, 70}, {98, 10}, {3, 39},
{11, 34}, {17, 64}, {36, 42}, {52, 100}, {38, 11}, {83, 14}, {5, 17}, {72, 70}, {3, 97},
{8, 94}, {64, 60}, {47, 25}, {99, 26}, {99, 69}}
3514.46
upath
と、lineto
実際に入力を前処理しているように聞こえます。つまり、座標のリストを取得するのではなく、実際のポリゴンを取得します。
CrossingPolygon
。
upath
演算子で全体を解析できます。(実際には、セパレーター間の非常に単純な1:1変換です。}, {
単にになりlineto
、xとyの間のコンマが削除され、開始括弧と終了括弧が静的ヘッダーとフッターに置き換えられます...)