Фон
Если вы много играете в код, вы, вероятно, знаете о побитовой операции XOR . Учитывая два целых числа, оно дает другое целое число с 1
s в битах, где два входа различаются. Так, например 1010 XOR 0011 = 1001
.
Это оказывается очень полезным в теории игр, где она более известна как «nim sum». Если у вас есть сумма двух игр (то есть вы делаете ходы в одной игре за раз), значение позиции - это минимальная сумма значений позиций в каждой отдельной игре.
Но мы можем сделать еще один шаг вперед. С добавлением nim и соответствующим определением умножения nim мы можем сформировать поле из неотрицательных целых чисел. Таким образом, задача состоит в том, чтобы умножить игру в гольф.
Определение
Умножение Nim подчиняется следующим правилам:
Произведение nim 2-степени Ферма n = (2 ^ (2 ^ k)) с любым меньшим числом является обычным произведением.
Произведение nim n-степени Ферма n само по себе равно 3n / 2.
Умножение Нима распределяется по сложению Нима.
Умножение по Nim коммутативно и ассоциативно (как и сложение по nim).
Мультипликативная идентичность равна 1 (а аддитивная идентичность равна 0).
Любое неотрицательное целое число может быть записано как сумма nim различных степеней двойки, а любая степень два может быть записана как произведение различных чисел Ферма, поэтому этого достаточно для определения умножения nim для всех неотрицательных целых чисел.
пример
Все это было довольно абстрактно, поэтому давайте рассмотрим пример. Я буду использовать +
для обозначения nim сложения (XOR) и *
для умножения nim.
6 * 13
= (4 + 2) * (8 + 4 + 1)
= (4 + 2) * ((4 * 2) + 4 + 1)
= (4 * 4 * 2) + (4 * 2 * 2) + (4 * 4) + (4 * 2) + (4 * 1) + (2 * 1)
= (6 * 2) + (4 * 3) + 6 + 8 + 4 + 2
= ((4 + 2) * 2) + 12 + 6 + 8 + 4 + 2
= (4 * 2) + (2 * 2) + 12 + 6 + 8 + 4 + 2
= 8 + 3 + 12 + 6 + 8 + 4 + 2
= 15
Дополнительные тестовые случаи
4, 4 -> 6
4, 3 -> 12
4, 7 -> 10
2, 4 -> 8
2, 3 -> 1
1, 42 -> 42
Вызов
Напишите программу или функцию, которая, учитывая два неотрицательных целых числа в любой удобной форме, вычисляет их произведение nim.
Это код-гольф , поэтому выигрывает самое короткое представление.
Ответы:
Nim , 120 байт
Попробуйте онлайн!
Хорошо, это может быть сумасшествием, но кто-то должен был умножить Nim в Nim ...
Это стандартный алгоритм из Википедии. Проблема в том, что я не знаю языка, поэтому пришлось изучать основы на лету. В частности, я был удивлен , что
-=
иmin
не работает для множеств, и лучший способ мне удалось найти для извлечения минимум должен был использовать итератор и возвращает первое значение. Надеюсь, эксперты Nim помогут мне улучшить это.источник
Python 2 , 85 байт
Попробуйте онлайн!
Медленно, как черт. Вычисляет mex ({α ′ β ⊕ α β ′ ⊕ α 'β ′: α ′ <α, β ′ <β}) рекурсивно.
источник
Желе , 16 байт
Использует рекурсивную формулу xy = mex ({ay ⊕ xb ⊕ ab: a <x, b <y}) для умножения Нимбера .
Попробуйте онлайн!
Как это устроено
источник
CGSuite ,
523922 байтаНе осознавал, что имеет такие встроенные и анонимные «процедуры».
Оригинальная версия, 36 байт:
Или 25 байтов, если ввод / вывод может быть nimbers:
Ну, я надеялся
*a**b
/a*b
работал, но это не так.источник
Pyth , 21 байт
демонстрация
Используется минимальная исключаемая формулировка элемента умножения nim, как указано здесь .
Две вложенные карты используются для перебора всех меньших значений (
mm ... GH
), затем результаты сглаживаются (s
). Умная часть идет сf-T ... 0
, где мы перебираем целые числа вверх от 0, чтобы найти первую, не содержащуюся в наборе, упомянутом выше. Делая это таким образом, нам не нужно вычислять верхнюю границу итерации, сохраняя несколько байтов.В конце функция
g
вычисляет произведение nim.источник
JavaScript (ES6),
142128 байтПервый шаг состоит в том, чтобы разделить оба
x
иy
на XOR степеней2
, взять их попарно продукты nim, а затем XOR результаты (потому что продукт nim распределяется по XOR). Как только мы вернулись к случаюx
иy
обеим степеням 2, отметим, что мощности Ферма умножаются друг на друга, используя обычную арифметику, поэтому мы можем разложитьx
иy
на степени Ферма. Еслиx
иy
не разделяем власть Ферма, мы можем повернуть процесс вспять и просто вернутьсяx * y
. Однако, если они делят мощность Ферма, то мы делим ихx
иy
на эту мощность вычисляем произведение nim, а затем берем произведение nim с квадратом nim этой мощности Ферма. Ungolfed:источник
Wolfram Language (Mathematica) , 81 байт
Попробуйте онлайн!
Используя формулу:
источник