Знаете ли вы, что небольшое число может позаимствовать биты у большего числа? Вот пример. Допустим, наши два числа 5 и 14. Сначала запишите их в двоичном виде:
5 14
000101 001110
Сначала мы берем наименьшее на бит от большего числа, и мы даем его наименьший от бита на другой номер. Так
This bit turns off
|
v
000101 001110
^
|
This bit turns on
Теперь у нас есть
000111 001100
и наши числа 7 и 12. Первое число все еще меньше, поэтому мы продолжим.
000111 001100
001111 001000
Теперь у нас 15 и 8, поэтому мы можем остановиться. Мы назовем этот набор операций «заимствование битов» двумя числами. Давайте сделаем еще один пример. 20 и 61.
20 61
010100 111101
010101 111100
010111 111000
111111 100000
63 32
Таким образом, наш конечный результат 32, 63. Давайте сделаем еще один . 31, а 12. 31 уже больше 12, так что ничего не поделаешь! Заимствование битов 31 и 12 дает 31 и 12, без изменений.
Соревнование
Ваша задача - написать программу или функцию, которая принимает два числа и заимствует их. Два числа всегда будут положительными целыми числами. Ваш ввод и вывод могут быть в любом разумном формате.
Тест IO:
Input: 2, 3
Output: 3, 2
Input: 3, 2
Output: 3, 2
Input: 8, 23
Output: 31, 0
Input: 42, 81
Output: 63, 0
Input: 38, 41
Output: 47, 32
Input: 16, 73
Output: 23, 0
Input: 17, 17
Output: 17, 17
Применяются стандартные лазейки, и выигрывает кратчайший ответ в байтах!
Python, 42 байта
Спасибо @ jimmy23013 за 4 байта в гольфе! Спасибо @LeakyNun за игру в 2 байта!
Проверьте это на Ideone .
источник
Mathematica, 46 байтов
Тот же метод, который использовался в моем решении в J.
Спасибо @ Martin за сохранение 1 байта и напоминание мне о приложении инфикса
~
.использование
Входные данные состоят из двух целочисленных аргументов, а выходные данные представляют собой список с заимствованными битами значениями.
источник
#//.{x_,y_}/;x<y:>{BitOr[x,x+1],BitAnd[y,y-1]}&
(может быть, у вас есть идея, как сократить это время)/.
и условие/;
. Хотелось бы, чтобы Mathematica могла переключаться между логическим и битовым, проверяя типы аргументов to&&
и тому подобное.Pyth,
292725222120191816 байтТестирование.
источник
05AB1E,
1615 байтПопробуйте онлайн
источник
Лабиринт ,
3734 байтаПопробуйте онлайн!
объяснение
Быстрый лабиринтный праймер:
Программа использует тот же алгоритм, что и другие ответы: мы заменим
(a, b)
с(a | a+1, b & b-1)
тех пор , какa < b
. Я добавлю полное объяснение после того, как попробую еще поиграть в гольф.IP начинается в верхнем левом углу, идет вправо.
?
считывает целое числоa
. Тогда"
не работает, но необходимо предотвратить немедленное снижение IP-адреса. Это также тупик, поэтому IP поворачивается и?
снова выполняет чтениеb
.}
затем переходитb
от основного к вспомогательному , так что теперь у нас есть:|
Тогда ничего не делает, потому что он принимает побитового ИЛИ отa
и0
. Поскольку мы знаем,a
что всегда положительно, IP поворачивает на восток (потому что он не может повернуть на запад). Начинается основной цикл программы. Мы начнем с короткого линейного сечения, чтобы сравнитьa
иb
:IP сейчас на другом перекрестке. Сначала рассмотрим случай, когда результат положительный. Это значит,
b > a
и нам нужно выполнить еще одну итерацию. Эта итерация также полностью линейна. Обратите внимание, что стеки в настоящее время:И затем мы возвращаемся к началу цикла (так
a
как снова положительный, IP снова поворачивает на восток).Если в какой-то момент
b-a
более не является положительным, IP выберет один из двух других путей. Обратите внимание , что в обоих случаях мы забираемa
с{
, а затем врезался в угол , где IP следует изгиб , а затем распечататьa
с!
. Теперь вершина стека снова,b-a
что означает, что в обоих случаях IP будет в конечном итоге двигаться на восток. Все, что осталось, это короткий линейный бит:источник
Java 7, 73 байта
Ungolfed и тестовые случаи:
Попробуй это здесь.
Выход:
Старые правила вызова [
126125123 байта]:ПРИМЕЧАНИЕ. В старых правилах вызова вместо двух свободных целых чисел использовались два целочисленных массива.
источник
while
петлю, как этоfor(;x<y;x|=x+1,y&=y-1);
-_-
Я хотел бы написать это лучше с самого начала. К счастью, это не является необоснованным или радикальным изменением. Кроме того, да, я не комментировал каждый ответ, но я информировал каждого пользователя. Мне не хотелось информировать одного и того же пользователя несколько раз. Я не прокомментировал пост Денниса, но это потому, что он был одним из пользователей, который поощрял меня изменить его изначально.JavaScript (ES6), 33 байта
Простой порт ответов @miles.
источник
f=
начале: PЮлия, 27 байт
Попробуйте онлайн!
Как это устроено
Мы определяем бинарный оператор
<|
для наших целей. Он не определен в последних версиях Julia, но все еще распознается синтаксическим анализатором как оператор. Хотя\
(не определено явно для целых чисел) на один байт короче, его высокий приоритет потребует заменыx|-~x<|y&~-y
на(x|-~x)\(y&~-y)
, увеличивая таким образом число байтов.<|
проверяет, является ли его первый аргумент строго меньше, чем второй. Если это так, он рекурсивно вызывает себя с аргументами x | - ~ x = x | (x + 1) и y & ~ -y = y & (y - 1) .Поскольку добавление 1 к x переключает все завершающие биты и самый младший неустановленный бит, x | (x + 1) переключает младший неустановленный бит (и никаких других битов). Аналогично, поскольку вычитание 1 из y переключает все завершающие невыбранные биты и самый низкий установленный бит, y & (y + 1) переключает самый низкий установленный бит.
Наконец, когда неравенство x <y больше не выполняется,
<|
возвращается пара [x, y] .источник
MATLAB,
6766 байтцикл:
рекурсивный (67 байт):
Такой же подход к изменению битов, как и многие другие ответы.
источник
Clojure, 63 байта
Тот же метод, который используется в моем решении в J.
использование
источник