Намалювання трикутника Серпінського було зроблено до смерті . Є й інші цікаві речі, які ми можемо з цим зробити. Якщо ми досить сильно косимося до трикутника, ми можемо розглядати перевернуті трикутники як вузли фрактального графіка. Давайте знайдемо цей графік!
Спочатку давайте призначимо номер кожному вузлу. Найбільший трикутник догори дном буде нульовим вузлом, і тоді ми просто спускаємося по шару вниз (по ширині перший), присвоюючи послідовні числа в порядку зверху ліворуч праворуч:
Клацніть для більшої версії, де невеликі цифри трохи менше розмито.
(Звичайно, ця модель продовжує до нескінченності всередині синіх трикутників.) Ще один спосіб визначити нумерацію, що центральний вузол має індекс 0
, а діти вузла i
(суміжні трикутники наступного меншого масштабу) мають індекси 3i+1
, 3i+2
і 3i+3
.
Як ми рухаємося навколо цього графіка? Існує до шести природних кроків, які можна зробити з будь-якого даного трикутника:
- Завжди можна переміщатися через середину одного з ребер до одного з трьох дітей поточного вузла. Ми будемо позначати ці кроки як
N
,SW
іSE
. Наприклад , якщо ми в даний час на вузлі2
, це призведе до вузлів7
,8
,9
відповідно. Інші рухи по краях (до непрямих нащадків) заборонені. - Можна також просуватися через один з трьох кутів, за умови, що він не торкається краю трикутника, ні до прямого батьків, ні до одного з двох непрямих предків. Ми будемо позначати ці кроки як
S
,NE
іNW
. Наприклад , якщо ми в даний час на вузлі31
,S
призведе до10
,NE
було б неприпустимим іNW
призведе до0
.
Змагання
Дано два невід’ємні цілі числа x
і y
знайдіть найкоротший шлях від x
до y
, використовуючи лише шість описаних вище кроків. Якщо є кілька найкоротших шляхів, виведіть будь-який з них.
Зауважте, що ваш код повинен працювати більше, ніж лише 5 рівнів, зображених на наведеній вище діаграмі. Ви можете припустити, що x, y < 1743392200
. Це гарантує, що вони вміщуються в 32-бітове ціле число. Зауважте, що це відповідає 20 рівням дерева.
Ваш код повинен обробити будь-який дійсний вхід менш ніж за 5 секунд . У той час як це виключає найперший пошук в широкій силі, це повинно бути досить слабким обмеженням - моя опорна реалізація обробляє довільне введення на глибину 1000 за півсекунди (це ~ 480-значне число для вузлів).
Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).
Вихід повинен бути плоским, недвозначним список рядків N
, S
, NE
, NW
, SE
, SW
, використовуючи будь-який розумний роздільник (прогалини, символи перекладу рядка, коми, ","
...).
Діють стандартні правила гольф-коду .
Випробування
Перші кілька тестових випадків можна опрацювати вручну, використовуючи схему, подану вище. Інші забезпечують достатню ефективність відповідей. Для них можуть бути інші рішення такої ж довжини, які не вказані.
0 40 => N N N N
66 67 => S SW N N N
30 2 => NW NW -or- NE SW
93 2 => NE SW
120 61 => NW NW NW NW N SE SW N
1493682877 0 => S S NW NW
0 368460408 => SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130 1242824 => NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
520174 1675046339 => NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
312602548 940907702 => NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873 => NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
547211529 1386725128 => S S S NE NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199 => NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE