Ваша цель состоит в том, чтобы реализовать операцию умножения XOR (без переноса ), определенную ниже, как можно меньше байтов.
Если мы думаем о побитовом XOR ( ^
) как двоичное добавление без переноса
101 5
^ 1001 9
----
1100 12
5^9=12
мы можем выполнить умножение XOR @
, выполнив двоичное длинное умножение, но выполнив шаг сложения, не перенося как битовое XOR ^
.
1110 14
@ 1101 13
-----
1110
0
1110
^ 1110
------
1000110 70
14@13=70
(Для математиков это умножение в кольце многочленов F_2[x]
, отождествление многочленов с натуральными числами путем оценки в x=2
качестве многочлена над Z.)
Умножение XOR коммутирует a@b=b@a
, связывает (a@b)@c=a@(b@c)
и распределяет по битовому XOR a@(b^c)=(a@b)^(a@c)
. Фактически, это уникальная такая операция, которая соответствует умножению в a@b=a*b
любом случае a
и b
является степенью 2
подобия 1,2,4,8...
.
Требования
Возьмите два неотрицательных целых числа в качестве входных и выходных или напечатайте их XOR-произведение. Это должны быть числа или их десятичные строковые представления, а не их двоичные расширения. Побеждает несколько байтов.
Не беспокойтесь о целочисленных переполнениях.
Вот несколько тестовых случаев в формате a b a@b
.
0 1 0
1 2 2
9 0 0
6 1 6
3 3 5
2 5 10
7 9 63
13 11 127
5 17 85
14 13 70
19 1 19
63 63 1365
PCLMULQDQ
из расширения CLMUL. К сожалению, я получил отрицательный отзыв за свои знания о наборе команд x86 (связан сPEXT/PDEP
), поэтому я оставлю это здесь в качестве комментария.Ответы:
машинный код x86: 7 байт
Всего две инструкции.
pclmulqdq
делает тяжелую работу, он буквально реализует этот тип xor-умножения.ret
чтобы сделать его вызываемой функцией, надеюсь, удовлетворяющей требованию «вывода» результата (в возвращаемом значении,xmm0
). Помещать в аргументы целочисленные аргументыxmm
немного необычно, но я надеюсь, вы меня простите.источник
Z80, 11 байт
Код вызывается как функция.
a
иb
находятся вD
иE
(порядок не имеет значения), и ответ сохраняется вA
момент возврата кода (функции ввода / вывода отсутствуют).Он выдает правильные результаты для всех входных данных теста, кроме тех,
63@63
которые возвращаются,85
потому что все регистры 8-битные и 1365 mod 256 = 85 (целочисленное переполнение).источник
C,
4438 байтБлагодаря nimi мы теперь используем рекурсию на 6 байтов меньше!
Мы определяем функцию
f
, которая принимаетa
,b
.Это можно назвать так:
Какие выводы:
13 @ 14 = 70
Попробуйте тестовые случаи онлайн !
источник
f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}
?(b&1)
с ,b%2
чтобы сохранить еще два байта , так как%
имеют одинаковый уровень приоритета слева направо , как*
.Pyth,
1312 байтДемонстрация.
Старая версия, 13 байт:
Демонстрация.
источник
vz
двух целочисленных входных данных.CJam,
1413 байтовКак это работает :
Сначала мы получаем длинные результаты умножения, а затем работаем, начиная с двух нижних пар.
Попробуйте онлайн здесь
источник
J, 14 байт
Использование:
Пояснение (чтение в основном справа налево
u
иv
обозначение произвольных функций):u&.#:
применяетсяu
к векторам двоичных представлений входных чисел, а затем возвращает результат обратно в целое число (u&.v == v_inverse(u(v(input_1), v(input_2)))
)*/
продукты (*
) входов в продукт Декарта (/
) двух двоичных векторовv(u@)
применитьu
кv
(продукту Декарта)u/.
подать заявлениеu
к каждой анти-диагонали произведения Декарта (анти-диагонали представляют 1-ю, 2-ю, ... цифру в двоичном представлении)~:/
уменьшить (/
) анти-диагональ с операцией XOR (~:
)Попробуйте это онлайн здесь.
источник
Python 2, 35 байт
Звоните как
f(13, 14)
. Я думаю, что большинство языков с подобной конструкцией сходятся на чем-то подобном.источник
Ява, 62
расширенный
источник
for(;i<32;)
чтобыwhile(i<32)
? Они одинаковой длины, но второй кажется более естественным способом написания.i++
изначально был вfor
курсе и получил гольф на свое нынешнее место. Такwhile
как не меньше, нет причин менять его.Haskell, 50 байтов
Перевод ответа C на BrainSteel. Пример использования:
источник
Perl - 35 байт
Считать параметр командной строки как единое целое. Входные данные взяты из
STDIN
пробела.Пример использования:
источник
Юлия,
353330 байтЭто создает рекурсивную функцию,
f
которая принимает два целых числа и возвращает произведение XOR входных данных.Ungolfed:
Сохранено пару байтов с поддержкой от Sp3000!
источник
Python 2,
104917866 байтВозьмите биты
b
в обратном порядке, заканчивая до того, как вы нажмете'0b'
на начало строки. Умножение каждый из них с помощьюa
иxor
с общим, а затем левым сдвигомa
. Затем распечатайте итог.источник
Go, 63 байта
Полный пример:
http://play.golang.org/p/-ngNOnJGyM
источник
GAP , 368 байт
Конечно, давайте сделаем это! (это всего лишь лёгкая игра в гольф, смысл был больше двигаться в F 2 [x] и делать вычисления больше, чем любая попытка быть выигрышной)
Вот код
Вот негольфированный код с объяснением:
Итак, во-первых, мы создадим одномерное кольцо многочленов над полем F 2 и назовем его
R
. Обратите внимание, чтоGF(2)
это F 2 в GAP.Далее мы собираемся присвоить переменную GAP
x
неопределенному кольцуR
. Теперь, когда я говорюx
в GAP, система будет знать, что я говорю о неопределенности кольцаR
.Далее у нас есть две функции, которые являются обратными отображениями друг друга. Эти карты обе на, но они не сохраняют структуру, поэтому я не мог найти лучший способ реализовать их в GAP. Там почти наверняка есть лучший способ, если вы знаете это, пожалуйста, прокомментируйте!
Первая карта
to_ring
берет целое число и отображает его в соответствующий элемент кольца. Он делает это с помощью преобразования в двоичный алгоритм, где все,1
что должно появиться в двоичном коде, заменяется на «x^n
где»n
- подходящая степень, которую 2 взяла бы, если бы число было действительно двоичным.Следующая функция полностью изменяет это.
to_ints
берет элемент ring и отображает его в соответствующее ему целое число. Я делаю это, получая список коэффициентов полинома, и для каждого ненулевого коэффициента результат увеличивается на 2 ^ n, так же, как мы конвертируем двоичный код в десятичный.На последнем этапе мы вызываем эти функции. Мы берем два целочисленных ввода, преобразуем их в элементы в кольце
R
, затем умножаем эти элементы вместе и отправляем произведение обратно в целые числа.источник
Рубин,
767573 байтаRuby, 60 байт (только функция, без ввода / вывода)
источник
Mathematica, 40 байт
источник
f@@{a,b,c,d}
=f[a,b,c,d]
. reference.wolfram.com/language/ref/Apply.htmlДротик,
3432 байтаПрямая рекурсивная реализация.
источник
гнуплот, 29 байт
так же, как в дартс (см. выше)
источник
GNU Assembler (x86_64 Mac OS X), 97 байт
Это правильная функция, которая может быть вызвана из C:
& может быть протестировано с помощью этой программы на C:
Обратите внимание, что в Mac OS X вы должны использовать его
clang -x c
для компиляции как C, а не C ++.Для Linux (если я правильно помню), код будет 95 байтов:
Как ни странно, эта версия на самом деле длиннее, чем определение функции для встроенной сборки, но эта версия была длиннее, чем у чистого решения C, которое у нас уже есть, поэтому я решил попробовать сборку.
редактировать
Если это посчитано собранным размером (исключая любые этикетки & c.), То это
Ассемблер x86_64, 22 байта:
источник
Golflua 68
В основном делает то же битовое смещение, что и ответ Ypnypn на Java , но, похоже, для правильной работы требуется деление на 2 в конце. Принимает значения как stdin, примеры ниже
источник
Цейлон, 90 байт
Это только что описанный алгоритм: умножьте
a
на тот,2^i
где установленi
бит thb
, и сложите их все вместе, используя xor. Перебирает0:64
потому что целые числа являются 64-битными в Цейлоне при работе на JVM (ниже при запуске в качестве Javascript, но затемb.get(i)
просто возвращает false)отформатирован:
Псевдоним хранит здесь только один байт.
источник
(неконкурентный) желе, 16 байтов
Попробуйте онлайн!
источник