Mathematica、111 105 104バイト
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&
説明:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&
r
入力を受け取り#
、セル0までの距離(セル数)を計算する関数を定義します。これは、各距離/リングの最後のセルのパターンを活用することでこれを行います:0 = 3(0 ^ 2 + 0)、6 = 3(1 ^ 2 + 1)、18 = 3(2 ^ 2 + 2)、36 = 3(3 ^ 2 + 3)、...およびそのパターンの式を反転します。セル0の場合、実際には(1/2)+ i *(sqrt(3)/ 6)のフロアを取得し、コンポーネントごとに計算して0 + 0 * i = 0 になることに注意してください。
r
定義され、r@#
セルのためのリングである#
(他の関数の定義の中で)。#+3r@#-3(r@#)^2&
はコードに正確に表示されませんが、セルの番号を取得し、次の内部リングのセルの最大番号を減算するため、「現在のリングのどのセルがこれですか?」という質問に対する答えが得られます。たとえば、セル9はリング2の3番目のセルなので、r[9]
2を#+3r@#-3(r@#)^2&[9]
出力し、3を出力します。
上記の関数でできることは、「セル0、セル17、セル58」光線から問題のセルへの反時計回りの角度である極角を見つけるために使用することです。すべてのリングの最後のセルは常に角度Pi / 6であり、Pi /(3 * ring_number)の増分でリングを一周します。したがって、理論的には、Pi / 6 +(which_cell_of_the_current_ring)* Pi /(3 * ring_number)のようなものを計算する必要があります。ただし、画像の回転は何にも影響しないため、Pi / 6部分を破棄できます(6バイトを節約するため)。これを前の式と組み合わせて単純化すると、次のようになりますPi(#/(3r@#)+1-r@#)&
残念ながら、リング番号が0であるため、これはセル0に対して未定義です。そのため、これを回避する必要があります。自然な解決策は次のようなものですt=If[#==0,0,Pi(#/(3r@#)+1-r@#)]&
。しかし、セル0の角度は気にせずr@#
、繰り返されるので、実際にここでバイトを保存できますt=Limit[Pi(#/(3x)+1-x),x->r@#]&
リング番号と角度がわかったので、セル(中央)の位置を見つけて、隣接関係をテストできます。リングは六角形であるため、実際の位置を見つけるのは面倒ですが、リングを完全な円であるかのように単純に指定して、リング番号をセル0の中心までの距離として扱うことができます。閉じる。複素数の極形式を使用して、単純な関数で複素平面のこの近似位置を表すことができます。p = r@#*Exp[I*t@#] &;
複素平面上の2つの複素数間の距離は、それらの差の絶対値によって与えられます。その後、結果を丸めて近似からのエラーを処理し、これが1に等しいかどうかを確認できます。この作品には名前がありませんが、ですRound@Abs[p@#-p@#2]==1&
。
次のようなコードを貼り付け、Gear->「Evaluate cell」をクリックするか、Shift + EnterまたはテンキーEnterを押すと、Wolfram Cloudサンドボックスでオンラインで試すことができます。
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&[24,45]
または、すべてのテストケースについて:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&;t=Limit[Pi(#/(3x)+1-x),x->r@#]&;p=r@#*Exp[I*t@#]&;Round@Abs[p@#-p@#2]==1&//MapThread[#,Transpose[{{0,1},{7,18},{8,22},{24,45},{40,64},{64,65},{6,57},{29,90},{21,38},{38,60},{40,63},{41,39},{40,40}}]]&