ヘキサゴンインまたはヘキサゴンアウト?


8

たとえば蜂の巣に見られる通常の六角形について語るに、すばらしい話があります。しかし、この忙しいミツバチは、ハニーポットの内側と外側のどちらのポイントであるかを彼に知らせるためにあなたの助けが必要です。したがって、下の図に示すように、原点を中心とし、エッジサイズがlの正六角形を指定して、座標セット(x、y)が正六角形の内側、端、または外側にあるかどうかを確認します。

原点を中心とする、エッジの長さがlの六角形

入力、出力、ルール

ルールは次のとおりです。

  • 入出力メソッドはデフォルトのルールに従います
  • 入力は3で構成され、整数x,y,l
  • xそしてy、任意の好都合な符号付き整数フォーマットです。l正です(0にはなりません)。
  • プログラムは1、ポイント(x,y)が正六角形の内側にある場合、-1またはそれが外側または外側の場合、aを出力または返す必要があります。0場合、端に正確に。
  • これはコードゴルフなので、最短のコードが優先されます。同点の場合は、最も古い投稿が優先されます。
  • stdoutへの出力の場合:出力の先頭/末尾のスペースまたは改行が許可されます。
  • 標準の抜け穴が適用されます。

テストケース

ここにいくつかのテストケースがあります:

0,0,1        --> 1
0,1,1        --> -1
0,-1,1       --> -1
1,0,1        --> 0
-1,0,1       --> 0
-1,-1,1      --> -1
1,1,1        --> -1
-2,-3,4      --> 1
32,45,58     --> 1
99,97,155    --> -1
123,135,201  --> 1

これは正六角形であると思いますが、それを明示する必要があります。
Level River St

@LevelRiverStはい。レギュラー。すぐに追加します。
agtoever 2016年

1
x、yを複素数x + yiとして取得できますか?
リルトシアスト2016年


@lirtosiast問題は、複雑な平面ではなく、ユークリッド平面の六角形についてです。そのため、複雑な入力は許可されていません。
agtoever 2016年

回答:


2

JavaScript(ES6)77 83

(a,b,l,h=Math.sqrt(3)*l,x=a<0?-a:a,y=b<0?-b:b)=>y|x!=l?2*y<h&x/l+y/h<1?1:-1:0

テスト

f=(a,b,l,h=Math.sqrt(3)*l,x=a<0?-a:a,y=b<0?-b:b)=>y|x!=l?2*y<h&x/l+y/h<1?1:-1:0

// TEST

function go() {
  C.width=400;C.height=300;
  var l=+I.value, x,y, cols={0:'#ff0',1:'#0f0','-1':'#888'},
  ctx = C.getContext("2d")
  ctx.translate(200,150)
  ctx.strokeStyle='#000'
  ctx.lineWidth=1;
  ctx.beginPath();
  ctx.moveTo(0,-150);ctx.lineTo(0,150);ctx.moveTo(-200,0);ctx.lineTo(200,0);
  ctx.stroke();
  ctx.strokeStyle='#f00'
  ctx.beginPath();
  ctx.moveTo(l*10,0);ctx.lineTo(l*5,l*Math.sqrt(3)*5);ctx.lineTo(-l*5,l*Math.sqrt(3)*5)
  ctx.lineTo(-l*10,0);ctx.lineTo(-l*5,-l*Math.sqrt(3)*5);ctx.lineTo(l*5,-l*Math.sqrt(3)*5)
  ctx.closePath();
  ctx.stroke();

  for(y=-14;y<15;y++)
    for(x=-19;x<20;x++) {
      ctx.beginPath();
      ctx.moveTo(x*10,y*10-3);ctx.lineTo(x*10,y*10+3);
      ctx.moveTo(x*10-3,y*10);ctx.lineTo(x*10+3,y*10);
      ctx.strokeStyle=cols[f(x,y,l)]
      ctx.stroke()
    }
}

go()
#C {
  border: 1px solid #000
}
<b>L</b> <input id=I value=15><button onclick="go()">GO</button><br>
<canvas id=C width=400 height=300></canvas>


2

ルビー、150 145 137 127 125 106 88 76バイト

76バイト

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z<=>0}

トリプル比較をロケットに変更しました。

88バイト

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z==0 ?0:0<z ?1:-1}

六角形上の点のapothemテストに等しいyを削除します。

106バイト:

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y==d&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:z==0 ?0:0<z ?1:-1}

ポスターはイプシロンを使用しないことを提案したため、イプシロンをゼロに置き換えて再配置し、absを削除しました。

125バイト:

->(x,y,l){x,y,t,e=x.abs,y.abs,3**0.5,1e-9;d=t*l;z=d-t*x-y;(2*y-d).abs<=e&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:z.abs<=e ?0:0<z ?1:-1}

yをzの定義に組み込み、いくつかの括弧を削除します。

127バイト:

->(x,y,l){x,y,t,e=x.abs,y.abs,3**0.5,1e-9;d=t*l;z=d-t*x;(2*y-d).abs<=e&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:(z-y).abs<=e ?0:y<z ?1:-1}

to_fキャストの必要性を避けるために用語を再配置しました。a(アポテム)の代わりにd(アポテムの2倍)を使用します。複数の割り当てを組み合わせる。

137バイト:

->(x,y,l){x=x.abs.to_f;y=y.abs.to_f;a=3**0.5*l/2;e=1e-9;z=2*a*(1-x/l);(y-a).abs<=e&&2*x<=l ?0:y>a ?-1:2*x<l ?1:(z-y).abs<=e ?0:y<z ?1:-1}

インライン化された「c」。

150バイト:

->(x,y,l){c=l/2.0;x=x.abs.to_f;y=y.abs.to_f;a=3**0.5*l/2;e=1e-10;z=2*a*(1-x/l);(y-a).abs<=e&&x<=c ?0:(y>a ?-1:(x<c ?1:((z-y).abs<=e ?0:(y<z ?1:-1))))}

これは整数または浮動小数点に対して機能します!イプシロンテストでは、エッジ上にある丸め誤差内のポイントが正しく識別されます。

絶対値はすべてを象限1に移動します。

値 'a'は、アポテム距離(六角形のy切片)です。

値「c」は、六角形の右上隅のx値です。

値「z」は、ポイントがコーナーからx切片への傾斜線の上か下かを確認するためのものです。

未ゴルフ:

hex = ->(x,y,l){ 
    c = l/2.0;
    x = x.abs.to_f;
    y = y.abs.to_f;
    a = 3**0.5 * l / 2;
    e = 1e-10;
    z = 2*a*(1 - x/l);
    if (y-a).abs <= e && x <= c then 0
    elsif (y>a) then -1
    elsif (x<c) then 1
    elsif (z-y).abs <= e then 0
    elsif y < z then 1
    else -1
    end
}

テスト

hex = ->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z<=>0}

cases = [
    [0,0,1,1],
    [0,1,1,-1],
    [0,-1,1,-1],
    [1,0,1,0],
    [-1,0,1,0],
    [-1,-1,1,-1],
    [1,1,1,-1],
    [-2,-3,4,1],
    [32,45,58,1],
    [99,97,155,-1],
    [123,135,201,1]
]

cases.each { |test| 
  expected = test[3]
  actual = hex.call(test[0],test[1],test[2])
  status = expected == actual ? "PASS" : "FAIL";
  p "#{status}. #(x,y) L = (#{test[0]},#{test[1]}) #{test[2]} Expects #{expected}. Actual #{actual}"
}
"Done!"

これは短くなる可能性があります。整数にイプシロンは必要ありません
edc65

3の平方根を導入することで、浮動小数点を使用せざるを得なくなりました。比較前に数値を丸めるか、イプシロン計算を使用できます。イプシロンはコードがより一般的でフロートで機能することを可能にするので、私はイプシロンのままにしました。私はRubyをプログラミングしてからしばらくしか経っていないので、丸め誤差をどのように処理するのかわかりません。
Paul Chernoch 2016年

左右の傾きは合理的ではありません。格言は合理的ではありません。[l、0]と[-l、0]の境界に整数座標がある2つのポイントのみ
edc65

おそらく、整数入力の場合、六角形上に「存在する」可能性のある整数点は他にないでしょう。それを自分で証明することは、コードを気にせずイプシロンを使用するよりも困難でした。
Paul Chernoch 2016年

うん!Pythonソリューションに合格しました!
Paul Chernoch 2016年


0

ジュリア、65 58バイト

f(x,l)=(t=maxabs(x/l*[[0 1 1];[2 1 -1]/3^.5]);(t<1)-(t>1))

x行ベクトル[x y]です。次のように呼び出しますf([0 0],1)


0

Python 2、89バイト

ジュリアの答えとほぼ同じ解決策ですが、numpyなしでベクトルの演算を使用できます

lambda x,y,L,K=3**0.5/2.:cmp(K*L,max([abs(x*i+y*j)for i,j in[[K,1/2.],[0,1],[-K,1/2.]]]))

結果

>>> f(0,0,1)
1
>>> f(32,45,58)
1
>>> f(99,97,155)
-1
>>> f(-1,0,1)
0
>>> [f(0,0,1)== 1,f(0,1,1)== -1,f(0,-1,1)== -1,f(1,0,1)== 0,f(-1,0,1)== 0,f(-1,-1,1)== -1,f(1,1,1)== -1,f(-2,-3,4)== 1,f(32,45,58)== 1,f(99,97,155)== -1,f(123,135,201)== 1,f(0,0,1)== 1,f(0,1,1)== -1,f(0,-1,1)== -1,f(1,0,1)== 0,f(-1,0,1)== 0,f(-1,-1,1)== -1,f(1,1,1)== -1,f(-2,-3,4)== 1,f(32,45,58)== 1,f(99,97,155)== -1,f(123,135,201)== 1]
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]


0

JavaScript(ES6)、67バイト

with(Math)(a,b,l)=>sign(min(l*l*3-b*b*4,(l-abs(a))*sqrt(3)-abs(b)))

注:これを変数に割り当てて呼び出せるようにするには、のf=後にを置きwith(Math)ます。

私が使用l*lしてb*b最初のパラメータにすることminへの呼び出しを避けるために、absそしてsqrt私は、私は二番目のパラメータと同様のトリックを行うことができるかどうかを考え出すことができませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.