Reverse Bit Order dari Integer 32-bit

21

Tulis kode terpendek untuk membalik urutan bit integer 32-bit.

Aturan:

  1. Input dianggap bilangan bulat atau string yang setara jika bahasa Anda tidak mendukung nilai numerik (mis. Windows Batch).
  2. Output harus berupa bilangan bulat atau string yang setara jika bahasa Anda tidak mendukung nilai numerik (mis. Windows Batch).
  3. Hanya perpustakaan standar.
  4. Mungkin fungsi atau program lengkap.
  5. Input dapat berasal dari stdinatau sebagai argumen fungsi.
  6. Output harus berupa stdoutatau sebagai nilai yang dikembalikan.
  7. Jika bahasa Anda memiliki fungsi pustaka built-in atau standar yang melakukan ini dalam satu langkah (misalnya rbitdalam perakitan ARM), itu tidak dapat digunakan.

Contoh:

Kunci:

  1. desimal
    • biner
    • (membalikkan)
    • biner terbalik
    • output desimal

Contoh:

  1. -90 (Contoh 8-bit untuk demonstrasi)

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

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

    • 11000101010011010001100110100110b
    • (membalikkan)
    • 01100101100110001011001010100011b
    • 1704506019

Catatan: Kelalaian adalah permainan gratis. Jika saya tidak mengatakannya, dan itu bukan salah satu celah standar , maka itu sepenuhnya diizinkan.

Isiah Meadows
sumber
Apa yang dimaksud dengan "kelalaian" dalam "kelalaian adalah permainan gratis"?
Todd Lehman
1
Apa pun yang tidak secara eksplisit dinyatakan dalam aturan.
Isiah Meadows
Apakah tabel statis 16 GB akan dihitung sebagai bagian dari panjang program?
Hot Licks
@HotLicks Menurut interpretasi khas program, ya.
FUZxxl
bahasa yang hanya mendukung input 8-bit, dapatkah kita mengambil input sebagai empat angka 8-bit?
Sparr

Jawaban:

0

perakitan x86, 9 byte

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

Dalam bentuk byte:, 33 C0 40 D1 E9 13 C0 73 FA9 byte.

Myria
sumber
Itu lagi persis selama solusi saya jika Anda (a) mematuhi konvensi pemanggilan cdecl dan (b) benar-benar kembali dari fungsi.
FUZxxl
@ FuZxxl Entah bagaimana, saya tidak melihat versi Anda. Anda sepenuhnya benar. Saya sedang berpikir __fastcalldan tidak punya ret.
Myria
24

Perakitan MMIX (28 Bytes)

Angka 64 bit

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

Ini berkumpul untuk:

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

Bagaimana cara kerjanya?

The MORinstruksi melakukan perkalian matriks pada dua jumlah 64-bit yang digunakan sebagai dua 8x8 matriks boolean. Angka boolean dengan digit abcdefghklmnopqr 2 digunakan sebagai matriks seperti ini:

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

The MORmengalikan instruksi matriks diwakili oleh argumen mereka di mana perkalian anddan penambahan adalah or. Ini:

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

dan selanjutnya:

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

yang merupakan urutan kebalikan dari bit dari nomor aslinya.

Angka 32 bit

Jika Anda hanya ingin kebalikan dari angka 32 bit alih-alih angka 64 bit, Anda dapat menggunakan metode yang dimodifikasi ini:

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

dirakit:

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

Multiplikasi matriks pertama pada dasarnya bekerja seperti ini:

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

octabyte yang sesuai adalah #0000000001020408 yang kita muat dalam dua instruksi pertama. Perkalian kedua terlihat seperti ini:

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

Octabyte yang sesuai adalah #0102040810204080 yang kita buat dari matriks pertama seperti ini:

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

Perkalian kedua adalah bisnis seperti biasa, kode yang dihasilkan memiliki panjang yang sama (28 byte).

FUZxxl
sumber
1
ini pertama kalinya saya mendengar tentang instruksi perkalian matriks pada CPU
phuclv
@ LưuVĩnhPhúc: Bukan perkalian matriks, tetapi VAX memiliki instruksi untuk mengevaluasi polinomial .
nneonneo
1
@nneonneo POLYInstruksi dari VAX pada dasarnya adalah penggandaan-dan-tambahkan yang menyatu dengan loop bawaan. Hal serupa juga ada dalam arsitektur modern (seperti x86), tetapi mereka biasanya tidak memiliki loop bawaan untuk mengevaluasi seluruh polinomial sekaligus.
FUZxxl
12

80386 unit ( 13 12 byte)

Sebagai fungsi dalam sintaks AT&T menggunakan konvensi pemanggilan 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

Fungsi ini berkumpul ke urutan byte berikut:

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

Dipecah menjadi instruksi:

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    

Ia bekerja seperti ini: Di ​​masing-masing dari 32 iterasi dari loop, argumen, yang terletak di 4(%esp), benar bergeser oleh satu posisi. Bit terakhir secara implisit bergeser ke bendera carry. The adcinstruksi menambahkan dua nilai dan menambah nilai membawa bendera untuk hasilnya. Jika Anda menambahkan nilai pada dirinya sendiri, yaitu %eax, Anda secara efektif menggesernya dengan satu posisi. Ini membuatadc %eax,%eax cara yang mudah untuk bergeser ke kiri%eax satu posisi dengan satu posisi sambil menggeser konten bendera carry ke bit orde rendah.

Saya ulangi proses ini 32 kali sehingga seluruh konten 4(%esp)dibuang ke %eax. Saya tidak pernah secara eksplisit menginisialisasi %eaxkarena isinya sebelumnya digeser selama loop.

FUZxxl
sumber
+1 Terima kasih atas kalimat terakhir Anda, Sudah jelas sekarang tapi saya melewatkannya.
edc65
1
Saya selalu senang melihat solusi perakitan di sini :)
user1354557
8

C,    63    52   48

Versi asli:

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

Versi terbaru (dengan perubahan yang disarankan oleh Allbeert , es1024 , dan Dennis ):

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

Catatan: Karena versi kedua menghilangkan pengaturan r=0, kode ini mengasumsikan bahwa int32 bit. Jika asumsi ini salah, fungsi kemungkinan besar akan menghasilkan hasil yang salah, tergantung pada keadaan awal rsaat masuk ke fungsi.


Versi final (dengan perubahan lebih lanjut disarankan oleh Dennis dan Alchymist ):

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

Catatan: Ini menempatkan deklarasi variabel kerja rdan ike dalam daftar parameter. Parameternya adalah sebagai berikut: nadalah angka yang akan dibalik sedikit. rdan ivariabel kerja yang harus dilewatkan sebagai 0.

Todd Lehman
sumber
1
Anda dapat menghapus inttipe fungsi, dan juga berubah return rmenjadi sesuatu seperti i=rkarena kebanyakan kompiler C cenderung meninggalkan hasil operasi terakhir dalam register kembali. Ini bekerja pada gcc dan cl untuk saya.
Allbeert
1
Anda dapat mencukur 4 byte lainnya dengan menggunakan r(n){...}bukannyar(int n){...}
es1024
2
@FUZxxl Anda tidak bisa drop intdi int r=0,i=32;kecuali Anda memindahkan mereka keluar dari fungsi tubuh.
es1024
1
@ FuZxxl: Tidak boleh berkomentar ketika saya lelah ... Pergeseran dan pembagian aritmatika tidak setara; putaran terakhir menuju nol, sedangkan putaran pertama menuju infinity negatif. -1 >> 1adalah -1untuk AS dan 2**31 - 1untuk LS, sementara -1 / 2ini 0.
Dennis
1
@Todd: Apa alasan Anda tidak mendefinisikan rdan isebagai argumen? Akan menghemat tiga byte lagi ...
Dennis
5

Julia 0.2, 33 byte

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

Seperti apa bentuknya.

bits memberi Anda representasi bit (menghormati komplemen dua). parseinttidak peduli tentang komplemen dua, tetapi mengembalikan integer 32 bit, sehingga komplemen keduanya hanya ditangani oleh overflow.

Menurut changelogs, deteksi overflow ditambahkan ke parseintdalam Julia 0.3, jadi ini mungkin tidak berfungsi lagi.

Martin Ender
sumber
5
Ini adalah kode produksi, bukan kode golf! xD Kurasa Julia baik-baik saja.
cjfaure
4

Python 2, 50

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

Secara umum sama dengan solusi Pyth saya. Ambil input mod 2 ** 32, konversikan ke biner empuk 32-bit, balikkan, ubah sengatan biner menjadi desimal dan cetak.

isaacg
sumber
4

CJam, 15 byte

li4H#+2bW%32<2b

Cobalah online.

"Game gratis" yang digunakan joker: Outputnya akan selalu berupa integer yang tidak ditandai .

Uji kasus

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

Bagaimana itu bekerja

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
sumber
4

JavaScript (E6) 37 39 40 50

Fungsi, input angka dan mengembalikan nomor terbalik. Algoritma paling dasar, mungkin bisa lebih banyak golf dengan beberapa trik pintar.

Edit Rekursi alih-alih loop

Sunting 2 Mengikuti saran @bebe k*2alih-alihk<<1

Sunting 3 Sesuatu yang saya lewatkan sama sekali: itu loop 32 bit penuh, tidak perlu menginisialisasi k. Terima kasih @ FuZxxl

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

Dulu

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

Uji Di konsol FireFox, uji menggunakan angka dalam OP dan beberapa angka 16 dan 32 bit yang lebih acak

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

Contoh hasil uji

        -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
sumber
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kuntuk sekali pakai dan R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kdapat digunakan kembali
bebe
@bebe :( Saya merevisi jawaban saya menggunakan rekursi dan kehilangan semua untuk membaca komentar Anda ...
edc65
2
Anda berada di 38 byte jika k<<1menjadi k*2dan v>>1menjadi v/2. itu bekerja untuk 486. saya tidak tahu tentang kasus tes lain
bebe
1
@ bebe v / 2 tidak akan berfungsi untuk angka negatif. 486/512 == 0,9 ... dan 486 >> 9 == 0, trunc itu sama. Tapi -90/128 == -0.7 ... dan -90 >> 7 == - 1
edc65
4

assemply x86, 10 Bytes

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

Ini menganggap input dalam eax, output dalam edx. (Juga, pada output eax adalah nol dan CF dan ZF diatur, jika ada yang peduli).

Alih-alih penghitung, 1 tambahan didorong di awal sebagai penanda data akhir

Hagen von Eitzen
sumber
Ini sebenarnya memiliki ukuran yang sama dengan solusi saya, yaitu tiga byte lebih besar. Jika Anda menambahkan retinstruksi untuk kembali dari fungsi dan mengimplementasikan cdecl (yaitu mengubah rcr %eaxke rcr 4(%esp)dan rcl %edxke rcl %eax), Anda berakhir dengan satu byte tambahan untuk retdan dua byte lainnya untuk referensi memori. Tetap saja, solusi yang bagus.
FUZxxl
3

J ( 17 15 13 byte)

_32#.@|.@{.#:

Berikut adalah definisi eksplisit untuk menjelaskan apa yang dilakukannya:

3 : '#. |. _32 {. #: y'
  1. #: ymewakili ysebagai nomor basis 2 menggunakan tempat sebanyak yang diperlukan.
  2. x {. ymengambil |x(besarnya x) item dari y, dari depan jika xpositif, dari belakang jika xnegatif. Jika kami mengambil lebih banyak item daripada yang ada, hasilnya diisi dengan nol. _32 {. #: ysecara efektif bantalan #: yhingga 32 bit.
  3. |. ymembalik y, i. membalik urutan item dalam y.
  4. #. y ditafsirkan ysebagai nomor basis-2.
FUZxxl
sumber
3

Dyalog APL , 10 byte

2⊥⌽⎕⊤⍨32/2

2⊥ dari-base-2 of

yang terbalik

input numerik

⊤⍨ dalam sistem bilangan yang terdiri dari

32/2 32 bit

TryAPL online!

Adm
sumber
2

Python - 89

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

Python mewakili angka biner negatif secara sederhana -0b{positive_number}. Jadi untuk mengatasi ini, lengkapi angka negatif dan kemudian XOR dengan semua 1.

Setelah itu, buat representasi string dari integer berdasarkan pada format {:032b}yang menyediakan representasi 32bit dari angka tersebut. Akhirnya, balikkan string dan putar kembali menjadi integer.

EDIT

Terima kasih kepada @Martin Büttner karena menunjukkan masalah komplemen dua. Jikan diakhiri dengan 1 maka dengan komplemen dua's versi terbalik akan negatif.

Untungnya, seperti yang dijelaskan di atas, Python menyukai angka biner negatif dengan cara yang cukup sederhana. Untungnya, intfungsi Python memungkinkan karakter tanda opsional dalam argumen pertamanya.

Jadi sekarang, tambahkan tanda minus jika naneh untuk memuaskan komplemen dua.

BeetDemGuise
sumber
@ MartinBüttner Terima kasih. Saya melewatkan kemungkinan itu pada awalnya. Kode baru menangani komplemen dua lebih baik.
BeetDemGuise
2
Anda dapat bermain golf yang sedikit lebih banyak: ['','-'][n%2]adalah '-'*(n%2).
Justin
2

Pyth , 33 32 22

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

Penjelasan:

                 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.

Golf:

33 -> 32: Memindahkan add to sebelum membalikkan untuk menyimpan kutipan akhir.

32 -> 22: Digunakan Q mod 2 ^ 32 bukan mesin yang rumit. Menggabungkan kedua string menjadi satu.

Kasus uji:

$ 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
sumber
Apakah ini berfungsi dengan hasil sebagai 32 angka besar yang memiliki bit paling kiri pada 1? Dalam hal ini harus menghasilkan bilangan bulat negatif.
edc65
@ edc65 Saya mengeluarkan integer unsigned 32 bit.
isaacg
2

GNU dc, 27 byte

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

Keluaran:

$ 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 byte

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

Keluaran:

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

Fungsi C, 89 byte

Ide yang sama seperti /codegolf//a/36289/11259 - menggunakan Stanford bit twiddling hacks . Tidak akan memenangkan golf, tetapi tetap menarik:

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

Keluaran:

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

Fungsi Java, 64 karakter.

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

Harus juga bekerja di C.

Florian F
sumber
2

PHP, 46 Bytes

Versi Online

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

atau

<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Jörg Hülsermann
sumber
Tidak substrperlu (-12 byte). Anda harus menyebutkan cara menjalankannya.
Titus
1
@Itus apakah Anda sudah mencoba testcase -984802906?
Jörg Hülsermann
1
Versi kedua Anda dapat ditingkatkan agar sesuai dengan yang pertama:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph
@Christoph peningkatan yang sangat bagus Terima kasih
Jörg Hülsermann
1

JS 115

Yah itu sama sekali tidak terlihat bagus: D

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

Metode @Florian F di JS panjangnya 53 byte:

for(n=+prompt(r=0),i=32;i--;n>>=1)r=r<<1|n&1;alert(r)
bebe
sumber
1
The it may be a functionberarti aturan Anda tidak perlu peringatan atau cepat
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;}

Operasi bit yang kemungkinan besar dapat dilakukan lebih pendek di semua bahasa pemrograman.

Pada dasarnya, loop melalui semua kekuatan 2 hingga integer maksimum + 1 (Yang berubah menjadi kekuatan dua) dan karena (2.147.483.647 +1) = 0 Saya dapat loop ke 0. Bit bergeser ke kiri untuk memindahkan bit ke yang pertama posisi. Bit terakhir di tempat 32 berjalan 31 langkah ke kanan, kedua terakhir ke 30 dll. Jadi dengan menggunakan DAN operator dengan 1 saya akan tahu apakah itu 1 atau 0. Jika 1, saya akan menambahkan nilai i saat ini ke hasil dan Kembalikan.

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
sumber
Hal-hal kecil, tetapi Anda dapat menginisialisasi iketika Anda mendeklarasikannya, dan menyimpan byte dengan menghapus i++dari for loop, dan alih-alih membandingkan hasil 1&...dengan 0 Anda dapat menghapus pernyataan if sama sekali dan kalikan idengan hasil yang diberikan r|=i*(1&(V>>(31-l++)));di dalam loop
VisualMelon
Pintar! Saya merasa kehilangan sesuatu. Terima kasih!
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);}

Diperluas

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

Python - 37

Mirip dengan solusi @ isaacg.

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

C ++, 160

Ini bukan yang terpendek, namun hanya menggunakan 24 operasi.
Diambil dari buku Hacker's Delight.

Golf:

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

Tidak Disatukan:

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
sumber
1
Ini adalah pertanyaan kode golf. Cobalah mengurangi jumlah karakter dalam solusi Anda, bukan jumlah operasi.
FUZxxl
1

Haskell, 145 - tidak ada operasi bitwise

Bit-twiddling menganggap saya sebagai antitesis dari Haskell, jadi saya telah menghindari penggunaan operator bitwise. Program yang dihasilkan tentu saja bukan kontestan terpendek, tapi saya pikir penggunaan matematika bukannya sedikit-sedikit menarik setidaknya.

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

Penjelasan

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. menggunakan modulo untuk membawa hasilnya ke kisaran 32-bit
  2. membangun daftar 0 s dan 1s, bit paling signifikan pertama dengan berulang kali membagi dengan 2 dan mengambil sisanya
  3. menyatukan daftar tak terbatas 0 hingga s ke akhir daftar ini
  4. meraih 32 elemen pertama dari daftar (Dua yang terakhir ini diperlukan untuk memastikan daftar itu benar-benar panjang 32 bit.)
  5. mengkonversi daftar 0dan 1menjadi integer dengan asumsi bit paling signifikan adalah yang pertama (berulang ganda dan tambahkan).

Saya tidak yakin apa yang merupakan "perpustakaan standar" di Haskell jadi saya berasumsi Data.Tuple dan Data.List OK (mereka cukup standar).

Juga, outputnya adalah bilangan bulat 32-bit yang tidak ditandatangani karena perubahan itu akan menghabiskan banyak byte: Saya berpendapat ini di bawah "kelalaian adalah permainan gratis".

ballesta25
sumber
Perpustakaan standar: apa yang disertakan bersama bahasa. Ini termasuk header sistem untuk C, 4000+ kelas dan metode di Java (kebanyakan tidak relevan).
Isiah Meadows
1

PHP, 46 41 byte

coba online

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

bitwise ... lebih atau kurang. Jalankan sebagai pipa dengan php -nR '<code>'.

PHP, 46 byte

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

solusi bitwise murni; dijalankan sebagai pipa dengan-nR .

PHP, 47 59 byte

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

pendekatan bawaan lainnya; simpan ke file dan jalankan sebagai pipa dengan -F.

Titus
sumber
0

Perl - 60

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

+1 untuk p flag (beri tahu saya jika saya salah menghitung ini).

Jalankan dengan:

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

C ++ 69

int r(int n){int e=0,i=0;for(;i<32;i++)e|=((n>>i)&1)<<31-i;return e;}
rans
sumber
@ MBE apa ini e;i;? Deklarasi tanpa tipe bukan C ++ yang valid. Untuk variabel itu bahkan tidak valid C.
Ruslan
@Ruslan saya tidak mengenali '++' dalam judul, maaf. (Saya tidak akan setuju dengan pernyataan kedua Anda)
bebe
int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 byte :)
Christoph
0

R, 45

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

Contoh:

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

Selalu saja malu dengan jawaban Python. Kata kunci fungsi sialan itu.

shadowtalker
sumber
0

Rubi, 43 41 byte

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

Di Ruby, menggunakan notasi indeks braket (foo [i]) mengembalikan bit di tempat ke-n.

--Edit--

Refactoring injectfungsionalitas mencukur beberapa byte

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

marcus erronius
sumber
0

Perl5: 46

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

Tidak ada yang mewah. Ini menggeser output ke kiri, salin lsb sebelum menggeser sumber ke kanan.

Sylwester
sumber
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 - Pasang kembali Monica
sumber
0

Perl (37 + 1)

pada dasarnya port solusi C oleh Todd Lehman

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

perl Cina goth
sumber