Mathematica, 111 105 104 byte
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&
Penjelasan:
r=Floor[(1+Sqrt[(4#-1)/3])/2]&
mendefinisikan fungsi r
yang mengambil input #
dan menghitung jarak (dalam jumlah sel) ke sel 0. Ia melakukan ini dengan mengeksploitasi pola dalam sel terakhir dari setiap jarak / dering: 0 = 3 (0 ^ 2 + 0), 6 = 3 (1 ^ 2 + 1), 18 = 3 (2 ^ 2 + 2), 36 = 3 (3 ^ 2 + 3), ... dan membalikkan rumus untuk pola itu. Perhatikan bahwa untuk sel 0, sebenarnya dibutuhkan lantai (1/2) + i * (sqrt (3) / 6), yang menghitung komponen-bijaksana untuk mendapatkan 0 + 0 * i = 0.
Dengan r
didefinisikan, r@#
adalah cincin untuk sel #
(di dalam definisi fungsi lain). #+3r@#-3(r@#)^2&
tidak muncul dalam kode persis, tetapi dibutuhkan jumlah sel dan kurangi jumlah sel tertinggi di cincin dalam berikutnya, sehingga memberikan jawaban untuk pertanyaan "sel dari cincin mana saat ini?" Misalnya, sel 9 adalah sel ke-3 dari cincin 2, demikian r[9]
juga output 2 dan#+3r@#-3(r@#)^2&[9]
akan menghasilkan 3.
Apa yang dapat kita lakukan dengan fungsi di atas adalah menggunakannya untuk menemukan sudut kutub , sudut berlawanan arah jarum jam dari sinar "sel 0, sel 17, sel 58" ke sel yang dimaksud. Sel terakhir dari setiap cincin selalu pada sudut Pi / 6, dan kami mengelilingi sebuah cincin dalam penambahan Pi / (3 * ring_number). Jadi, secara teori, kita perlu menghitung sesuatu seperti Pi / 6 + (which_cell_of_the_current_ring) * Pi / (3 * ring_number). Namun, rotasi gambar tidak memengaruhi apa pun, sehingga kami dapat membuang bagian Pi / 6 (untuk menghemat 6 byte). Menggabungkan ini dengan formula sebelumnya dan menyederhanakan, kami dapatkanPi(#/(3r@#)+1-r@#)&
Sayangnya, ini tidak terdefinisi untuk sel 0 karena nomor cincinnya adalah 0, jadi kita perlu menyiasatinya. Solusi alami akan seperti itu t=If[#==0,0,Pi(#/(3r@#)+1-r@#)]&
. Tetapi karena kita tidak peduli dengan sudut untuk sel 0 dan karena r@#
diulang, kita sebenarnya dapat menyimpan byte di sinit=Limit[Pi(#/(3x)+1-x),x->r@#]&
Sekarang kita memiliki nomor cincin dan sudut, kita dapat menemukan posisi sel (tengah) sehingga kita dapat menguji kedekatan. Menemukan posisi yang sebenarnya mengganggu karena cincin itu heksagonal, tetapi kita bisa menganggap cincin itu lingkaran sempurna sehingga kita memperlakukan nomor cincin sebagai jarak ke pusat sel 0. Ini tidak akan menjadi masalah karena perkiraannya cukup dekat. Dengan menggunakan bentuk kutub dari bilangan kompleks , kita dapat mewakili posisi perkiraan ini di bidang kompleks dengan fungsi sederhana:p = r@#*Exp[I*t@#] &;
Jarak antara dua bilangan kompleks pada bidang kompleks diberikan oleh nilai absolut dari selisihnya, dan kemudian kita dapat membulatkan hasilnya untuk menangani kesalahan apa pun dari perkiraan, dan memeriksa apakah ini sama dengan 1. Fungsi yang akhirnya apakah karya ini tidak memiliki nama, tetapi ada Round@Abs[p@#-p@#2]==1&
.
Anda dapat mencobanya secara online di kotak pasir Wolfram Cloud dengan menempelkan kode seperti berikut ini dan mengeklik Gear -> "Evaluate cell" atau menekan Shift + Enter atau numpad Enter:
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]
Atau untuk semua kasus uji:
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}}]]&