Обратный битовый порядок 32-битных целых


21

Напишите кратчайший код, чтобы изменить порядок бит 32-разрядного целого числа.

Правила:

  1. Предполагается, что входные данные являются действительными целочисленными или строковыми эквивалентами, если ваш язык не поддерживает числовые значения (например, Windows Batch).
  2. Выходные данные должны быть действительными целочисленными или строковыми эквивалентами, если ваш язык не поддерживает числовые значения (например, Windows Batch).
  3. Только стандартная библиотека.
  4. Это может быть функция или полная программа.
  5. Ввод может быть либо из, stdinлибо в качестве аргумента функции.
  6. Вывод должен быть либо stdoutв виде возвращаемого значения.
  7. Если ваш язык имеет встроенную или стандартную библиотечную функцию, которая делает это за один шаг (например, rbitв сборке ARM), это нельзя использовать.

Примеры:

Ключ:

  1. десятичная дробь
    • двоичный
    • (задний ход)
    • перевернутый двоичный
    • десятичный вывод

Примеры:

  1. -90 (8-битный пример для демонстрации)

    • 10100110b
    • (задний ход)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (задний ход)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (задний ход)
    • 01100101100110001011001010100011b
    • 1704506019

Примечание: пропуски бесплатной игры. Если я этого не сказал, и это не одна из стандартных лазеек , то это полностью разрешено.


Что подразумевается под «упущениями» в «упущениях - бесплатная игра»?
Тодд Леман

1
Все, что прямо не указано в правилах.
Исия Медоус

Будет ли статическая таблица 16 ГБ считаться частью длины программы?
Hot Licks

@HotLicks Согласно типичной интерпретации программы, да.
FUZxxl

язык, который поддерживает только 8-битные входы, мы можем принять вход как четыре 8-битных числа?
Спарр

Ответы:


0

сборка x86, 9 байт

    xor eax, eax
    inc eax
myloop:
    shr ecx, 1
    adc eax, eax
    jnc short myloop

В байтовой форме: 33 C0 40 D1 E9 13 C0 73 FA9 байтов.


Это опять-таки ровно столько, сколько мое решение, если вы (а) соблюдаете соглашение о вызовах cdecl и (б) действительно возвращаетесь из функции.
FUZxxl

@FUZxxl Почему-то я не видел твою версию. Вы полностью правы. Я думал __fastcallи не имел ret.
Мирия

24

MMIX сборка (28 байт)

64-разрядные числа

rbit:
    SETH $1,#0102 # load matrix in 16-byte steps
    ORMH $1,#0408
    ORML $1,#1020
    ORL  $1,#4080
    MOR  $0,$1,$0 # multiplication 1
    MOR  $0,$0,$1 # multiplication 2
    POP  1,0      # return

Это собирает в:

rbit:
    E0010102 # SETH $1,#0102
    E9010408 # ORMH $1,#0408
    EA011020 # ORML $1,#1020
    EB014080 # ORL  $1,#4080
    DC000100 # MOR  $0,$1,$0
    DC000001 # MOR  $0,$0,$1
    F8010000 # POP  1,0

Как это работает?

MORКоманда выполняет матричное умножение на два 64-битовых величин , используемых в качестве два 8x8 матриц логических значений. В качестве матрицы используется логическое число с цифрами abcdefghklmnopqr 2 :

/ abcd \
| efgh |
| klmn |
\ opqr /

В MORумножают инструкции матрицы представлены их аргументами , где умножение andи сложение or. Это:

/ 0001 \      / abcd \      / opqr \
| 0010 |  \/  | efgh |  --  | klmn |
| 0100 |  /\  | klmn |  --  | efgh |
\ 1000 /      \ opqr /      \ abcd /

и, кроме того:

/ opqr \      / 0001 \      / rqpo \
| klmn |  \/  | 0010 |  --  | nmlk |
| efgh |  /\  | 0100 |  --  | hgfe |
\ abcd /      \ 1000 /      \ dcba /

что является обратным порядком битов исходного числа.

32-разрядные числа

Если вы просто хотите изменить 32-битное число вместо 64-битного, вы можете использовать этот модифицированный метод:

rbit:
    SETL   $1,#0408 # load first matrix in two steps
    ORML   $1,#0102
    MOR    $1,$1,$0 # apply first matrix
    SLU    $2,$1,32 # compile second matrix
    16ADDU $1,$2,$1
    MOR    $1,$0,$1 # apply second matrix
    POP    1,0      # return

собран:

rbit:
    E3010408 # SETL   $1,#0408
    EA010102 # ORML   $1,#0102
    DC010001 # MOR    $1,$1,$0
    3B020120 # SLU    $2,$1,32
    2E010201 # 16ADDU $1,$2,$1
    DC010001 # MOR    $1,$0,$1
    F8010000 # POP    1,0

Первое умножение матриц в основном работает так:

/ 0000 \      / 0000 \      / 0000 \
| 0000 |  \/  | 0000 |  --  | 0000 |
| 0001 |  /\  | abcd |  --  | efgh |
\ 0010 /      \ efgh /      \ abcd /

соответствующий октабайт, #0000000001020408который мы загружаем в первых двух инструкциях. Второе умножение выглядит так:

/ 0000 \      / 0001 \      / 0000 \
| 0000 |  \/  | 0010 |  --  | 0000 |
| efgh |  /\  | 0100 |  --  | hgfe |
\ abcd /      \ 1000 /      \ dcba /

Соответствующий октабайт #0102040810204080мы создаем из первой матрицы следующим образом:

SLU $2,$1,#32   # $2 = #0102040800000000
16ADDU $1,$2,$1 # $2 = $2 + $1 << 4
                     = $2 + #0000000010204080
                #    = #0102040810204080

Второе умножение является обычным делом, полученный код имеет одинаковую длину (28 байт).


1
я впервые слышу об инструкции умножения матриц на процессоре
phuclv

@ LưuVĩnhPhúc: Не умножение матриц, но VAX имел инструкцию для оценки полинома .
nneonneo

1
@nneonneo POLYИнструкция VAX - это, по сути, слияние, умножение и сложение со встроенным циклом. Подобные вещи также существуют в современных архитектурах (например, x86), но они обычно не имеют встроенного цикла для оценки всего полинома сразу.
FUZxxl

12

Сборка 80386 ( 13 12 байт)

В качестве функции в синтаксисе AT & T с использованием соглашения о вызовах cdecl.

    # reverse bits of a 32 bit word
    .text
    .globl rbit
    .type rbit,@function
rbit:
    push $32       # prepare loop counter
    pop %ecx
0:  shrl 4(%esp)   # shift lsb of argument into carry flag
    adc  %eax,%eax # shift carry flag into lsb
    loop 0b        # decrement %ecx and jump until ecx = 0
    ret            # return

Эта функция собирается в следующую последовательность байтов:

6a 20 59 d1 6c 24 04 11 c0 e2 f8 c3

Разбить на инструкции:

6a 20       push $32
59          pop %ecx
d1 6c 24 04 shrl 0x4(%esp)
11 c0       adc  %eax,%eax
e2 f8       loop .-6
c3          ret    

Это работает так: в каждой из 32 итераций цикла аргумент, который находится в 4(%esp), смещается вправо на одну позицию. Последний бит неявно сдвигается в флаг переноса. adcИнструкция добавляет два значения и добавляет значение флага переноса в результате. Если вы добавляете значение к себе, то есть %eaxфактически сдвигаете его влево на одну позицию. Это делает adc %eax,%eaxудобный способ сдвига влево %eaxна одну позицию, в то же время сдвигая содержимое флага переноса в младший бит.

Я повторить этот процесс 32 раз , так что все содержимое 4(%esp)сбрасывается в %eax. Я никогда явно не инициализирую, %eaxпоскольку его предыдущее содержимое перемещается во время цикла.


+1 Спасибо за ваше последнее предложение, теперь это очевидно, но я пропустил это.
edc65

1
Я всегда рад видеть здесь решения по сборке :)
user1354557

8

С    63    52   48

Оригинальная версия:

int r(int n){int r=0,i=32;for(;i--;r=r<<1|n&1,n>>=1);return r;}

Обновленная версия (с изменениями, предложенными Allbeert , es1024 и Dennis ):

r(n){int r,i=32;for(;i--;r=r*2|n&1,n>>=1);return r;}

Примечание. Поскольку во второй версии не задано значение r=0, в коде предполагается, что значение int32 бита. Если это предположение ложно, функция, скорее всего, даст неправильный результат, в зависимости от начального состояния при rвходе в функцию.


Окончательная версия (с дальнейшими изменениями, предложенными Денисом и Алхимиком ):

r(n,r,i){for(;32-i++;r=r*2|n&1,n>>=1);return r;}

Примечание: это помещает объявление рабочих переменных rи iв список параметров. Параметры следующие: nэто число, которое должно быть инвертировано в битах. rи iрабочие переменные, которые должны быть переданы как 0.


1
Вы можете удалить intтип функции, а также изменить его return rна что-то вроде, i=rтак как большинство компиляторов Си, как правило, оставляют результат последней операции в регистре возврата. Он работал на gcc и cl для меня.
Allbeert

1
Вы можете сбрить еще 4 байта, используя r(n){...}вместоr(int n){...}
es1024

2
@FUZxxl вы не можете опускать intв , int r=0,i=32;если вы не переместите их из тела функции.
es1024

1
@FUZxxl: Не надо комментировать, когда я устал ... Арифметический сдвиг и деление не эквивалентны; последний округляется к нулю, а первый - к отрицательной бесконечности. -1 >> 1является -1для AS и 2**31 - 1для LS, в то время как -1 / 2это 0.
Деннис

1
@ Тодд: Любая причина, которую вы не определили rи в iкачестве аргументов? Сохранит еще три байта ...
Деннис

5

Юлия 0,2, 33 байта

f(n)=parseint(reverse(bits(n)),2)

Делает то, на что это похоже.

bitsдает вам представление битов (с учетом дополнения до двух). parseintне заботится о дополнении до двух, но возвращает 32-битное целое число, поэтому дополнение до двух просто обрабатывается переполнением.

Согласно журналам изменений, parseintв Julia 0.3 было добавлено обнаружение переполнения , поэтому это может больше не работать.


5
Это производственный код, а не код для игры в гольф! xD Я думаю, Джулия просто великолепна.
cjfaure

4

Python 2, 50

print int("{:032b}".format(input()%2**32)[::-1],2)

Во многом так же, как мое решение Pyth. Возьмите входной мод 2 ** 32, преобразуйте его в 32-разрядный двоичный файл с двоичными данными, переверните, преобразуйте двоичный код обратно в десятичный и напечатайте.


4

CJam, 15 байтов

li4H#+2bW%32<2b

Попробуйте онлайн.

Используется джокер «Свободная игра»: на выходе всегда будет целое число без знака .

Контрольные примеры

$ cjam reverse32.cjam <<< 486; echo
1736441856
$ cjam reverse32.cjam <<< -984802906; echo
1704506019

Как это устроено

li   " Read from STDIN and cast to integer. ";
4H#+ " Add 4 ** 17 to avoid special cases. ";
2b   " Convert into array of digits in base 2. ";
W%   " Reverse the order. ";
32<  " Discard the 33th and all following digits. ";
2b   " Convert the array of digits into an integer. ";

4

JavaScript (E6) 37 39 40 50

Функция, ввод номера и возврат обратного номера. Самый простой алгоритм, вероятно, может быть лучше в гольф с некоторыми хитрыми трюками.

Редактировать рекурсию вместо цикла

Изменить 2 Следуя предложению @bebe k*2вместоk<<1

Edit 3 Что-то, что я пропустил вообще: это полный 32-битный цикл, нет необходимости инициализировать k. Спасибо @FUZxxl

R=(v,b=32,k)=>b?R(v>>1,b-1,k*2|v&1):k

это было

R=v=>{for(k=b=0;b++<32;)k+=k+(v&1),v>>=1;return k}

Тест В консоли FireFox, тестируйте, используя числа в OP и еще несколько случайных 16- и 32-битных чисел

Bin=x=>('0'.repeat(32)+(x<0?-x-1:x).toString(2)).slice(-32).replace(/./g,d=>x>0?d:1-d),
Dec=x=>(' '.repeat(11)+x).slice(-11),
R16=_=>Math.random()*65536|0,  
R32=_=>(Math.random()*65536<<16)|R16(),  
[-90,486,-984802906,R16(),R16(),R16(),R32(),R32(),R32(),R32()]
 .forEach(n=> console.log(Dec(n)+' '+Bin(n)+' '+Dec(R(n))+' '+Bin(R(n))))

Пример тестового вывода

        -90 11111111111111111111111110100110  1711276031 01100101111111111111111111111111
        486 00000000000000000000000111100110  1736441856 01100111100000000000000000000000
 -984802906 11000101010011010001100110100110  1704506019 01100101100110001011001010100011
      45877 00000000000000001011001100110101 -1395851264 10101100110011010000000000000000
      39710 00000000000000001001101100011110  2027487232 01111000110110010000000000000000
      56875 00000000000000001101111000101011  -730136576 11010100011110110000000000000000
-1617287331 10011111100110100010011101011101 -1159439879 10111010111001000101100111111001
-1046352169 11000001101000011110111011010111  -344488573 11101011011101111000010110000011
 1405005770 01010011101111101010111111001010  1408597450 01010011111101010111110111001010
  -35860252 11111101110111001101000011100100   655047615 00100111000010110011101110111111

b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kдля однократного использования и R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kмногоразового использования
bebe

@bebe :( Я пересматривал свой ответ с помощью рекурсии и потерял все, чтобы прочитать твой комментарий ...
edc65

2
вы в 38 байтах, если k<<1становится k*2и v>>1становится v/2. это работало на 486. Я не знаю о других тестовых случаях
bebe

1
@bebe v / 2 не будет работать для отрицательных чисел. 486/512 == 0,9 ... и 486 >> 9 == 0, усечение это то же самое. Но -90/128 == -0,7 ... и -90 >> 7 == - 1
edc65

4

x86 в сборе, 10 байт

   f9                      stc    
   d1 d8            1:     rcr    %eax
   74 05                   je     2f
   d1 d2                   rcl    %edx
   f8                      clc    
   eb f7                   jmp    1b
                    2:

Это предполагает ввод в EAX, вывод в EDX. (Кроме того, на выходе eax равно нулю, а CF и ZF установлены, если кому-то нужно).

Вместо счетчика в начале добавляется дополнительный 1 в качестве маркера конца данных


Это на самом деле имеет тот же размер, что и мое решение, которое на три байта больше. Если вы добавите retинструкцию для возврата из функции и реализуете cdecl (т.е. измените rcr %eaxна rcr 4(%esp)и rcl %edxна rcl %eax), вы получите один дополнительный байт для retи еще два байта для ссылки на память. Тем не менее, хорошее решение.
FUZxxl

3

J ( 17 15 13 байт)

_32#.@|.@{.#:

Вот явное определение, чтобы объяснить, что он делает:

3 : '#. |. _32 {. #: y'
  1. #: yпредставляет yсобой число 2, используя столько мест, сколько необходимо.
  2. x {. yпринимает |x(величину x) предметы yс фронта, если xположительный, со спины, если xотрицательный. Если мы возьмем больше предметов, чем присутствует, результат будет дополнен нулями. _32 {. #: yэффективно дополняет #: yдо 32 бит.
  3. |. yсальто y, я. меняет порядок элементов в y.
  4. #. y интерпретирует yкак число базы-2.


2

Python - 89

def r(n):
 if n<0:n=~n^0xFFFFFFFF
 print int(['','-'][n%2]+'{:032b}'.format(n)[::-1],2)

Python представляет отрицательные двоичные числа просто -0b{positive_number}. Таким образом, чтобы справиться с этим, дополнить отрицательные числа, а затем XOR со всеми 1.

После этого создайте строковое представление целого числа на основе формата, {:032b}который обеспечивает 32-битное представление числа. Наконец, переверните строку и превратите ее обратно в целое число.

РЕДАКТИРОВАТЬ

Благодаря @Martin Büttner за то, что он указал на проблему с дополнительным дополнением. Если nзаканчивается на 1, то в дополнение к двум обратная версия будет отрицательной.

К счастью, как объяснялось выше, Python любит отрицательные двоичные числа довольно простым способом. К счастью, intфункция Python позволяет использовать необязательные символы знака в своем первом аргументе.

Так что теперь, добавьте знак минус, если nнечетно, чтобы удовлетворить два дополнения.


@ MartinBüttner Спасибо. Сначала я упустил эту возможность. Новый код лучше обрабатывает два дополнения.
BeetDemGuise

2
Вы можете играть в гольф, что немного больше: ['','-'][n%2]есть '-'*(n%2).
Джастин

2

Пиф , 33 32 22

v_%"%032db0"vsc%Q^2 32

Объяснение:

                 Q             Evaluated input.
                %Q^2 32        Q mod 2^32. Same 32 bit binary representation as Q.
             vsc%Q^2 32        Convert to binary string, then that to decimal int.
   %"%032db0"vsc%Q^2 32        Pad above number to 32 bits, and append b0.
  _%"%032db0"vsc%Q^2 32        Reverse it.
 v_%"%032db0"vsc%Q^2 32        Eval and print. Due to leading "0b", eval as binary.

Гольфы:

33 -> 32: перед добавлением добавлено добавление до сохранения, чтобы сохранить конечную кавычку.

32 -> 22: Использовал Q mod 2 ^ 32 вместо сложной техники. Объединить обе строки в одну.

Тестовые случаи:

$ cat rev_bits 
v_%"%032db0"vsc%Q^2 32

$ ./pyth.py rev_bits <<< -984802906
1704506019

$ ./pyth.py rev_bits <<< 486
1736441856

$ ./pyth.py rev_bits <<< 0
0

Это работает с результатом как большие 32 числа, имеющие самый левый бит в 1? В этом случае он должен вывести отрицательное целое число.
edc65

@ edc65 Я вывожу 32-битное целое число без знака.
Исаак

2

GNU dc, 27 байт

0?[2~rssr2*+dlsz34>m]dsmx+p

Выход:

$ dc revbits.dc <<< 15
4026531840
$ dc revbits.dc <<< 255
4278190080
$ dc revbits.dc <<< 65535
4294901760
$ dc revbits.dc <<< 4294901760
65535
$ dc revbits.dc <<< 4278190080
255
$ dc revbits.dc <<< 4026531840
15
$ 

Bash + coreutils, 45 байт

n=`dc -e2do32^n$1p`
dc -e2i`rev<<<${n: -32}`p

Выход:

$ ./revbits.sh 15
4026531840
$ ./revbits.sh 255
4278190080
$ ./revbits.sh 65535
4294901760
$ ./revbits.sh 4294901760
65535
$ ./revbits.sh 4278190080
255
$ ./revbits.sh 4026531840
15
$ 

Функция C, 89 байт

Идея та же, что и у /codegolf//a/36289/11259 - использование стэнфордских хитов твидлинга . Не собираюсь выигрывать в гольф, но тем не менее интересно:

// 89 byte function:
i;r(v){for(i=1;i<32;i*=2)v=v>>i&(1L<<32)/((1<<i)+1)|(v&(1L<<32)/((1<<i)+1))<<i;return v;}

// Test program:
#include <stdio.h>

int main (int argc, char **argv)
{
    printf("r(0x0000000f) = 0x%08x\n", r(0x0000000f));
    printf("r(0x000000ff) = 0x%08x\n", r(0x000000ff));
    printf("r(0x0000ffff) = 0x%08x\n", r(0x0000ffff));
    printf("r(0xffffffff) = 0x%08x\n", r(0xffffffff));
    printf("r(0x0f0f0f0f) = 0x%08x\n", r(0x0f0f0f0f));
    printf("r(0xf0f0f0f0) = 0x%08x\n", r(0xf0f0f0f0));
}

Выход:

$ ./revbits 
r(0x0000000f) = 0xf0000000
r(0x000000ff) = 0xff000000
r(0x0000ffff) = 0xffff0000
r(0xffffffff) = 0xffffffff
r(0x0f0f0f0f) = 0xf0f0f0f0
r(0xf0f0f0f0) = 0x0f0f0f0f
$

2

Функция Java, 64 символа.

 int r(int n){int r=0,i=32;for(;i-->0;n>>=1)r=r<<1|n&1;return r;}

Также должен работать в C.


2

PHP, 46 байт

Онлайн версии

for(;$i<32;)$t.=$argn>>$i++&1;echo bindec($t);

или

<?=bindec(strrev(sprintf("%064b",$argn<<32)));

substrНенужно (-12 байт). Вы должны упомянуть, как их запустить.
Тит

1
@ Титус, ты пробовал тестовый случай -984802906?
Йорг Хюльсерманн

1
Ваша вторая версия может быть улучшена, чтобы соответствовать первой:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Кристоф

@Christoph очень хорошее улучшение Спасибо
Йорг Хюльсерманн

1

JS 115

Ну, это выглядит не очень хорошо: D

n=+prompt();alert(eval('0b'+(Array(33).join(0)+(n<0?n>>>0:n).toString(2)).slice(-32).split('').reverse().join('')))

Метод @Florian F в JS имеет длину 53 байта:

for(n=+prompt(r=0),i=32;i--;n>>=1)r=r<<1|n&1;alert(r)

1
Эти it may be a functionсредства правило вам не нужно предупреждение или быстрое
slebetman

1

C # 81 74

int R(int V){int l,r=l=0,i=1;for(;i>0;i*=2)r|=i*(1&V>>(31-l++));return r;}

Битовые операции, которые, скорее всего, можно сделать короче на всех языках программирования.

По сути, перебираем все степени от 2 до целых максимумов + 1 (что превращается в степень двух) и, поскольку (2 147 483 647 + 1) = 0, я могу зациклить до 0. Сдвиг бита Слева направо, чтобы переместить бит в первый позиция. Последний бит на месте 32 идет на 31 шаг вправо, второй последний идет на 30 и т. Д. Поэтому, используя оператор AND с 1, я узнаю, равен ли он 1 или 0. Если это 1, я добавлю текущее значение i к результату и верни это.

int R(int V)
{
    int l,r=l=0,i=1;
    for(;i>0;i*=2)
        r|=i*(1&(V>>(31-l++)));
    return r;
 }

Небольшие вещи, но вы можете инициализировать, iкогда вы объявляете это, и сохранять байт, удаляя i++из цикла for, и вместо сравнения результата 1&...с 0 вы можете полностью удалить оператор if и умножить iна результат, передаваемый r|=i*(1&(V>>(31-l++)));в цикле
VisualMelon

Умная! У меня было чувство, что я что-то упустил. Благодарность!
WozzeC

1

C # 142

using System;using System.Linq;int f(int n){return Convert.ToInt32(new string(Convert.ToString(n,2).PadLeft(32,'0').Reverse().ToArray()),2);}

расширенный

int f(int n)
{
    return Convert.ToInt32(
        new string(
            Convert.ToString(n, 2)
            .PadLeft(32, '0')
            .Reverse()
            .ToArray()), 2);
}

1

Python - 37

Похоже на решение @ isaacg.

f=lambda n:int(bin(n%2**32)[:1:-1],2)

1

С ++, 160

Это не самый короткий, однако он использует только 24 операции.
Взято из книги Восторг Хакера.

Golfed:

typedef unsigned U;U R(U&x){U a=-1u/3,b=-1u/5,c=-1u/17,d=65280;x=(x&a)*2|(x/2)&a;x=(x&b)*4|(x/4)&b;x=(x&c)<<4|(x>>4)&c;x=(x<<24)|((x&d)<<8)|((x>>8)&d)|(x>>24);}

Ungolfed:

unsigned R(unsigned x) {
    x = (x & 0x55555555) <<  1 | (x >>  1) & 0x55555555; 
    x = (x & 0x33333333) <<  2 | (x >>  2) & 0x33333333; 
    x = (x & 0x0F0F0F0F) <<  4 | (x >>  4) & 0x0F0F0F0F; 
    x = (x << 24) | ((x & 0xFF00) << 8) | ((x >> 8) & 0xFF00) | (x >> 24); 
    return x; 
} 

1
Это кодовый вопрос о гольфе. Пожалуйста, попробуйте уменьшить количество символов в вашем решении, а не количество операций.
FUZxxl

1

Haskell, 145 - без побитовых операций

Бит-тиддлинг кажется мне полной противоположностью Haskell, поэтому я избегаю использования битовых операторов. Получившаяся программа, конечно, не самая короткая, но я подумал, что использование математики вместо бит-тиддлинга было по крайней мере интересно.

import Data.Tuple
import Data.List
f m=foldl1((+).(*2))$take 32$(unfoldr(\n->if n==0 then Nothing else Just$swap$divMod n 2)$mod m$2^32)++[0,0..]

объяснение

f m=foldl1((+).(*2))$take 32$(unfoldr(\n->if n==0 then Nothing else Just$swap$divMod n 2)$mod m$2^32)++[0,0..]
    |------5-------|---4----|--------------------------2---------------------------------|----1-----|---3----|
  1. использует модуль для вывода результата в 32-битный диапазон
  2. строит список 0s и 1s, сначала младший значащий бит путем многократного деления на 2 и взятия остатка
  3. объединяет бесконечный список 0s до конца этого списка
  4. захватывает первые 32 элемента списка (последние два были необходимы, чтобы убедиться, что список на самом деле имеет длину 32 бита.)
  5. преобразует список 0и 1в целое число, предполагая, что самый старший бит - первый (повторяется дважды и добавляет).

Я не совсем уверен, что составляет «стандартную библиотеку» в Haskell, поэтому я предположил, что Data.Tuple и Data.List были в порядке (они довольно стандартны).

Кроме того, выходные данные представляют собой 32-разрядное целое число без знака после изменения, которое обойдется мне в байтах: я утверждаю это в разделе «упущения - бесплатная игра».


Стандартная библиотека: что поставляется с языком. Это включает системные заголовки для C, более 4000 классов и методов в Java (большинство из них не имеют значения).
Isiah Meadows

1

PHP, 46 41 байт

попробуйте их онлайн

while($i<32)$r=$r*2|$argn>>$i++&1;echo$r;

поразрядно ... более или менее. Беги как труба с php -nR '<code>'.

PHP, 46 байт

while($i<32)$r|=($argn>>$i&1)<<31-$i++;echo$r;

чисто побитовое решение; беги как труба с -nR.

PHP, 47 59 байт

<?=bindec(str_pad(strrev(substr(decbin($argn),-32)),32,0));

другой встроенный подход; сохранить в файл и запустить как канал с -F.


0

Perl - 60

$_=unpack"N",pack"B*",scalar reverse unpack"B32",pack"N",$_

+1 за флаг p (дайте мне знать, если я считаю это неправильно).

Бежать с:

echo 486 | perl -pe'$_=unpack"N",pack"B32",scalar reverse unpack"B32",pack"N",$_'

0

C ++ 69

int r(int n){int e=0,i=0;for(;i<32;i++)e|=((n>>i)&1)<<31-i;return e;}

@bebe что это e;i;? Объявления без типа не являются допустимым C ++. Для переменных это даже не верно C.
Руслан

@ Руслан, я не узнал «++» в названии, извините. (я не согласен с твоим вторым утверждением)
bebe

int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 байт :)
Кристоф

0

Р, 45

f=function(x)packBits(intToBits(x)[32:1],"i")

Примеры:

f(486)
# [1] 1736441856
f(-984802906)
# [1] 1704506019

Всегда просто стесняюсь ответов Python. Это чертово ключевое слово функции.


0

Рубин, 43 41 байт

def r(n)(0..31).inject(0){|a,b|a*2+n[b]}end

В Ruby использование обозначения индекса в скобках (foo [i]) возвращает бит на n-м месте.

--Редактировать--

Рефакторинг injectфункциональности сбивает пару байтов

def r(n)z=0;32.times{|i|z=z*2+n[i]};z;end


0

Perl5: 46

sub r{for(0..31){$a=$a*2|$_[0]&1;$_[0]>>=1}$a}

Ничего фантастического. Он сдвигает вывод влево, копирует lsb перед сдвигом источника вправо.



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.