Odwróć kolejność bitów liczb całkowitych 32-bitowych

21

Napisz najkrótszy kod, aby odwrócić kolejność bitów 32-bitowej liczby całkowitej.

Zasady:

  1. Zakłada się, że dane wejściowe są prawidłową liczbą całkowitą lub ekwiwalentem ciągu, jeśli Twój język nie obsługuje wartości liczbowych (np. Windows Batch).
  2. Dane wyjściowe muszą być prawidłową liczbą całkowitą lub ciągiem równoważnym, jeśli Twój język nie obsługuje wartości liczbowych (np. Windows Batch).
  3. Tylko biblioteka standardowa.
  4. Może to być funkcja lub pełny program.
  5. Dane wejściowe mogą pochodzić z stdinargumentu funkcji lub z niego.
  6. Dane wyjściowe muszą mieć wartość stdoutlub być zwracaną wartością.
  7. Jeśli twój język ma wbudowaną lub standardową funkcję biblioteki, która wykonuje to w jednym kroku (np. rbitW zespole ARM), nie można jej użyć.

Przykłady:

Klawisz:

  1. dziesiętny
    • dwójkowy
    • (rewers)
    • odwrócony binarny
    • wyjście dziesiętne

Przykłady:

  1. -90 (8-bitowy przykład dla demonstracji)

    • 10100110b
    • (rewers)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (rewers)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (rewers)
    • 01100101100110001011001010100011b
    • 1704506019

Uwaga: pominięcia to darmowa gra. Jeśli tego nie powiedziałem i nie jest to jedna ze standardowych luk , to jest to całkowicie dozwolone.

Isiah Meadows
źródło
Co należy rozumieć przez „pominięcia” w „pominięciach to darmowa gra”?
Todd Lehman
1
Wszystko, co nie zostało wyraźnie określone w regulaminie.
Isiah Meadows
Czy stół statyczny 16 GB byłby liczony jako część długości programu?
Hot Licks
@HotLicks Zgodnie z typową interpretacją programu tak.
FUZxxl,
język, który obsługuje tylko 8-bitowe dane wejściowe, czy możemy brać dane wejściowe jako cztery liczby 8-bitowe?
Sparr

Odpowiedzi:

0

Zestaw x86, 9 bajtów

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

W formie 33 C0 40 D1 E9 13 C0 73 FAbajtów:, 9 bajtów.

Myria
źródło
To znowu jest dokładnie tak długo, jak moje rozwiązanie, jeśli (a) zastosujesz się do konwencji wywoływania cdecl i (b) faktycznie powrócisz z funkcji.
FUZxxl,
@FUZxxl Jakoś nie widziałem twojej wersji. Masz całkowitą rację. Myślałem __fastcalli nie miałem ret.
Myria
24

Zespół MMIX (28 bajtów)

64-bitowe liczby

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

To łączy się z:

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

Jak to działa?

MORInstrukcji wykonuje mnożenie macierzy w dwóch 64-bitowych ilości stosowanych jako dwa 8x8 matryc logicznych. Liczba boolowska z cyframi abcdefghklmnopqr 2 jest używana jako macierz w następujący sposób:

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

W MORmnoży instruktażowe macierze reprezentowane przez swoich argumentów gdzie mnożenie andi dodawanie or. To jest:

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

a ponadto:

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

która jest odwrotną kolejnością bitów oryginalnego numeru.

32-bitowe liczby

Jeśli chcesz tylko odwrócić liczbę 32-bitową zamiast liczby 64-bitowej, możesz użyć tej zmodyfikowanej metody:

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

zmontowane:

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

Pierwsze mnożenie macierzy działa w zasadzie tak:

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

odpowiedni oktabajt #0000000001020408ładujemy w pierwszych dwóch instrukcjach. Drugie mnożenie wygląda następująco:

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

Odpowiedni oktabajt #0102040810204080tworzymy z pierwszej macierzy w następujący sposób:

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

Drugie mnożenie odbywa się jak zwykle, wynikowy kod ma tę samą długość (28 bajtów).

FUZxxl
źródło
1
po raz pierwszy słyszę o instrukcji mnożenia macierzy na procesorze
phuclv
@ LưuVĩnhPhúc: Nie mnożenie macierzy, ale VAX miał instrukcję oceny wielomianu .
nneonneo
1
@nneonneo POLYInstrukcja VAX jest w zasadzie połączonym mnożeniem i dodawaniem z wbudowaną pętlą. Podobne rzeczy istnieją również we współczesnych architekturach (jak x86), ale zwykle nie mają wbudowanej pętli do oceny całego wielomianu na raz.
FUZxxl,
12

80386 montaż ( 13 12 bajtów)

Jako funkcja w składni AT&T przy użyciu konwencji wywoływania 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

Ta funkcja składa się z następującej sekwencji bajtów:

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

Podzielony na instrukcje:

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    

Działa to w ten sposób: w każdej z 32 iteracji pętli argument, który znajduje się w 4(%esp), jest przesunięty w prawo o jedną pozycję. Ostatni bit jest domyślnie przenoszony na flagę carry. adcInstrukcja dodaje dwie wartości i dodaje wartość flagi przeniesienia do wyniku. Jeśli dodajesz wartość do siebie, tzn. %eaxSkutecznie przesuwasz ją w lewo o jedną pozycję. Jest adc %eax,%eaxto wygodny sposób na przesunięcie w lewo %eaxo jedną pozycję przy jednoczesnym przesunięciu zawartości flagi przenoszenia na bit niskiego rzędu.

Powtarzam ten proces 32 razy, aby cała zawartość 4(%esp)została zrzucona %eax. Nigdy nie inicjowałem jawnie, %eaxponieważ jego poprzednia zawartość jest przesuwana podczas pętli.

FUZxxl
źródło
+1 Dzięki za ostatnie zdanie. Teraz jest oczywiste, ale mi tego brakowało.
edc65
1
Zawsze cieszę się z rozwiązań montażowych tutaj :)
user1354557
8

C,    63    52   48

Orginalna wersja:

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

Zaktualizowana wersja (ze zmianami wprowadzonymi przez Allbeert , es1024 i Dennis ):

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

Uwaga: Ponieważ druga wersja pomija ustawienie r=0, kod zakłada, że ​​an intma 32 bity. Jeśli to założenie jest fałszywe, funkcja najprawdopodobniej wygeneruje niepoprawny wynik, w zależności od początkowego stanu rwejścia do funkcji.


Wersja ostateczna (z dalszymi zmianami sugerowanymi przez Dennisa i Alchymista ):

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

Uwaga: To stawia deklarację zmiennych roboczych ri ido listy parametrów. Parametry są następujące: njest liczbą, która ma być odwrócona. ri isą zmiennymi roboczymi, które należy przekazać jako 0.

Todd Lehman
źródło
1
Możesz usunąć inttyp funkcji, a także zmienić się return rna coś w rodzaju, i=rponieważ większość kompilatorów C zwykle pozostawia wynik ostatniej operacji w rejestrze zwrotnym. Dla mnie działało na gcc i cl.
Allbeert
1
Możesz ogolić kolejne 4 bajty, używając r(n){...}zamiastr(int n){...}
es1024
2
@FUZxxl nie można upuść intw int r=0,i=32;chyba przenieść je z organizmu funkcji.
es1024
1
@FUZxxl: Nie powinienem komentować, kiedy jestem zmęczony ... Przesunięcie arytmetyczne i podział nie są równoważne; ten ostatni zaokrągla w kierunku zera, podczas gdy pierwsze w kierunku ujemnej nieskończoności. -1 >> 1jest -1dla AS i 2**31 - 1dla LS, podczas gdy -1 / 2jest 0.
Dennis
1
@Todd: Każdy powód, dla którego nie zdefiniował r, a ijako argumenty? Zaoszczędziłby jeszcze trzy bajty ...
Dennis
5

Julia 0,2, 33 bajty

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

Robi to, jak to wygląda.

bitsdaje bitową reprezentację (z uwzględnieniem uzupełnienia dwóch). parseintnie przejmuje się uzupełnieniem dwóch, ale zwraca 32-bitową liczbę całkowitą, więc uzupełnienie dwóch jest obsługiwane przez przepełnienie.

Według dzienników zmian parseintw Julii 0.3 dodano wykrywanie przepełnienia , więc to może już nie działać.

Martin Ender
źródło
5
To jest kod produkcyjny, a nie golfowy! xD Myślę, że Julia jest po prostu świetna.
cjfaure
4

Python 2, 50

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

Zasadniczo to samo, co moje rozwiązanie Pyth. Weź wejściowy mod 2 ** 32, przekonwertuj na 32-bitowy wypełniony plik binarny, odwróć, zamień żądło binarne z powrotem na dziesiętne i wydrukuj.

isaacg
źródło
4

CJam, 15 bajtów

li4H#+2bW%32<2b

Wypróbuj online.

Użyty joker „Free game”: Wyjście zawsze będzie liczbą całkowitą bez znaku .

Przypadki testowe

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

Jak to działa

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. ";
Dennis
źródło
4

JavaScript (E6) 37 39 40 50

Funkcja, wprowadzanie liczb i zwracanie odwróconej liczby. Najbardziej podstawowy algorytm, prawdopodobnie można grać w golfa za pomocą inteligentnej sztuczki.

Edytuj rekurencję zamiast pętli

Edytuj 2 Zgodnie z sugestią @bebe k*2zamiastk<<1

Edytuj 3 Coś, co w ogóle mi umknęło: jest to pełna 32-bitowa pętla, nie trzeba inicjować k. Dzięki @FUZxxl

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

To było

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

Testuj W konsoli FireFox, testuj używając liczb w OP i niektórych bardziej losowych liczb 16 i 32 bitowych

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))))

Przykład wyjścia testowego

        -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
edc65
źródło
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kdo jednorazowego użytku i R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):knadaje się do wielokrotnego użytku
bebe
@bebe :( Poprawiałem moją odpowiedź za pomocą rekurencji i straciłem wszystko, aby przeczytać twój komentarz ...
edc65
2
masz 38 bajtów, jeśli k<<1staje się k*2i v>>1staje v/2. działało dla 486. Nie wiem o innych przypadkach testowych
bądź
1
@bebe v / 2 nie działa dla liczb ujemnych. 486/512 == 0,9 ... i 486 >> 9 == 0, obcięcie jest takie samo. Ale -90/128 == -0,7 ... i -90 >> 7 == - 1
edc65
4

x86, 10 bajtów

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

Zakłada się wejście w eax, wyjście w edx. (Ponadto, na wyjściu eax wynosi zero, a CF i ZF są ustawione, jeśli kogo to obchodzi).

Zamiast licznika, dodatkowy 1 jest wpychany na początku jako znacznik końca danych

Hagen von Eitzen
źródło
To faktycznie ma taki sam rozmiar jak moje rozwiązanie, czyli trzy bajty większe. Jeśli dodasz retinstrukcję powrotu z funkcji i zaimplementujesz cdecl (tj. Zmienisz rcr %eaxna rcr 4(%esp)i rcl %edxna rcl %eax), otrzymujesz jeden dodatkowy bajt na retdwa kolejne bajty na odwołanie do pamięci. Mimo to miłe rozwiązanie.
FUZxxl,
3

J ( 17 15 13 bajtów)

_32#.@|.@{.#:

Oto wyraźna definicja wyjaśniająca, co robi:

3 : '#. |. _32 {. #: y'
  1. #: yreprezentuje yjako liczbę podstawową 2, wykorzystując tyle miejsc, ile potrzeba.
  2. x {. ypobiera |x(wielkość x) przedmiotów y, z przodu, jeśli xjest dodatnia, z tyłu, jeśli xjest ujemna. Jeśli weźmiemy więcej przedmiotów niż obecnie, wynik zostanie uzupełniony zerami. _32 {. #: yskutecznie uzupełnia #: ydo 32 bitów.
  3. |. yprzewraca y, ja. odwraca kolejność elementów w y.
  4. #. y interpretuje yjako liczbę podstawową 2.
FUZxxl
źródło
2

Python - 89

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

Python reprezentuje po prostu ujemne liczby binarne -0b{positive_number}. Aby sobie z tym poradzić, uzupełnij liczby ujemne, a następnie XOR wszystkimi 1.

Następnie utwórz ciąg liczb całkowitych w oparciu o format {:032b}zapewniający 32-bitową reprezentację liczby. Na koniec odwróć ciąg i zamień go z powrotem w liczbę całkowitą.

EDYTOWAĆ

Dzięki @Martin Büttner za zwrócenie uwagi na problem uzupełnienia dwóch. Jeśli nkończy się na 1, to przez uzupełnienie do dwóch odwrócona wersja byłaby ujemna.

Na szczęście, jak wyjaśniono powyżej, Python lubi ujemne liczby binarne w dość prosty sposób. Na szczęście intfunkcja Pythona pozwala opcjonalnie podpisywać znaki w pierwszym argumencie.

Więc teraz dodaj znak minus, jeśli njest nieparzysty, aby spełnić uzupełnienie dwóch.

BeetDemGuise
źródło
@ MartinBüttner Dzięki. Początkowo tęskniłem za tą możliwością. Nowy kod lepiej obsługuje uzupełnienie dwóch.
BeetDemGuise
2
Możesz zagrać w golfa nieco więcej: ['','-'][n%2]jest '-'*(n%2).
Justin
2

Pyth , 33 32 22

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

Wyjaśnienie:

                 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.

Golfy:

33 -> 32: Przeniesiono dodaj do przed cofnięciem, aby zapisać cytat końcowy.

32 -> 22: Używany Q mod 2 ^ 32 zamiast skomplikowanej maszyny. Połączono oba ciągi w jeden.

Przypadki testowe:

$ 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
isaacg
źródło
Czy to działa z wynikiem, gdy duże 32 cyfry mają najbardziej lewy bit na 1? W takim przypadku powinna wypisać ujemną liczbę całkowitą.
edc65
@ edc65 Wyprowadzam 32-bitową liczbę całkowitą bez znaku.
isaacg
2

GNU dc, 27 bajtów

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

Wydajność:

$ 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 bajtów

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

Wydajność:

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

Funkcja C, 89 bajtów

Taki sam pomysł, jak /codegolf//a/36289/11259 - przy użyciu kręcących się hacków Stanforda . Nie zamierzam wygrywać w golfa, ale mimo to interesujące:

// 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));
}

Wydajność:

$ ./revbits 
r(0x0000000f) = 0xf0000000
r(0x000000ff) = 0xff000000
r(0x0000ffff) = 0xffff0000
r(0xffffffff) = 0xffffffff
r(0x0f0f0f0f) = 0xf0f0f0f0
r(0xf0f0f0f0) = 0x0f0f0f0f
$
Cyfrowa trauma
źródło
2

Funkcja Java, 64 znaki.

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

Powinien także działać w C.

Florian F.
źródło
2

PHP, 46 bajtów

Wersje online

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

lub

<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Jörg Hülsermann
źródło
substrJest niepotrzebne (-12 bajtów). Powinieneś wspomnieć, jak je uruchomić.
Tytus
1
@Titus próbowałeś testcase -984802906?
Jörg Hülsermann
1
Twoja druga wersja może zostać ulepszona, aby pasowała do pierwszej:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph
@Christoph bardzo miła poprawa Dziękujemy
Jörg Hülsermann
1

JS 115

Cóż, to wcale nie wygląda dobrze: D

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

Metoda @Florian F w JS ma długość 53 bajtów:

for(n=+prompt(r=0),i=32;i--;n>>=1)r=r<<1|n&1;alert(r)
bebe
źródło
1
Te it may be a functionśrodki reguły nie trzeba wpisem lub wiersza
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;}

Operacje bitowe, które najprawdopodobniej można wykonać krócej we wszystkich językach programowania.

Zasadniczo, przełóż wszystkie moce od 2 do maksymalnej liczby całkowitej + 1 (co zamienia się w potęgę dwóch), a ponieważ (2 147 483 647 + 1) = 0 mogę zapętlić do 0. Przesunięcie bitu w lewo do prawa, aby przenieść bit do pierwszego pozycja. Ostatni bit na miejscu 32 idzie w 31 krokach w prawo, drugi ostatni idzie w 30, itd. Tak więc używając operatora AND z 1, będę wiedział, czy jest to 1 lub 0. Jeśli to 1, dodam bieżącą wartość i do wyniku i zwróc to.

int R(int V)
{
    int l,r=l=0,i=1;
    for(;i>0;i*=2)
        r|=i*(1&(V>>(31-l++)));
    return r;
 }
WozzeC
źródło
Małe rzeczy, ale możesz zainicjować, ikiedy je deklarujesz, i zapisać bajt, usuwając i++z pętli for, i zamiast porównywać wynik 1&...z 0, możesz całkowicie usunąć instrukcję if i pomnożyć iprzez wynik r|=i*(1&(V>>(31-l++)));
podany
Sprytny! Miałem wrażenie, że czegoś mi brakuje. Dzięki!
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);}

Rozszerzony

int f(int n)
{
    return Convert.ToInt32(
        new string(
            Convert.ToString(n, 2)
            .PadLeft(32, '0')
            .Reverse()
            .ToArray()), 2);
}
BenVlodgi
źródło
1

Python - 37

Podobne do rozwiązania @ isaacg.

f=lambda n:int(bin(n%2**32)[:1:-1],2)
cjfaure
źródło
1

C ++, 160

To nie jest najkrótszy, ale wykorzystuje tylko 24 operacje.
Zaczerpnięte z książki Hacker's Delight.

Gra w golfa:

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);}

Nie golfowany:

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; 
} 
Somnium
źródło
1
To jest pytanie do golfa z kodem. Spróbuj zmniejszyć liczbę znaków w swoim rozwiązaniu, a nie liczbę operacji.
FUZxxl,
1

Haskell, 145 - bez operacji bitowych

Wirowanie bitów wydaje mi się antytezą Haskella, więc uniknąłem użycia operatorów bitowych. Powstały program z pewnością nie jest najkrótszym uczestnikiem, ale pomyślałem, że użycie matematyki zamiast kręcenia bitów było co najmniej interesujące.

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..]

Wyjaśnienie

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. używa modulo, aby doprowadzić wynik do 32-bitowego zakresu
  2. konstruuje listę 0s i 1s, najpierw najmniej znaczący bit, wielokrotnie dzieląc przez 2 i biorąc resztę
  3. łączy nieskończoną listę 0s z końcem tej listy
  4. pobiera pierwsze 32 elementy listy (te dwa ostatnie były potrzebne, aby upewnić się, że lista ma długość 32 bitów).
  5. konwertuje listę 0i 1na liczbę całkowitą, zakładając, że najbardziej znaczący bit jest pierwszy (powtarzane podwójne i dodawanie).

Nie jestem do końca pewien, co stanowi „standardową bibliotekę” w Haskell, więc założyłem, że Data.Tuple i Data.List są w porządku (są dość standardowe).

Ponadto, wyjście jest 32-bitową liczbą całkowitą bez znaku, ponieważ zmiana, która kosztowałaby mnie bajty: argumentuję to pod „pominięciami to darmowa gra”.

ballesta25
źródło
Biblioteka standardowa: co jest dostarczane z językiem. Obejmuje to nagłówki systemowe C, ponad 4000 klas i metod w Javie (większość nie ma znaczenia).
Isiah Meadows
1

PHP, 46 41 bajtów

wypróbuj je online

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

bitowe ... mniej więcej. Uruchom jako potok z php -nR '<code>'.

PHP, 46 bajtów

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

czyste rozwiązanie bitowe; uruchomić jako potok z -nR.

PHP, 47 59 bajtów

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

inne wbudowane podejście; zapisz do pliku i uruchom jako potok za pomocą -F.

Tytus
źródło
0

Perl - 60

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

+1 za flagę p (daj mi znać, jeśli liczę to źle).

Biegnij z:

echo 486 | perl -pe'$_=unpack"N",pack"B32",scalar reverse unpack"B32",pack"N",$_'
hmatt1
źródło
0

C ++ 69

int r(int n){int e=0,i=0;for(;i<32;i++)e|=((n>>i)&1)<<31-i;return e;}
rdans
źródło
@bebe co to jest e;i;? Deklaracje bez typu nie są poprawnym językiem C ++. W przypadku zmiennych nie jest to nawet ważne C.
Ruslan
@Ruslan, nie rozpoznałem „++” w tytule, przepraszam. (nie zgodziłbym się z twoim drugim stwierdzeniem)
bądź
int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 bajtów :)
Christoph
0

R, 45

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

Przykłady:

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

Zawsze nieśmiała od odpowiedzi w Pythonie. To cholerne słowo kluczowe funkcji.

Shadowtalker
źródło
0

Rubin, 43 41 bajtów

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

W Ruby użycie notacji indeksu nawiasów (foo [i]) zwraca bit na n-tym miejscu.

--Edytować--

Refaktoryzacja injectfunkcjonalności zabiera kilka bajtów

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

Marek Erronius
źródło
0

Perl5: 46

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

Nic fajnego. Przesuwa wyjście w lewo, kopiuje lsb przed przesunięciem źródła w prawo.

Sylwester
źródło
0

Clojure, 202 156 142

#(read-string (let [s (clojure.pprint/cl-format nil "~2r" %)](apply str (reverse (apply str (concat (repeat (- 32 (count s)) "0") s "r2"))))))
Bob Jarvis - Przywróć Monikę
źródło
0

Perl (37 + 1)

w zasadzie port rozwiązania C autorstwa Todda Lehmana

perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'

goth perl chiński
źródło