Thứ tự bit đảo ngược của số nguyên 32 bit


21

Viết mã ngắn nhất để đảo ngược thứ tự bit của số nguyên 32 bit.

Quy tắc:

  1. Đầu vào được coi là một số nguyên hoặc chuỗi tương đương nếu ngôn ngữ của bạn không hỗ trợ các giá trị số (ví dụ: Windows Batch).
  2. Đầu ra phải là số nguyên hoặc chuỗi hợp lệ tương đương nếu ngôn ngữ của bạn không hỗ trợ các giá trị số (ví dụ: Windows Batch).
  3. Chỉ thư viện tiêu chuẩn.
  4. Nó có thể là một chức năng hoặc một chương trình hoàn chỉnh.
  5. Đầu vào có thể từ stdinhoặc là một đối số chức năng.
  6. Đầu ra phải là stdouthoặc là một giá trị trả về.
  7. Nếu ngôn ngữ của bạn có chức năng thư viện chuẩn hoặc tích hợp thực hiện điều này trong một bước (ví dụ: rbittrong lắp ráp ARM), thì không thể sử dụng ngôn ngữ đó.

Ví dụ:

Chìa khóa:

  1. số thập phân
    • nhị phân
    • (đảo ngược)
    • nhị phân đảo ngược
    • đầu ra thập phân

Ví dụ:

  1. -90 (Ví dụ 8 bit để trình diễn)

    • 10100110b
    • (đảo ngược)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (đảo ngược)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (đảo ngược)
    • 01100101100110001011001010100011b
    • 1704506019

Lưu ý: Bỏ sót là trò chơi miễn phí. Nếu tôi không nói, và đó không phải là một trong những sơ hở tiêu chuẩn , thì nó hoàn toàn được phép.


"Thiếu sót" trong "thiếu sót là trò chơi miễn phí" nghĩa là gì?
Todd Lehman

1
Bất cứ điều gì không được nêu rõ ràng trong các quy tắc.
Isiah Meadows

Bảng tĩnh 16gb có được tính là một phần của thời lượng chương trình không?
Hot Licks

@HotLicks Theo cách giải thích điển hình của chương trình, vâng.
FUZxxl

ngôn ngữ chỉ hỗ trợ đầu vào 8 bit, chúng ta có thể lấy đầu vào làm bốn số 8 bit không?
Sparr

Câu trả lời:


0

lắp ráp x86, 9 byte

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

Ở dạng byte : 33 C0 40 D1 E9 13 C0 73 FA, 9 byte.


Điều đó một lần nữa chính xác là miễn là giải pháp của tôi nếu bạn (a) tuân theo quy ước gọi cdecl và (b) thực sự trở về từ hàm.
FUZxxl

@FUZxxl Bằng cách nào đó, tôi đã không thấy phiên bản của bạn. Bạn hoàn toàn chính xác. Tôi đã suy nghĩ __fastcallvà không có ret.
Myria

24

Lắp ráp MMIX (28 byte)

Số 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

Điều này lắp ráp để:

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

Làm thế nào nó hoạt động?

Lệnh này MORthực hiện phép nhân ma trận trên hai đại lượng 64 bit được sử dụng làm hai ma trận 8 x 8 của booleans. Một số boolean có chữ số abcdefghklmnopqr 2 được sử dụng như một ma trận như thế này:

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

Lệnh này MORnhân các ma trận được biểu thị bằng các đối số của chúng trong đó phép nhân andvà phép cộng là or. Nó là:

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

và hơn thế nữa:

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

đó là thứ tự đảo ngược của các bit của số ban đầu.

Số 32 bit

Nếu bạn chỉ muốn đảo ngược số 32 bit thay vì số 64 bit, bạn có thể sử dụng phương pháp sửa đổi này:

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

lắp ráp:

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

Phép nhân ma trận đầu tiên về cơ bản hoạt động như thế này:

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

octabyte tương ứng là #0000000001020408cái mà chúng ta tải trong hai hướng dẫn đầu tiên. Phép nhân thứ hai trông như thế này:

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

Octabyte tương ứng là #0102040810204080cái mà chúng ta tạo ra từ ma trận đầu tiên như thế này:

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

Phép nhân thứ hai là kinh doanh như bình thường, mã kết quả có cùng độ dài (28 byte).


1
đây là lần đầu tiên tôi nghe về hướng dẫn nhân ma trận trên CPU
phuclv

@ LưuViênPhúc: Không phải là phép nhân ma trận, nhưng VAX đã có một hướng dẫn để đánh giá một đa thức .
nneonneo

1
@nneonneo POLYHướng dẫn của VAX về cơ bản là một phép nhân và cộng với một vòng lặp dựng sẵn. Những điều tương tự cũng tồn tại trong các kiến ​​trúc hiện đại (như x86), nhưng chúng thường không có vòng lặp dựng sẵn để đánh giá toàn bộ đa thức cùng một lúc.
FUZxxl

12

Lắp ráp 80386 ( 13 12 byte)

Là một hàm trong cú pháp AT & T sử dụng quy ước gọi 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

Hàm này tập hợp thành chuỗi byte sau:

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

Chia nhỏ thành hướng dẫn:

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    

Nó hoạt động như thế này: Trong mỗi 32 lần lặp của vòng lặp, đối số, được đặt tại 4(%esp) , được dịch chuyển sang phải bởi một vị trí. Bit cuối cùng được ngầm chuyển sang cờ mang. Các adchướng dẫn thêm hai giá trị và cho biết thêm giá trị của lá cờ carry đến kết quả. Nếu bạn thêm một giá trị cho chính nó, tức là %eax, bạn thực sự dịch chuyển nó sang một vị trí. Điều này làm cho adc %eax,%eaxmột cách thuận tiện để dịch chuyển trái sang %eaxmột vị trí trong khi chuyển nội dung của cờ mang sang bit thứ tự thấp.

Tôi lặp lại quá trình này 32 lần để toàn bộ nội dung 4(%esp)được đổ vào %eax. Tôi không bao giờ khởi tạo một cách rõ ràng %eaxvì nội dung trước đó của nó được chuyển ra trong vòng lặp.


+1 Cảm ơn câu cuối cùng của bạn, bây giờ rõ ràng nhưng tôi đã bỏ lỡ điều đó.
edc65

1
Tôi luôn vui khi thấy các giải pháp lắp ráp tại đây :)
user1354557

8

C,    63    52   48

Phiên bản gốc:

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

Phiên bản cập nhật (với các thay đổi được bao gồm bởi Allbeert , es1024Dennis ):

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

Lưu ý: Vì phiên bản thứ hai bỏ qua cài đặt r=0, mã giả định rằng an intlà 32 bit. Nếu giả định này là sai, rất có thể hàm sẽ tạo ra kết quả không chính xác, tùy thuộc vào trạng thái ban đầu củar mục nhập vào hàm.


Phiên bản cuối cùng (với những thay đổi tiếp theo được đề xuất bởi DennisAlchymist ):

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

Lưu ý: Điều này đặt khai báo các biến công việc rivào danh sách tham số. Các tham số như sau: nlà số được đảo ngược bit. rilà các biến công việc phải được thông qua là 0.


1
Bạn có thể loại bỏ loại inthàm và cũng thay đổi return rthành loại như i=rvì hầu hết các trình biên dịch C có xu hướng để lại kết quả của thao tác cuối cùng trong thanh ghi trả về. Nó làm việc trên gcc và cl cho tôi.
Allbeert

1
Bạn có thể tắt 4 byte khác bằng cách sử dụng r(n){...}thay vìr(int n){...}
es1024

2
@FUZxxl bạn không thể thả intvào int r=0,i=32;trừ khi bạn di chuyển chúng ra khỏi thân chức năng.
es1024

1
@FUZxxl: Không nên bình luận khi tôi mệt mỏi ... Sự thay đổi và phân chia số học không tương đương; vòng sau hướng về 0, trong khi vòng đầu tiên hướng về vô cực âm. -1 >> 1-1cho AS và 2**31 - 1cho LS, trong khi -1 / 20.
Dennis

1
@Todd: Bất kỳ lý do nào bạn không xác định rilàm đối số? Sẽ tiết kiệm thêm ba byte ...
Dennis

5

Julia 0,2, 33 byte

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

Liệu nó trông như thế nào.

bits cung cấp cho bạn đại diện bit (tôn trọng bổ sung của hai). parseintkhông quan tâm đến phần bù của hai, nhưng trả về số nguyên 32 bit, vì vậy phần bù của hai phần đơn giản được xử lý bằng cách tràn.

Theo các thay đổi, phát hiện tràn đã được thêm vào parseinttrong Julia 0.3, vì vậy điều này có thể không hoạt động nữa.


5
Đây là mã sản xuất, không phải mã golf! xD Tôi đoán Julia thật tuyệt.
cjfaure

4

Con trăn 2, 50

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

Nhìn rộng giống như giải pháp Pyth của tôi. Lấy mod đầu vào 2 ** 32, chuyển đổi thành nhị phân đệm 32 bit, đảo ngược, chuyển đổi nhị phân trở lại thành số thập phân và in.


4

CJam, 15 byte

li4H#+2bW%32<2b

Hãy thử trực tuyến.

Joker "trò chơi miễn phí" được sử dụng: Đầu ra sẽ luôn là một số nguyên không dấu .

Các trường hợp thử nghiệm

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

Làm thế nào nó hoạt động

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

Chức năng, số đầu vào và trả về số đảo ngược. Thuật toán cơ bản nhất, có lẽ có thể được chơi golf nhiều hơn với một số mẹo thông minh.

Chỉnh sửa đệ quy thay vì vòng lặp

Chỉnh sửa 2 Theo đề xuất @bebe k*2thay vìk<<1

Chỉnh sửa 3 Một cái gì đó tôi đã bỏ lỡ: đó là một vòng lặp 32 bit đầy đủ, không cần phải khởi tạo k. Cảm ơn @FUZxxl

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

Đó là

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

Kiểm tra trong bảng điều khiển FireFox, kiểm tra bằng cách sử dụng các số trong OP và một số số 16 và 32 bit ngẫu nhiên khác

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

Ví dụ về đầu ra thử nghiệm

        -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để sử dụng duy nhất và R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):klà tái sử dụng
bebe

@bebe :( Tôi đã xem lại câu trả lời của mình bằng cách sử dụng đệ quy và mất tất cả để đọc nhận xét của bạn ...
edc65

2
bạn ở mức 38 byte nếu k<<1trở thành k*2v>>1trở thành v/2. nó làm việc cho 486. Tôi không biết về trường hợp thử nghiệm khác
bebe

1
@bebe v / 2 sẽ không hoạt động đối với các số âm. 486/512 == 0.9 ... và 486 >> 9 == 0, cắt nó giống nhau. Nhưng -90/128 == -0,7 ... và -90 >> 7 == - 1
edc65

4

x86 lắp ráp, 10 byte

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

Điều này giả sử đầu vào trong eax, đầu ra trong edx. (Ngoài ra, trên đầu ra eax là 0 và CF và ZF được đặt, nếu có ai quan tâm).

Thay vì bộ đếm, thêm 1 được đẩy vào đầu như là điểm đánh dấu dữ liệu cuối


Điều này thực sự có cùng kích thước với giải pháp của tôi, lớn hơn ba byte. Nếu bạn thêm retlệnh để trả về từ hàm và triển khai cdecl (nghĩa là thay đổi rcr %eaxthành rcr 4(%esp)rcl %edxthành rcl %eax), bạn sẽ có thêm một byte cho retvà hai byte khác cho tham chiếu bộ nhớ. Tuy nhiên, một giải pháp tốt đẹp.
FUZxxl

3

J ( 17 15 13 byte)

_32#.@|.@{.#:

Dưới đây là một định nghĩa rõ ràng để giải thích những gì nó làm:

3 : '#. |. _32 {. #: y'
  1. #: yđại diện ynhư một số cơ sở 2 sử dụng càng nhiều nơi càng cần thiết.
  2. x {. ylấy |x(độ lớn x) của các mục từ y, từ phía trước nếu xdương, từ phía sau nếu xâm. Nếu chúng ta lấy nhiều vật phẩm hơn hiện tại, kết quả được đệm bằng số không. _32 {. #: ymiếng đệm hiệu quả #: yđến 32 bit.
  3. |. ylật y, tôi. đảo ngược thứ tự của các mục trong y.
  4. #. y giải thích ynhư là một số cơ sở-2.


2

Con trăn - 89

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

Python đại diện cho số nhị phân âm là đơn giản -0b{positive_number} . Vì vậy, để giải quyết vấn đề này, hãy bổ sung các số âm và sau đó là XOR với tất cả 1.

Sau đó, tạo biểu diễn chuỗi của số nguyên dựa trên định dạng {:032b}cung cấp biểu diễn 32 bit của số. Cuối cùng, đảo ngược chuỗi và biến nó trở lại thành một số nguyên.

CHỈNH SỬA

Cảm ơn @Martin Büttner đã chỉ ra vấn đề bổ sung của hai người. Nếun kết thúc bằng 1 thì bằng hai phần bù, phiên bản đảo ngược sẽ là số âm.

May mắn thay, như đã giải thích ở trên, Python thích các số nhị phân âm theo cách khá đơn giản. Cũng may, inthàm của Python cho phép các ký tự ký tự tùy chọn trong đối số đầu tiên.

Vì vậy, bây giờ, thêm một dấu trừ nếu nlà số lẻ để đáp ứng phần bù của hai.


@ MartinBüttner Cảm ơn. Tôi đã bỏ lỡ khả năng đó lúc đầu. Mã mới xử lý bổ sung của hai tốt hơn.
BeetDemGuise

2
Bạn có thể chơi golf mà hơn một chút: ['','-'][n%2]'-'*(n%2).
Justin

2

Bình thường , 33 32 22

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

Giải trình:

                 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.

Sân gôn:

33 -> 32: Đã thêm di chuyển vào trước khi đảo ngược để lưu trích dẫn kết thúc.

32 -> 22: Sử dụng Q mod 2 ^ 32 thay vì máy móc phức tạp. Kết hợp cả hai chuỗi thành một.

Các trường hợp thử nghiệm:

$ 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

Liệu nó có hoạt động với kết quả là 32 số lớn có bit trái nhất ở 1 không? Trong trường hợp này, nó sẽ xuất ra một số nguyên âm.
edc65

@ edc65 Tôi xuất ra một số nguyên không dấu 32 bit.
isaacg

2

GNU dc, 27 byte

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

Đầu ra:

$ 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

Đầu ra:

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

Hàm C, 89 byte

Ý tưởng tương tự như /codegolf//a/36289/11259 - sử dụng các bản hack twiddling của Stanford . Tuy nhiên, sẽ không giành được giải golf, nhưng dù sao cũng thú vị:

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

Đầu ra:

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

2

Hàm Java, 64 ký tự.

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

Cũng nên làm việc trong C.


2

PHP, 46 byte

Phiên bản trực tuyến

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

hoặc là

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

Không substrcần thiết (-12 byte). Bạn nên đề cập đến cách chạy chúng.
Tít

1
@Titus bạn đã thử testcase -984802906chưa?
Jörg Hülsermann

1
Phiên bản thứ hai của bạn có thể được cải thiện để phù hợp với phiên bản đầu tiên:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph

@Christoph cải thiện rất tốt Cảm ơn bạn
Jörg Hülsermann

1

Mã số 115

Chà trông không ổn chút nào: D

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

Phương thức của @Florian F trong JS dài 53 byte:

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

1
Các it may be a functionphương tiện quy tắc bạn không cần phải cảnh báo hoặc nhắc nhở
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;}

Các hoạt động bit mà hầu như có thể được thực hiện ngắn hơn trong tất cả các ngôn ngữ lập trình.

Về cơ bản, lặp qua tất cả các lũy thừa từ 2 đến tối đa nguyên + 1 (Biến thành lũy thừa của hai) và kể từ (2.147,483,647 + 1) = 0 Tôi có thể lặp sang 0. Bit dịch chuyển sang trái sang phải để di chuyển bit vào đầu tiên Chức vụ. Bit cuối cùng ở vị trí 32 đi 31 bước sang phải, giây cuối cùng đi 30, v.v ... Vì vậy, bằng cách sử dụng toán tử AND với 1 tôi sẽ biết nếu đó là 1 hoặc 0. Nếu là 1 tôi sẽ thêm giá trị i hiện tại vào kết quả và trả lạ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;
 }

Những điều nhỏ nhặt, nhưng bạn có thể khởi tạo ikhi bạn khai báo nó và lưu một byte bằng cách xóa i++khỏi vòng lặp for và thay vì so sánh kết quả 1&...với 0, bạn có thể loại bỏ hoàn toàn câu lệnh if và nhân ivới kết quả đưa ra r|=i*(1&(V>>(31-l++)));bên trong vòng lặp
VisualMelon

Tài giỏi! Tôi có cảm giác mình đang thiếu thứ gì đó. Cảm ơn!
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);}

Mở rộng

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

1

Con trăn - 37

Tương tự như giải pháp của @ isaacg.

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

1

C ++, 160

Đây không phải là ngắn nhất, tuy nhiên nó chỉ sử dụng 24 thao tác.
Lấy từ cuốn sách Delight Delight.

Chơi gôn

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

Ung dung:

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
Đây là một câu hỏi golf mã. Hãy cố gắng giảm số lượng ký tự trong giải pháp của bạn, không phải số lượng các hoạt động.
FUZxxl

1

Haskell, 145 - không hoạt động bitwise

Xoay vòng bit tấn công tôi như là phản đề của Haskell, vì vậy tôi đã tránh sử dụng các toán tử bitwise. Chương trình kết quả chắc chắn không phải là thí sinh ngắn nhất, nhưng tôi nghĩ rằng việc sử dụng toán học thay vì xoay vòng bit ít nhất là thú vị.

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

Giải trình

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. sử dụng modulo để đưa kết quả vào phạm vi 32 bit
  2. xây dựng một danh sách 0s và 1s, bit có ý nghĩa nhỏ nhất trước tiên bằng cách chia 2 lần và lấy phần còn lại
  3. nối một danh sách vô hạn của 0s đến cuối danh sách này
  4. lấy 32 phần tử đầu tiên của danh sách (Hai phần tử cuối cùng này là cần thiết để đảm bảo danh sách thực sự dài 32 bit.)
  5. chuyển đổi một danh sách 01thành một số nguyên giả sử bit quan trọng nhất là đầu tiên (lặp lại gấp đôi và thêm).

Tôi không chắc chắn cái gì tạo thành "thư viện chuẩn" trong Haskell vì vậy tôi giả sử Data.Tuple và Data.List đều ổn (chúng khá chuẩn).

Ngoài ra, đầu ra là một số nguyên 32 bit không dấu kể từ khi thay đổi sẽ khiến tôi phải trả giá bằng byte: Tôi đang tranh luận điều này trong phần "thiếu sót là trò chơi miễn phí".


Thư viện chuẩn: những gì tàu với ngôn ngữ. Điều này bao gồm các tiêu đề hệ thống cho C, hơn 4000 lớp và phương thức trong Java (hầu hết là không liên quan).
Isiah Meadows

1

PHP, 46 41 byte

thử chúng trực tuyến

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

bitwise ... nhiều hay ít. Chạy như ống với php -nR '<code>'.

PHP, 46 byte

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

một giải pháp bitwise tinh khiết; chạy như ống với -nR.

PHP, 47 59 byte

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

một cách tiếp cận tích hợp khác; lưu vào tập tin và chạy như đường ống với -F.


0

Perl - 60

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

+1 cho cờ p (cho tôi biết nếu tôi đang đếm sai).

Chạy với:

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 đây là những e;i;gì? Các khai báo không có loại không phải là một C ++ hợp lệ. Đối với các biến, nó thậm chí không hợp lệ C.
Ruslan

@Ruslan tôi không nhận ra '++' trong tiêu đề, xin lỗi. (tôi sẽ không đồng ý với tuyên bố thứ hai của bạn)
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")

Ví dụ:

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

Luôn luôn chỉ ngại các câu trả lời của Python. Đó là từ khóa chức năng chết tiệt.


0

Hồng ngọc 43 41 byte

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

Trong Ruby, sử dụng ký hiệu chỉ số khung (foo [i]) trả về bit ở vị trí thứ n.

--Chỉnh sửa--

Tái cấu trúc injectchức năng cạo một vài byte

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}

Không có gì lạ mắt. Nó dịch chuyển đầu ra sang trái, sao chép lsb trước khi dịch chuyển nguồn sang phải.


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

0

Perl (37 + 1)

về cơ bản là một cổng của giải pháp C của Todd Lehman

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.