Описание задания
Дано целое число, поменять местами его (2k – 1) -й и 2k-й младшие значащие биты для всех целых чисел k> 0 . Это последовательность A057300 в OEIS.
(Предполагается, что число имеет «бесконечно много» ведущих нулей. На практике это просто означает добавление одиночного 0-битного числа к нечетной длине.)
Это код-гольф , поэтому выигрывает самый короткий код (в байтах).
Контрольные примеры
0 -> 0
1 -> 2
9 -> 6
85 -> 170
220 -> 236
1827 -> 2835
47525 -> 30298
unsigned char array_of_bytes[1024]
работать так, как вы ожидаете (т.е. быть битовым полем с 1024 *CHAR_BIT
записями). Я предполагаю, что большинство ответов, поддерживающих ввод произвольной длины, предположили бы, что оноCHAR_BIT
было четным, поскольку сдвиг битов между байтами громоздок. Таким образом, вы абсолютно можете поставить требование поддерживатьk
до некоторого постоянного размера, например, 256 или что-то более разумное для AES, и языки без 256-битных целочисленных типов должны будут использовать циклы. Это может сделать векторы SIMD достойными внимания при ответе на ассемблер x86: PОтветы:
Желе ,
1097 байтПопробуйте онлайн! или проверьте все контрольные примеры .
Как это работает
источник
Python 2, 26 байт
Немного хитрости!
Скажем,
n
имеет форму...ghfedcba
в двоичном виде . Затем мы можем разделить его на любой другой бит, какТогда результат с битовой коммутацией
s
может быть выражен какs=2*o+e
.Мы бы предпочли вычислить только один из
e
иo
, поэтому мы выражаемo=n-2*e
и подставляемИтак, теперь осталось выразить
e
в терминахn
. НомерM=4**n/3
имеет...10101010101
двоичную форму , которая служит маской для нечетных цифр. Показательn
гарантирует, чтоM
это достаточно долго. Принимая побитовоеand
из ,n/2
и это значение даетe
по желанию.Вместо этого мы можем выразить
e
в терминахo
e=(n-o)/2
, который даетs=(n+o*3)/2
, который сохраняет байт благодаря оптимизации из xsot.источник
n
. Тем не менее, я предпочитаю противоположное «нечетное» и «четное» соглашение об именовании битов. LSB - это бит 0, который является четным (даже если это первый бит). В SIMD-программировании, где тасования часто выбирают элементы с индексом, индексы считаются от 0, поэтому считается, что младший элемент является четным элементом. например[ 3 2 1 0 ]
lambda n:n+(n&4**n/3)*3>>1
f(x){return x+((x&~0U/3)*3)>>1;}
возвращает 1 для входа 2 .calc
(aka apcalc), а не в C. Я думал, что все будет в порядке, так как мне не нужно усечение до 32-бит или дополнения до двух. Я не думал, что выражение выглядело правильно, поэтому я был готов поверить своим неправильным тестам. Но в любом случае мне нужен лучший REPL для разработки битхаков. Какие-либо предложения? (в идеале командная строка Linux, какbc -l
илиcalc
, но фактически выставляетint32_t
/uint32_t
или что-то, а не расширенную точность.)Функция С, 38
Бит-вертел:
Ideone.
Или для удовольствия:
С рекурсивная функция, 43
Согласно формуле OEIS ,
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
или
Ideone.
источник
CJam,
161413 байтПроверьте это здесь.
объяснение
источник
Pyth, 9 байт
Попробуйте это в Pyth Compiler .
Как это работает
источник
JavaScript (ES6),
3230 байтРаботает только до 1073741823 из-за ограничений целых чисел JavaScript.
3836 байт работает до 4294967295:Редактировать: 2 байта сохранены благодаря @ user81655.
51 байт работает до 4503599627370495:
источник
n<<1
бытьn*2
?n/2
тоже могу использовать ! Я не знаю, почему я не думал об этом раньше.>>>
... что это?>>>
но это делает беззнаковый сдвиг.>>>0
в основном преобразуется в 32-разрядное целое число без знака.Функция x86 asm: 14 байт машинного кода
версия uint64_t: 24 байта
x86-64 Соглашение о вызовах SysV (
x
inedi
), но этот же машинный код также будет работать в 32-битном режиме. (Гдеlea
будет декодировать какlea eax, [edi + eax*2]
, что дает идентичные результаты ).0x4f - 0x40
= 14 байтЭто вывод компилятора из использования превосходной идеи xnor-one-mask в обратном направлении. (И противоположная терминология: младший бит - это бит 0, который является четным, а не нечетным.)
Я не нашел никаких улучшений по сравнению с тем, что делает компилятор. Я мог бы написать это как
mov eax, 0x555...
/and eax, edi
, но это такая же длина.Эта же функция для 64-битных целых чисел занимает 24 байта (см. Ссылку на Godbolt). Я не вижу способа короче 10 байт
movabs rax, 0x55...
для генерации маски в регистре. (div
Инструкция x86 неуклюжа, поэтому беззнаковое деление всех на 3 не помогает.)Я придумал цикл для генерации маски в rax, но он составляет 10 байтов (точно такой же длины, что и
mov imm64
).Если бы мы знали, что ни один из существующих байтов не
rax
имеет своих младших битов, мы могли бы пропуститьxor
, и это было бы длиной 8 байтов.В предыдущей версии этого ответа был 10-байтовый цикл с использованием
loop
insn, но он имел наихудшее время выполнения0xFFFFFFFFFFFFFF08
итераций, потому что я только установилcl
.источник
Оазис , 17 байт (не конкурирующий)
Попробуйте онлайн!
Оазис - это язык, разработанный Аднаном, который специализируется на последовательностях.
В настоящее время этот язык может делать рекурсивные и закрытые формы.
Мы используем эту формулу:
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
Указать базовый случай просто:
3120
в конце просто означает, чтоa(0)=0, a(1)=2, a(2)=1, a(3)=3
.источник
MATL , 10 байт
Попробуйте онлайн!
Модифицированная версия для генерации первых членов последовательности ( OEIS A057300 ).
объяснение
источник
зш, 28 байт
Принимает ввод в качестве аргумента командной строки, выводит на STDOUT.
Он не совместим с Bash, поскольку использует специфический для zsh синтаксис базового преобразования.
источник
Сетчатка, 70 байт
Тестирование. (Слегка изменено.)
Ну просто ради интереса: 7 байт
Принимает base-4 в качестве входа и выводит как base-4.
Попробуйте онлайн!
источник
05AB1E, 8 байтов
Спасибо @Adnan за -5 байтов!
Использует кодировку CP-1252.
Попробуйте онлайн!
Объяснение:
источник
1 2‚2 1‚
с12Â
8 байт.4в2‰íJJC
C
323029 байтАлгоритм скопирован из комментария xsot к ответу xnor на Python . Вместо маскировки в обе стороны, маскируйте в одну сторону и комбинируйте.
Это компилируется в тот же asm, что и в последней версии, которую я тестировал , и работает (для x до
0x3FFFFFFF
и для x выше, если бит 30 не установлен, см. Ниже). В машинном коде это та же длина, что и в моем существующем ответе asm.Вышеприведенная версия всегда очищает старший бит результата . Лучшая безопасная версия - 32 байта:
В версии Python такой проблемы нет, поскольку при необходимости python использует целочисленные типы произвольной точности вместо усечения до фиксированного верхнего предела.
источник
>>
был такой низкий приоритет. Я не играю в гольф достаточно часто, чтобы точно помнить, каковы правила, так как предупреждения компилятора, предлагающие парены в опасных случаях, спасают меня в реальном коде. : PJavascript (ES6),
113109 байтСохранено 4 байта благодаря Upgoat
Как это работает
источник
+('0b"+binary_string_here)
вместо `parseInt (..., 2)J, 20 байт
использование
Где
>>
STDIN и<<
STDOUT.Ungolfed
Три вилки.
Примечание
В официальном переводчике
^:_1
можно заменитьinv
, сохранив 1 байт.Однако ни один из онлайн-переводчиков не реализует это.
источник
C #, 44 байта
На основе реализации C
int f(int n)=>n>3?4*f(n/4)+f(n%4):n%2*2+n/2;
Попробуйте это здесь: C # pad
источник
INTERCAL , 60 байтов
Попробуйте онлайн!
Работает для 16-разрядных целых чисел, при этом ввод / вывод выполняется в наиболее естественном формате для INTERCAL: входные данные представляют собой последовательность десятичных цифр, написанных на одном из нескольких естественных или составных языков, а выходные данные представлены «разделенными римскими цифрами».
Это одна из тех редких проблем, когда бинарные операторы INTERCAL могут фактически использоваться вообще интуитивно, поскольку биты перемещения - это то, о чем они все. Select (
~
) берет биты из своего первого аргумента, соответствующие единицам в своем втором аргументе, и дополняет их нулями справа, а mingle ($
) перемежает биты из своих аргументов так, чтобы биты из первого аргумента были более значимыми. Таким образом, простое решение состоит в том, чтобы выбрать менее значимые чередующиеся биты (.1~#21845
), выбрать более значимые чередующиеся биты ().1~#43690
) и чередовать их вместе в обратном порядке. К счастью для подсчета байтов, хотя операторы INTERCAL не имеют определенного приоритета (так как целью языка является отсутствие прецедентов), получается, что C-INTERCAL в TIO не требует большой группировки для этого конкретного выражения, поскольку стоит всего один байт, так как'.
может быть сокращено!
.С поддержкой 32-битных целых чисел:
INTERCAL , 67 байт
Попробуйте онлайн!
INTERCAL не допускает 32-битные литералы, что на самом деле делает это немного легче для чтения, так как это означает, что магические константы для выбора чередующихся битов должны создаваться путем смешивания двух 16-битных литералов вместе, где один - все нули, а другой - все. (На самом деле, даже если бы были 32-битные литералы, это все равно было бы короче.
#0$#65535
Это два байта#1431655765
, и то же самое относится и к другому.) Это неестественно хорошо передает весь процесс для INTERCAL.Альтернативный подход с неуклюжим использованием перегрузки операндов :
INTERCAL , 71 байт
Попробуйте онлайн!
Это избавляет от выбора вообще, объявив , что
:1
будет.2
смешивался с.3
, установив:1
на вход, а затем выводит.3
смешанный с.2
. Так как:1
был перегружен как.2$.3
,DO :1 <- :2
присваивает значения.2
и так.3
, что:1
получает значение:2
, что приводит к тому , что.2
содержат более значимые чередующиеся биты из:2
и.3
содержат менее значимые чередующиеся биты. Это было бы меньше двух 32-битных решений на четыре байта, если ихPLEASE WRITE IN :1
можно было бы заменитьPLEASE WRITE IN :2 DO :1 <- :2
на перегруженные:1
, ноCALCULATING
оказывается необходимым для использования перегрузки. Я также чувствую, что может быть какой-то более короткий способ выполнить саму перегрузку, чем запуск программыDO:1<-:1/.2$.3
, но так как это INTERCAL, я также чувствую, что этого не может быть.источник
Mathematica, 44 байта
Тот же подход, что и в моем ответе на CJam: конвертировать в base-4, менять местами 1 и 2, конвертировать обратно. Он также использует трюк алефальфы, чтобы заменить
FromDigits
наFold
операцию, чтобы сохранить один байт.источник
На самом деле, 16 байтов
Попробуйте онлайн!
Объяснение:
источник
J, 22 байта
Альтернативный подход, основанный на манипулировании массивами вместо базового трюка.
использование
объяснение
источник
REXX, 88 байт
источник