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, тому r[9]
виводиться 2 і #+3r@#-3(r@#)^2&[9]
виводиться 3.
Що ми можемо зробити з функцією, наведеною вище, це використати її для пошуку полярного кута , кута проти годинникової стрілки від променя "комірка 0, клітинка 17, клітина 58" до комірки, про яку йдеться. Остання комірка кожного кільця завжди знаходиться під кутом Pi / 6, і ми обходимо кільце з кроком Pi / (3 * кільце_ число). Отже, теоретично нам потрібно обчислити щось на зразок Pi / 6 + (котрий_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@#] &;
Відстань між двома комплексними числами на складній площині задається абсолютним значенням їх різниці, і тоді ми можемо округлити результат, щоб переконатися в будь-яких помилках з наближення, і перевірити, чи дорівнює це 1. Функція, яка нарешті чи ця робота не має імені, але є Round@Abs[p@#-p@#2]==1&
.
Ви можете спробувати його в Інтернеті у пісочниці Wolfram Cloud , вставивши такий код, як наступний і натиснути Gear -> "Оцінити клітинку" або натиснувши Shift + Enter або 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]
Або для всіх тестових випадків:
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}}]]&