Số bit đảo ngược (nhị phân) là gì?


33

Vì vậy, bạn được cấp một số 10 (thập phân) cơ sở TÍCH CỰC . Công việc của bạn là đảo ngược các chữ số nhị phân và trả về số 10 cơ sở đó.

Ví dụ:

1 => 1 (1 => 1)
2 => 1 (10 => 01)
3 => 3 (11 => 11)
4 => 1 (100 => 001)
5 => 5 (101 => 101)
6 => 3 (110 => 011)
7 => 7 (111 => 111)
8 => 1 (1000 => 0001)
9 => 9 (1001 => 1001)
10 => 5 (1010 => 0101)

Đây là một thử thách , vì vậy giải pháp sử dụng ít byte nhất sẽ thắng.

Đây là A030101 trong OEIS.


2
"Đảo ngược các bit" có nghĩa là đảo ngược các chữ số nhị phân của nó? Đôi khi nó cũng có thể có nghĩa là đảo ngược mọi bit .
Sản phẩm ETH

Vâng. Xin lỗi vì không rõ ràng.
juniorRubyist

Đâyđây là tương tự như vậy.
Geobits


1
"cơ sở 10" Bất kỳ lý do cụ thể tại sao?
Máy

Câu trả lời:


20

Python , 29 byte

lambda n:int(bin(n)[:1:-1],2)

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

Đây là một hàm ẩn danh, không tên, trả về kết quả.


Đầu tiên, bin(n)chuyển đổi đối số thành một chuỗi nhị phân. Chúng tôi thường sẽ đảo ngược điều này với ký hiệu lát [::-1]. Điều này đọc chuỗi với một bước -1 , tức là ngược lại. Tuy nhiên, các chuỗi nhị phân trong Python có tiền tố là một 0b, và do đó chúng tôi đưa ra đối số thứ hai của lát cắt là 1 , yêu cầu Python đọc kết thúc ngược ở chỉ mục 1 , do đó không đọc các chỉ mục 10 .

Bây giờ chúng ta có chuỗi nhị phân ngược, chúng ta chuyển nó sang int(...)với đối số thứ hai là 2 . Điều này đọc chuỗi dưới dạng một số nguyên cơ sở 2, sau đó hàm ý được trả về bởi biểu thức lambda.


2
Đánh bại bạn trong 9 giây.
mbomb007


6
@ mbomb007 vì vậy câu trả lời của tôi không hợp lệ vì bạn đã nhấp vào nút đăng bài 9 giây trước khi ra tay? Chỉ vì chúng tôi đến cùng một sân golf cùng một lúc không có nghĩa là chúng tôi phải xóa bất kỳ câu trả lời nào. Nếu bất cứ điều gì, đổ lỗi cho câu hỏi 0 nỗ lực.
FlipTack

3
Không hợp lệ, nhưng chắc chắn là vô nghĩa. Nếu tôi đã chậm hơn, tôi chỉ cần xóa của tôi và đăng nhận xét về cái nhanh hơn mà tôi đã đưa ra.
mbomb007

1
@steenbergh Ai quan tâm? Cùng mã, cùng điểm.
mbomb007


13

JavaScript (ES6), 30 28 byte

Đã lưu 2 byte nhờ @Arnauld

f=(n,q)=>n?f(n>>1,q*2|n%2):q

Điều này về cơ bản tính toán một bit đảo ngược tại một thời điểm: Chúng tôi bắt đầu với q = 0 ; Trong khi n là dương, chúng ta nhân q với 2, cắt bit cuối cùng của n với n>>1và thêm nó vào q với |n%2. Khi n đạt 0, số đã được đảo ngược thành công và chúng ta trả về q .

Nhờ các tên dựng sẵn dài của JS, giải quyết thách thức này một cách dễ dàng mất 44 byte:

n=>+[...n.toString(2),'0b'].reverse().join``

Sử dụng đệ quy và một chuỗi, bạn có thể nhận được một giải pháp 32 byte thực hiện điều tương tự:

f=(n,q='0b')=>n?f(n>>1,q+n%2):+q

f=(n,q)=>n?f(n>>1,q*2|n%2):qgần như hoạt động. Nhưng đáng buồn là không cho n=0.
Arnauld

@Arnauld OP vẫn chưa trả lời về việc liệu đầu vào sẽ luôn dương hay không, nhưng nếu vậy thì 0 không phải xử lý.
FlipTack

Đây là một theo dõi muộn, nhưng đầu vào bây giờ được biết là luôn luôn tích cực.
Arnauld

@Arnauld Cảm ơn!
Sản phẩm ETH

10

Java 8, 53 47 46 45 byte

  • -4 byte nhờ Tít
  • -1 byte nhờ Kevin Cruijssen

Đây là một biểu thức lambda có cùng nguyên tắc với câu trả lời của ETH (mặc dù đệ quy sẽ quá dài dòng trong Java, vì vậy chúng tôi lặp lại thay thế):

x->{int t=0;for(;x>0;x/=2)t+=t+x%2;return t;}

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

Điều này có thể được chỉ định với IntFunction<Integer> f = ..., và sau đó được gọi với f.apply(num). Mở rộng, không được chỉnh sửa và nhận xét, nó trông như thế này:

x -> { 
    int t = 0;           // Initialize result holder   
    while (x > 0) {      // While there are bits left in input:
        t <<= 1;         //   Add a 0 bit at the end of result
        t += x%2;        //   Set it to the last bit of x
        x >>= 1;         //   Hack off the last bit of x
    }              
    return t;            // Return the final result
};

1
Lưu 3 byte t*2thay vì (t<<1), thêm một byte khi di chuyển phép tính đó từ đầu vòng lặp sang thân vòng lặp. Bạn có thể sử dụng xthay vì x>0cho điều kiện?
Tít

2
@Titus không phải không có một diễn viên rõ ràng cho một boolean, nhưng cảm ơn vì những lời khuyên khác! Cũng chỉ nhận ra rằng x>>=1có thể được thay thế bằng x/=2nó sẽ tự động được chia số nguyên.
FlipTack

45 byte (Thay đổi t=t*2+thành t+=t+.)
Kevin Cruijssen

@KevinCruijssen một cái tốt đẹp!
FlipTack

9

J, 6 byte

|.&.#:

|. đảo ngược

&. Dưới

#: cơ sở 2




7

Mê cung, 23 byte

?_";:_2
  :   %
 @/2_"!

Chà, điều này thật khó xử ... điều này trả về số BINary ngược ... Cảm ơn @Martin Ender đã chỉ ra cả lỗi của tôi và lỗi ID 10T của tôi. Vì vậy, điều này không làm việc, tôi sẽ phải tìm một giải pháp khác.


1
Chào mừng bạn đến với PPCG, và bài đăng đầu tiên tốt đẹp! Chỉ cần hoàn thành một thử thách trong một ngôn ngữ như Labyrinth có thể rất khó khăn. Ở quanh đây, chúng tôi thường tiền tố dòng đầu tiên của câu trả lời bằng một hoặc hai lần băm, để làm cho nó hiển thị dưới dạng tiêu đề:# Labyrinth, 89 bytes
ETHproductions

1
Bạn đã vô tình bỏ sót một không gian hàng đầu từ hàng thứ hai? Khi nó đứng, chương trình sẽ chỉ bật qua lại trên dòng đầu tiên vì _nằm trên các điểm nối.
Martin Ender

Thật không may, tôi chỉ nhận thấy rằng điều này không hợp lệ bất kể, bởi vì thách thức yêu cầu đại diện cơ số 10 của số bị đảo ngược, chứ không phải đại diện nhị phân của nó.
Martin Ender

6

C, 48 44 43 42 byte

-1 byte nhờ gurka và -1 byte nhờ anatolyg:

r;f(n){for(r=n&1;n/=2;r+=r+n%2);return r;}

Giải pháp 44 byte trước đó:

r;f(n){r=n&1;while(n/=2)r=2*r+n%2;return r;}

Giải pháp 48 byte trước đó:

r;f(n){r=0;while(n)r=2*(r+n%2),n/=2;return r/2;}

Ungolfed và cách sử dụng:

r;
f(n){
 for(
  r=n&1;
  n/=2;
  r+=r+n%2
 );
 return r;}
}


main() {
#define P(x) printf("%d %d\n",x,f(x))
P(1);
P(2);
P(3);
P(4);
P(5);
P(6);
P(7);
P(8);
P(9);
P(10);
}

Không rđược khởi tạo về 0 ở đây r;f(n){r=0;, ví dụ như r=0;không cần thiết? Một lỗi đánh máy nhỏ: " Giải pháp 48 byte trước "
simon

1
@gurka Các chức năng nên được tái sử dụng.
Karl Napf

1
Tôi nghĩ rằng forcác vòng lặp luôn luôn ít nhất là ngắn như whilecác vòng lặp và thường ngắn hơn.
anatolyg

@anatolyg đại loại như : r;f(n){for(r=n&1;n/=2;r=2*r+n%2);return r;}? Ngắn hơn 1 byte, nhưng tôi không chắc nếu nó hợp lệ C (C99).
simon

Vâng; đồng thời, biến =thành +=để làm cho nó ngắn hơn và khó hiểu hơn
anatolyg

5

Ruby, 29 28 byte

->n{("%b"%n).reverse.to_i 2}

"% b"% n định dạng đầu vào n dưới dạng chuỗi nhị phân, đảo ngược, sau đó chuyển đổi lại thành số

Các trường hợp sử dụng / kiểm tra:

m=->n{("%b"%n).reverse.to_i 2}
m[1] #=> 1
m[2] #=> 1
m[3] #=> 3
m[4] #=> 1
m[5] #=> 5
m[6] #=> 3
m[7] #=> 7
m[8] #=> 1
m[9] #=> 9
m[10] #=> 5

@Titus Tôi nghĩ bạn hiểu nhầm câu trả lời. 2là cơ sở anh ấy đang chuyển đổi và nlà đầu vào. ->args{return value}là cú pháp lambda ruby
Cyoce

Bạn có thể loại bỏ dấu ngoặc đơn trong .to_i(2)?
Cyoce

@Cyoce chắc chắn rồi, cảm ơn.
Alexis Andersen


4

Java (OpenJDK) , 63 byte

a->a.valueOf(new StringBuffer(a.toString(a,2)).reverse()+"",2);

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

Cảm ơn chọc cho -12 byte và Cyoce cho -8 byte!


Mặc dù các lần gửi REPL được cho phép, chúng vẫn tuân theo quy tắc mà bạn không thể cho rằng đầu vào nằm trong các biến được xác định trước (như atrong ngữ cảnh này)
FlipTack

@FlipTack Rất tiếc. Nó ban đầu là một chức năng trước khi tôi nhớ thay thế tồn tại
Pavel

1
Ngoài ra, trong tương lai, hãy sử dụng printthay vì printlnchơi gôn :)
FlipTack

1
StringBuffertiết kiệm một byte hơnStringBuilder
Chọc

1
Bạn có thể làm +""thay vì .toString()?
Cyoce

3

Perl 6 , 19 byte

{:2(.base(2).flip)}

Đầu vào ở đâu?
Tít

Đây là một hàm có một tham số duy nhất $_. Nó không được đề cập theo tên, nhưng basephương thức được gọi trên đó.
Sean

2
@Titus trong Perl 6 a Block là một loại Mã, có nghĩa là nó là một đối tượng có thể gọi được. Trên đây là một biểu thức mà bạn có thể thực hiện và gán cho một biến như hàm hoặc lambda bằng ngôn ngữ khác hoặc gọi trực tiếp - {:2(.base(2).flip)}(10)tại REPL sẽ in 5. Vì vậy, nó đáp ứng tiêu chí golf-code tiêu chuẩn cho một hàm.
hobbs

3

Haskell, 36 byte

0!b=b
a!b=div a 2!(b+b+mod a 2)
(!0)

Cùng một thuật toán (và độ dài!) Như câu trả lời JavaScript của ETHproductions .



3

PHP, 33 byte

<?=bindec(strrev(decbin($argn)));

chuyển đổi sang cơ sở2, chuỗi ngược, chuyển đổi thành thập phân. Lưu vào tập tin và chạy như đường ống với -F.

không có nội dung:

lặp lại, 41 byte

for(;$n=&$argn;$n>>=1)$r+=$r+$n%2;echo$r;

Trong khi đầu vào đã thiết lập các bit, hãy bật một bit từ đầu vào và đẩy nó sang đầu ra. Chạy như ống với -nR.

đệ quy, 52 byte

function r($n,$r=0){return$n?r($n>>1,$r*2+$n%2):$r;}

@ JörgHülsermann 44 byte có $r+=$r. Nhưng tôi thực sự không nhớ tại sao tôi lại đặt nó ở phía trước.
Tít




2

Scala, 40 byte

i=>BigInt(BigInt(i)toString 2 reverse,2)

Sử dụng:

val f:(Int=>Any)=i=>BigInt(BigInt(i)toString 2 reverse,2)
f(10) //returns 5

Giải trình:

i =>          // create an anonymous function with a parameter i
  BigInt(       //return a BigInt contructed from
    BigInt(i)     //i converted to a BigInt
    toString 2    //converted to a binary string
    reverse       //revered
    ,           
    2             //interpreted as a binary string
  )




1

Mẻ, 62 byte

@set/an=%1/2,r=%2+%1%%2
@if %n% gtr 0 %0 %n% %r%*2
@echo %r%

Giải thích: Trên đường chuyền đầu tiên, %1chứa tham số đầu vào trong khi %2trống. Do đó, chúng tôi đánh giá nlà một nửa %1r+%1modulo 2 ( %toán tử phải được nhân đôi để trích dẫn nó). Nếu nkhông phải là 0, thì chúng ta sẽ tự gọi mình theo đuôi đệ quy nvà một biểu thức được đánh giá trên đường chuyền tiếp theo sẽ nhân đôi hiệu quả rmỗi lần.


1

C #, 98 byte

using System.Linq;using b=System.Convert;a=>b.ToInt64(string.Concat(b.ToString(a,2).Reverse()),2);

1

R, 55 byte

sum(2^((length(y<-rev(miscFuncs::bin(scan()))):1)-1)*y)

Đọc đầu vào từ stdin và do đó sử dụng binhàm từ miscFuncsgói để chuyển đổi từ thập phân sang vectơ nhị phân.


1

Pushy , 19 byte

Không có chuyển đổi cơ sở dựng sẵn!

$&2%v2/;FL:vK2*;OS#

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

Pushy có hai ngăn xếp, và câu trả lời này sử dụng rộng rãi.

Có hai phần hai chương trình này. Đầu tiên, $&2%v2/;Fchuyển đổi số thành biểu diễn nhị phân ngược của nó:

            \ Implicit: Input is an integer on main stack.
$      ;    \ While i != 0:
 &2%v       \   Put i % 2 on auxiliary stack
     2/     \   i = i // 2 (integer division)
        F   \ Swap stacks (so result is on main stack)

Cho ví dụ 10, các ngăn xếp sẽ xuất hiện như sau trên mỗi lần lặp:

1: [10]
2: []

1: [5]
2: [0]

1: [2]
2: [0, 1]

1: [1]
2: [0, 1, 0]

1: [0]
2: [0, 1, 0, 1]

Chúng ta có thể thấy rằng sau lần lặp cuối cùng, 0, 1, 0, 1đã được tạo trên ngăn xếp thứ hai - các chữ số nhị phân ngược của 10 , 0b1010.

Phần thứ hai của mã, L:vK2*;OS#được lấy từ câu trả lời trước của tôi để chuyển đổi nhị phân thành thập phân . Sử dụng phương thức giải mã và giải thích trong câu trả lời đó, nó chuyển đổi các chữ số nhị phân trên ngăn xếp thành số nguyên 10 cơ sở và in kết quả.



0

C #, 167 byte

 for(int i = 1; i <= 10; i++)
 {
 var bytes= Convert.ToString(i, 2);
 var value= Convert.ToInt32(byteValue.Reverse()); 
 console.WriteLine(value);
}

Giải trình:

Ở đây tôi sẽ lặp lại n giá trị và mỗi lần giá trị số nguyên lặp được chuyển đổi thành giá trị byte sau đó đảo ngược giá trị byte đó và giá trị byte đó được chuyển đổi thành giá trị số nguyên.


1
Chào mừng đến với trang web! Tôi không biết nhiều về C # nhưng bạn chắc chắn có rất nhiều khoảng trắng bổ sung mà tôi khuyên bạn nên xóa. Cũng không rõ làm thế nào I / O được xử lý trong đệ trình này. Đó là tiêu chuẩn để viết một hàm hoặc sử dụng STDIN(tôi nghĩ đó là console.Read()nhưng bạn có thể sẽ biết rõ hơn tôi) và STDOUT. Dù sao, chào mừng bạn đến với trang web nếu bạn muốn có thêm lời khuyên có kinh nghiệm trong việc chơi golf C # Tôi muốn giới thiệu codegolf.stackexchange.com/questions/173/ trộm
Phù thủy lúa mì

Tôi đã đánh giá thấp câu trả lời này, vì nó hoàn toàn không hoạt động. .Reverse()trở về IEnumerable<char>. Vì Convert.ToInt32không có quá tải cho IE, nên nó ném một ngoại lệ. Ngoài ra, câu trả lời không tuân theo các quy tắc cho mã golf: 1) Vì không có gì được chỉ định, bài nộp phải là một chương trình đầy đủ hoặc chức năng không chỉ là một đoạn trích. 2) các usingcâu lệnh phải được bao gồm trong số byte
raznagul

0

c / c ++ 136 byte

uint8_t f(uint8_t n){int s=8*sizeof(n)-ceil(log2(n));n=(n&240)>>4|(n&15)<<4;n=(n&204)>>2|(n&51)<<2;n=(n&172)>>1|(n&85)<<1;return(n>>s);}

Nó sẽ không chiến thắng, nhưng tôi muốn thực hiện một cách tiếp cận khác trong c / c ++ 120 byte trong hàm

#include <math.h>
#include <stdio.h>
#include <stdint.h>

uint8_t f(uint8_t n){
    int s=8*sizeof(n)-ceil(log2(n));
    n=(n&240)>>4|(n&15)<<4;
    n=(n&204)>>2|(n&51)<<2;
    n=(n&172)>>1|(n&85)<<1;
    return (n>>s);
}

int main(){
    printf("%u\n",f(6));
    return 0;
}

Để giải thích những gì tôi đang làm, tôi đã sử dụng hàm log để xác định số lượng bit được sử dụng bởi đầu vào. Hơn một loạt ba lần dịch chuyển trái / phải, bên trong / bên ngoài, chẵn / lẻ làm lật toàn bộ số nguyên. Cuối cùng một chút thay đổi để chuyển số trở lại bên phải. Sử dụng số thập phân cho dịch chuyển bit thay vì hex là một nỗi đau nhưng nó đã tiết kiệm được một vài byte.


Bạn cần phải bao gồm khai báo hàm, vì vậy đây thực sự là 163 byte . Mặc dù, nếu bạn loại bỏ khoảng trắng bên ngoài, bạn có thể rút ngắn nó xuống 136.
DJMcMayhem
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.