В далеком королевстве шахматная королева совершает ежедневную прогулку по спиральной дорожке, пронумерованной от 1 до n
, не заботясь о том, чтобы следовать самой спирали, а просто делает движения королевы, как она делает это на шахматной доске. Королева любима своими подданными, и они записывают каждый квадрат, который она посещает на своем пути. Учитывая, что королева может начать свою прогулку на любом квадрате и заканчивать его на любом квадрате, какой самый короткий путь королевы она может пройти?
Соревнование
Получив спираль целых чисел на прямоугольной сетке, напишите функцию, которая возвращает один из кратчайших возможных путей (подсчитанных по количеству пройденных ячеек) между двумя числами в этой спиральной сетке, используя ходы шахматной королевы.
Например, от 16
до 25
:
25 10 11 12 13
24 9 2 3 14
23 8 1 4 15
22 7 6 5 16
21 20 19 18 17
Некоторые возможные пути включают в себя 16, 4, 2, 10, 25
и 16, 5, 1, 9, 25
.
правила
- На входе будут любые два натуральных числа.
- Выходными данными будет путь целых чисел (включая обе конечные точки) по спирали с использованием только ортогональных и диагональных перемещений.
- Длина пути подсчитывается по количеству пройденных клеток.
- Ваш ответ может быть программой или функцией.
- Это код гольф, поэтому выигрывает наименьшее количество байтов.
Как всегда, если проблема неясна, пожалуйста, дайте мне знать. Удачи и хорошего гольфа!
Контрольные примеры
>>> queen_spiral(4, 5)
4, 5
>>> queen_spiral(13, 20)
13, 3, 1, 7, 20
>>> queen_spiral(14, 14)
14
>>> queen_spiral(10, 3)
10, 11, 3
>>> queen_spiral(16, 25)
16, 4, 2, 10, 25
>>> queen_spiral(80, 1)
80, 48, 24, 8, 1
источник
Ответы:
APL (Dyalog Unicode) ,
5957 байтов SBCSПопробуйте онлайн!
-2 байта благодаря @ngn.
Анонимная функция, которая принимает две конечные точки в качестве левого и правого аргументов.
Ungolfed & как это работает
Королева движется по диагонали в первую очередь, поэтому достаточно предварительно рассчитать координаты каждого числа до
max(start,end)
.Алгоритм генерации координат основан на нескольких ответах на связанный вызов , но немного отличается от любого из существующих ответов:
r=1 2 3 4 5 6 7 8 9 10
n=1 1 2 2 3 3 4 4 5 5
r
поn
.1 2 3 3 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10
Затем, как только вектор координат
v
будет готов, мы можем легко конвертировать между спиральным индексом и координатами, используяv[i]
иv⍳coord
(находя первый индексcoord
вv
).источник
(⍵⊃v)-⍺⊃v
->⊃⍵⍺-.⊃⊂
(⍺⌷v)
->v[⍺]
Mathematica
615530 байтЭто создает сетку чисел, преобразует ее в график, а затем находит кратчайший путь между двумя числами, которые были введены.
UnGolfed
numberSpiral
это из Mathworld Prime Spiral . Создает спираль Улама (без выделения простых чисел).findPath
преобразует сетку чисел в график. Края являются действительными ходами ферзя на числовой сетке.Примеры
{4,5}
{} 13,3,1,7,22
{} 16,4,1,9,25
Кратчайший путь из 80 в 1 содержит 5, а не 6 вершин.
{80, 48, 24, 8, 1}
Golfed
источник
Scala (830 байт)
Строит спираль в квадратном двумерном массиве, используя четыре взаимно рекурсивных функции. Еще один рекурсивный поиск для построения списка путей.
Ungolfed
источник
Рубин,
262218216 байтЭто порт моего ответа Python . Предложения по игре в гольф приветствуются.
Edit: 45 байт благодаря Иордану и их предложениям
d=[0]*n=m*m;*e=c=0;*t=a
,.rect
,0<=>x
иx,y=(e[a]-g=e[b]).rect; t<<d[(g.real+x)*m+g.imag+y]
. Еще один байт от(x+y*1i)
до(x+y.i)
.Ungolfed:
источник
q=
из своего ответа, так как вы не учитываете его байты.c=0;e=[c];t=[a]
можно сократить до*e=c=0;*t=a
. Вы можете заменитьz=e[a]-e[b];x,y=z.real,z.imag
наx,y=(e[a]-e[b]).rect
иx+=x<0?1:x>0?-1:0
сx+=0<=>x
(то же самое дляy
). Я думаю, что это уменьшается до 229 байтов.d
сd=[0]*m*m
, затем заменитеd[c.real][c.imag]
наd[c.real*m+c.imag]
иd[e[b].real+x][e[b].imag+y]
сd[(e[b].real+x)*m+e[b].imag+y]
.t<<d[(e[b].real+x)*m+e[b].imag+y]
можно сократить доu,v=e[b].rect;t<<d[(u+x)*m+v+y]
.d=[0]*m*m
вd=[0]*n=m*m
и(m*m).times
кn.times
. Это 219.x,y=(e[a]-e[b]).rect
наx,y=(e[a]-g=e[b]).rect
, удаливu,v=e[b].rect
и изменивt<<d[(u+x)*m+v+y]
наt<<d[(g.real+x)*g.imag+v+y]
(в основном возвращая мой второй к последнему комментарию).Python 3, 316 байт
Этот ответ смотрит на координаты
a
иb
на спирали (используя комплексные числа) и добавляет сначала диагональные движения, затем ортогональные движения.Ungolfed:
источник