Это вызов, вдохновленный вращением Чебышева . Я предлагаю посмотреть на ответы там, чтобы получить вдохновение для этого вызова.
Для данной точки на плоскости существует уникальный квадрат (прямоугольник с равными сторонами), который центрируется в начале координат и пересекает эту точку ( интерактивная демонстрация ):
Для заданной точки p и расстояния d верните точку, полученную путем перемещения расстояния d от p против часовой стрелки (и по часовой стрелке для отрицательного значения d ), по периметру квадрата с центром в начале координат, пересекающем p . Ваш ответ должен быть точным как минимум до 4 десятичных цифр.
Testcases:
(0, 0), 100 -> (0, 0)
(1, 1), 81.42 -> (-0.4200, 1.0000)
(42.234, 234.12), 2303.34 -> (-234.1200, 80.0940)
(-23, -39.234), -234.3 -> (39.2340, -21.8960)
Следующие тестовые примеры взяты из оригинальной задачи Мартина Эндера, и все они с d = 1 :
(0, 0) -> (0, 0)
(1, 0) -> (1, 1)
(1, 1) -> (0, 1)
(0, 1) -> (-1, 1)
(-1, 1) -> (-1, 0)
(-1, 0) -> (-1, -1)
(-1, -1) -> (0, -1)
(0, -1) -> (1, -1)
(1, -1) -> (1, 0)
(95, -12) -> (95, -11)
(127, 127) -> (126, 127)
(-2, 101) -> (-3, 101)
(-65, 65) -> (-65, 64)
(-127, 42) -> (-127, 41)
(-9, -9) -> (-8, -9)
(126, -127) -> (127, -127)
(105, -105) -> (105, -104)
Ответы:
Python 2,
363335296266262258256233 байтаВу, 130 байтов потеряно! Спасибо Нейлу за сохранение 4 байта, Натану Мерриллу за сохранение 2 байта и xnor за сохранение нелепых 23 байтов!
Общая идея такова: мы можем уменьшить пройденное расстояние, взяв его модуль по периметру квадрата. Периметр определяется как 8-кратное наибольшее из двух координат, поскольку точка должна опираться на него. Затем, после того, как модуль взят, мы гарантируем отсутствие перекрытия. Это также гарантирует, что мы должны двигаться только против часовой стрелки, поскольку модуль дает положительный результат.
Оттуда я просто использую то, что мы знаем по заданным координатам x и y, чтобы выяснить, где мы находимся: сверху, снизу, слева, справа или в углу, и определить направление, которое может быть одним из
0, 1, 2, 3
:После этого это так же просто, как зацикливание, пока у нас еще есть расстояние для перемещения, и на основе направления, которое мы вычитаем или добавляем к соответствующей координате, и сообщаем циклу, в каком направлении мы движемся дальше.
Хотя довольно долго, это, безусловно, работает. Вот несколько примеров ввода / вывода:
Попробуйте онлайн или запустите контрольные примеры .
источник
s=max(x,y,-x,-y)
?(s>0)*(d>0)
естьs>0<d
. Выход может быть"%.4f "*2%tuple(p)
.if s:d=d%(8*s)
может бытьd%(s*8or 1)
.(r+1)
может быть~-r
.1*(x>-s)
может быть просто(x>-s)
.abs(y)==abs(x)
может бытьy*y==x*x
(x>-s)
не нужны скобки и~-r
декременты, поэтому я использовал-~r
.JavaScript (ES6), 147 байт
Объяснение: Работает, пытаясь добавить вектор направления, не выходя за границы квадрата. Любое превышение рекурсивно передается назад с направлением, повернутым против часовой стрелки на 90 °. Направление фактически кодируется с использованием вертикального флага
v
и единицы измерения,w
так что векторы (1, 0), (0, 1), (-1, 0) и (0, -1) кодируются сv
0, 1, 0 1 иw
1, 1, -1, -1 соответственно. Вектор направления может изначально не указывать в подходящем направлении, но он никогда не будет указывать назад, поэтому в конечном итоге он будет вращаться в полезном направлении.источник
f(42.234, 234.12, 2303.34) -> [-234.12, 80.09399999999988]
означающая, что он не имеет 4-значной точности. Может быть, добавление выходного форматирования исправит это? Хороший ответ, хотя! :)