Рассмотрим регулярную сетку, где каждая ячейка имеет целочисленные координаты. Мы можем сгруппировать ячейки в (квадратные) «кольца», где ячейки в каждом кольце имеют одинаковое расстояние Чебышева (или расстояние шахматной доски) от начала координат. Ваша задача - взять такую координату ячейки и повернуть эту ячейку на одну позицию против часовой стрелки внутри своего кольца. Это реализует следующее отображение:
Так, например, если ввод, (3, -2)
вы должны вывести (3, -1)
. Обратите внимание, что (0, 0)
это единственный вход, который должен отображаться на себя.
правила
Формат ввода / вывода довольно гибкий. Вы можете использовать два отдельных числа: пара / список / массив / кортеж чисел, одно комплексное число, строка, содержащая два числа и т. Д.
Вы можете предположить это -128 < x,y < 128
.
Вы можете написать программу или функцию и использовать любой из наших стандартных методов получения ввода и предоставления вывода.
Вы можете использовать любой язык программирования , но учтите, что эти лазейки по умолчанию запрещены.
Это код-гольф , поэтому самый короткий действительный ответ - измеренный в байтах - выигрывает.
Тестовые случаи
(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)
Ответы:
JavaScript (ES6),
6059 байтПринимает ввод с синтаксисом карри
(x)(y)
и возвращает массив[new_x, new_y]
.Как это работает
Наша главная задача - определить, в каком квадранте мы находимся, чтобы мы знали, в каком направлении двигаться.
Мы можем использовать эту формулу в первом приближении:
Вот что мы получаем:
Почти готово. Но нижний левый и правый нижний углы колец недействительны. Нам нужно сместить нижнюю половину матрицы на одну позицию влево, поэтому мы определяем
z
как:И мы заменим
x
сz
нашей формулой:Что приводит к:
Теперь вся матрица верна, за исключением особого случая
[0, 0]
(вообще без движения), который должен рассматриваться отдельно.Контрольные примеры
Показать фрагмент кода
источник
Желе ,
201412 байтВвод и вывод в виде массивов. Попробуйте онлайн! или проверьте все контрольные примеры .
Задний план
Чтобы выяснить, в каком направлении мы должны двигаться, мы можем наблюдать относительное положение начальной точки к биссектрисам квадранта x + y = 0 (синий) и x - y = 0 (красный).
Происхождение исправлено. Мы продвигаемся, добавляя [0, 0] к начальной точке.
Точки в самом верхнем треугольнике - включая биссектрису первого квадранта - имеют положительную сумму и неотрицательную дельту ( y - x ). Мы продвигаемся, добавляя [-1, 0] к начальной точке.
Точки в крайнем левом треугольнике, включая биссектрису второго квадранта, имеют неположительную сумму и положительную дельту. Продвигаемся, добавляя [0, -1] к начальной точке.
Точки в самом нижнем треугольнике - включая биссектрису третьего квадранта - имеют отрицательную сумму и неположительную дельту. Мы добавляем [1, 0] к начальной точке.
Точки в самом правом треугольнике, включая биссектрису четвертого квадранта, имеют неотрицательную сумму и отрицательную дельту. Мы продвигаемся, добавляя [0, 1] к начальной точке.
Чтобы выяснить правильное направление, мы вычисляем [-sign (x + y), -sign (y - x)] , который имеет только девять возможных результатов.
В следующей таблице показано, какие результаты должны быть сопоставлены с какими направлениями.
Это оставляет три случая.
Если хотя бы один из знаков равен 0 , [Δx, Δy] = [-sign (x + y), -sign (yx)] .
Если знаки равны и отличны от нуля, [Δx, Δy] = [-sign (x + y), 0] .
Если знаки разные и отличны от нуля, [Δx, Δy] = [0, -sign (yx)] .
Как это работает
источник
Pyth , 19 байт
Попробуйте онлайн!
Перевод моего ответа Юлии :
источник
Python, 55 байт
Обнаруживает четыре диагональных квадранта и сдвигает соответствующую координату.
источник
Haskell,
777169 байтЭто просто проверка каждого из этих наклоненных квадрантов и изменение входа соответственно. Обратите внимание, что пробелы необходимы, в противном случае, например,
>-
будет рассматриваться как оператор (который не определен).Спасибо @nimi за удаление еще нескольких байтов!
источник
,
вместо того, чтобы в&&
пределах первого охранника сохраняет байт. И тогда вы можете переключить второе сравнение-x<y
на другой байт.,
!Руби, 68
Лямбда-функция принимает комплексное число в качестве аргумента, возвращает комплексное число.
Мы поворачиваем точку на 90 градусов 4 раза, умножая на
i
. Поэтому он проходит через все 4 квадранта и будет возвращен без изменений - за исключением того факта, что мы изменяем его, когда он входит в конкретный из них. Тот факт, что он всегда изменяется в одном и том же квадранте, упрощает модификацию.Проще всего следовать, если мы изменим его,
z
когда оно находится в правом квадранте. в этом случае нам нужно увеличить координату y на 1 (т.е. добавитьi
кz
.)Мы проверяем
x.abs>=y.abs
, сравнивая квадратыx
иy
. Это говорит нам о том, что точка находится в правом или левом квадранте, а не сверху или снизу. Чтобы проверить это на самом деле в правом квадранте мы дополнительно проверить , чтоx>y
(строго больше , потому что мы хотим , чтобы исключить случай ,x=y
который относится к «верхнему» квадранту.) Если это верно , мы добавимi
кz
.По причинам, связанным с игрой в гольф, добавление
i
нежелательно. Вместо этого мы модифицируем число, когда оно находится в нижнем квадранте, и в этом случае мы должны добавить 1 кx
координате (добавить 1 кz
.). В этом случае мы проверяем,y*y>=x*x
чтобы убедиться, что оно находится в верхнем или нижнем квадранте. Чтобы в дальнейшем убедиться, что он находится в нижнем квадранте, нам нужно проверитьy<-x
(строго исключая случай с правым нижним углом, гдеy=-x
.)Преимущество этой проверки в том, что для координаты 0,0 нет особого случая. К сожалению, было обнаружено, что перемещение точки может сместить ее в другой квадрант, и это означает, что второе движение должно быть подавлено, если этот квадрант будет проверен снова, что, вероятно, сводит на нет преимущество.
Пример 1
Пример 2
В тестовой программе
схема
На следующем изображении показана (синяя) область, где
x*x>=y*y
(желтая) - область, гдеy<-x
и (зеленая) - пересечение этих областей, то есть область, где правильное преобразование представляет собой сложение 1 сz
.источник
Python, 52 байта
Комплексный ввод и вывод. Чтобы проверить, находится ли точка в нижнем диагональном квадранте, сначала поверните ее на 135 против часовой стрелки, чтобы переместить этот квадрант в (x> 0, y> 0) стандартный квадрант, и проверьте, нет ли в результате символа минус в строковом представлении. Вычитание 1 сначала учитывает граничное условие.
Если это не в том квадранте, поверните всю проблему на 90 градусов. Ввод нуля специально обрабатывается для вывода самого себя.
Другие попытки с комплексными числами:
источник
Mathematica, 34 байта
Это определяет унарный оператор,
±
который принимает и возвращает комплексное число, компоненты которого представляютx
иy
.Теперь, когда Линн представила решение для комплексных чисел, а Деннис побил мой счет, я не чувствую себя так плохо, разместив свою реализацию с привязкой к гольфу. :) (Оказывается, он практически идентичен ответу Линн.)
источник
MATL ,
1917 байтЭто использует комплексные числа в качестве ввода и вывода.
Попробуйте онлайн! Или проверьте все тестовые случаи .
объяснение
Давайте возьмем входные данные
-127+42j
в качестве примера.источник
Рубин, 51 байт
Оригинальная форма
Альтернативная форма для комментария Xnor
Используется тот же тип неравенства, что и в моем другом ответе, но по-другому.
В тестовой программе
источник
d
назначение? Похоже, вы можете просто сравнитьx*x>y*y
.y*y
и?
поэтому он точно такой же длины. Я включил это, поскольку я думаю, что ваш путь в некотором смысле аккуратнее. Я думаю, что Ruby пытается передать его как правильноеy?
имя функции.Юлия,
3834 байтаДеннис спас четыре байта. Благодарность!
Попробуйте онлайн!
источник
int(2angle(z)/pi+5)
для одного и того же числа байтов (отрицательные силы вызывают ошибку по любой причине).!z=z+(z!=0)im^...
во всех версиях.C ++, 94 байта
Ungolfed:
Использование:
Попробуйте онлайн
источник
(x>0?x:-(x))
может быть(x>0?x:-x)
.R
131 131байтФункция, которая принимает два целых числа в
x,y
качестве входных данных и записывает выходные данные в стандартный вывод. Решение соответствует схеме управления потоком @Dennis, но, вероятно, может быть в гольфе.РЕДАКТИРОВАТЬ: Обновил код на основе предложений @ JDL и сохранил кучу байтов.
Ungolfed
источник
as.logical(-1)
естьTRUE
,X==0|Y==0
может стать!X|!Y
, и условиеif(X!=Y...)
может статьif(X-Y)
. Кроме того, еслиX==Y
иX!=0
тогдаY!=0
является избыточным. На самом деле, все!=0
части являются избыточными;if(X!=0)
эквивалентноif(X)
.c(x,y)
вместоcat(x,y)
.JavaScript (ES6), 57 байт (55–63 †)
Принимает массив [x, y], изменяет его на месте и возвращает его.
Как это работает
Это функция стрелок с одним параметром и
return
свободным кратким телом.Параметр немедленно деструктурированный в
x
иy
переменные.Оператор запятой объединяет несколько выражений в одно, используя результат последнего.
i
используется для различения случаев приращения и уменьшения. Когдаx
больше чемy
, мы находимся либо в нижнем, либо в правом квадранте, и нам нужно продвинуться в одном измерении (i=1
путем принуждения булево-числовое). Точно так же, когда мы находимся на отрицательной части делительной диагонали x = y . Во всех других случаях, включая происхождение, увеличение не требуется (i=0
).Мы используем несколько похожее выражение для управления тем, какой индекс массива настраивать. Когда мы увеличиваем, а не в левом или нижнем квадрантах (или когда мы не увеличиваем, а в левом или нижнем), то получится побитовое XOR,
1
и мы отрегулируем значение y . Аналогично, когда мы находимся на делительной диагонали x = -y (включая начало координат). Во всех остальных случаях индекс будет0
( х ).Когда
i
есть1
, мы добавим его к указанному значению. Когдаi
есть0
, мы вычтем 1 из значения тогда и только тогда, когда мы не в источнике. Последнее обнаруживается путемx|y
выдачи ненулевого значения, обрезается до {0, 1} с помощью логического принуждения, и отрицаниеi
позволяет нам использовать побитовое ИЛИ вместо логического (так-1
как не имеет нулевых битов, оно безопасно для модификации).Массив является последним, поэтому он будет возвращен.
тестирование
Показать фрагмент кода
† Вариации
Мы можем сохранить еще два байта, пропуская содержательное возвращаемое значение и использование только мутации ввода:
… Или мы можем пропустить входную мутацию и сделать все переменные локальными для чистой функции ценой шести байтов:
источник
JavaScript (ES6),
8076 байтисточник
Haskell, 53 байта
Принимает два числа, выводит кортеж. Если точка находится в восточной части
-x<=y<x
, увеличьте вторую координату на 1. В противном случае циклически переключайте квадранты, поворачивая входную точку на 90 градусов, вызывая функцию на ней, затем поворачивая назад.источник
Ракетка 191 байт
Ungolfed (прямой перевод указания рисунка в код без использования какой-либо промежуточной формулы):
Тестирование:
Выход:
источник
На самом деле , 16 байтов
Это берет комплексное число как ввод и выводит другое комплексное число. Предложения по игре в гольф приветствуются! Попробуйте онлайн!
Ungolfing
источник
Scala, 184 байта
Ungolfed:
Объяснение:
источник