J、 40 39 34バイト
3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
匿名進機能、ポイントを取って、P、引数の1つ、およびポイントのリストとして、P他の引数として、(それがどのある引数問題ではない)、および返却0または1場合、pは外にありますか凸包内部Pそれぞれ。点pとPの点は複素数として扱われます。
例
is_inside =: 3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
0.5j0.5 is_inside 0j0 0j1 1j0 1j1
1
1.5j0.5 is_inside 0j0 0j1 1j0 1j1
0
または...
Python 2、関数、 121 103、完全なプログラム、 162
Python 3、149バイト
import sys,cmath as C
p,q,*P=[complex(*eval(l.replace(*";,")))for l in sys.stdin]
A=[C.phase((r-p)/(q-p+(q==p)))for r in P]
print(max(A)-min(A)>C.pi)
STDINを介して、元の投稿と同じ形式で入力を受け取り、pがPの凸包にあるかどうかを示すブール値を出力します。
説明
プログラムの最大値と最小値(符号付き)との差が任意の点の間の角度か否かをテストRにおけるP、P、および固定された任意の点QにおけるPは、(先ほどの最初の点を使用Pを)未満180°。言い換えると、Pのすべての点がpを中心に180°以下の角度で含まれているかどうかをテストします。
この条件が偽の場合に限り、pはPの凸包にあります。
さらに数バイトのコストで、角度を明示的に計算する必要のない同様の方法を使用できます。上記の条件は、存在する場合に限り、pがPの凸包の外側にあることを示すことに相当します。Pのすべての点がlの同じ側にあるような、lからpまでの線。そのような行が存在する場合、その後の点の1つ(または複数)に入射するようなAラインもあるPは、(我々が回転可能Lは、それがの点のいずれかに触れるまでPを。)
この線を(暫定的に)見つけるために、lをpを通る線とPの最初の点とすることから始めます。次に、Pの残りの点を反復処理します。ポイントの1つがlの左側にある場合(全体の方向性を想定し、左または右は実際には問題ではありません)、lをpとそのポイントを通過する線で置き換え、続行します。すべてのPを繰り返した後、pが凸包の外にある場合(かつその場合のみ)、Pのすべての点はlの右側(または上)にある必要があります。のポイントをもう一度通過することを確認しPます。
Python 2、172バイト
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=reduce(lambda*x:x[C(*x)],P)
print any(C(l,q)for q in P)
代替的に、聞かせて、単一パスで同じことを行うから、左の任意の2点間のrealtionことQとRで、Pように、qはの左側にあるR場合qは左側にあります通る直線のPおよびR。被左の上の順序関係であることに注意してくださいPは場合とにおける全ての点場合にのみPが通過するいくつかのラインの同じ側にあるP場合、であり、pはの凸包の外側にあるP。上記の手順は、Pの最小点を見つけますこの順序、つまりPの「左端」のポイントについて。2つのパスを実行する代わりに、最大(つまり、「最も右」のポイント)と最小のPのポイントを1つのパスで同じ順序で見つけ、最小値が左にあることを確認できます。最大、つまり効果的には、左端が推移的です。
これは、pがPの凸包の外側にある場合にうまく機能します。この場合、左方向は実際には順序関係ですが、pが凸包の内側にある場合は壊れる可能性があります(たとえば、我々がポイントこのアルゴリズム実行した場合に起こるPは反時計回りを実行している正五角形の頂点、あり、そしてpは我々は、ポイントを選択します。その中心であるが、我々はわずかアルゴリズムを変更し、対応するために)QでPを、と二分pとqを通る線に沿ってP(つまり、Pをqの周りで分割するwrt to-the-left-of。)これで、Pの「左部分」と「右部分」がそれぞれ半平面に含まれるようになりました。したがって、to-the-left-ofはそれぞれの順序関係になります。左部分の最小値と右部分の最大値を見つけ、上記のように比較します。もちろん、Pを物理的に2等分する必要はありません。1 つのパスで最小値と最大値を探すときに、Pの各点を単純に分類できます。
Python 2、194バイト
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=r=P[0]
for q in P:
if C(P[0],q):l=q*C(l,q)or l
elif C(q,r):r=q
print C(l,r)