Xóa bit có ý nghĩa nhất từ ​​một số nguyên


29

Đầu vào

Đầu vào là một số nguyên dương duy nhất n

Đầu ra

Đầu ra là nvới bit quan trọng nhất của nó được đặt thành 0.

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

1 -> 0
2 -> 0
10 -> 2
16 -> 0
100 -> 36
267 -> 11
350 -> 94
500 -> 244

Ví dụ: 350trong nhị phân là 101011110. Đặt bit quan trọng nhất của nó (tức là 1bit ngoài cùng bên trái ) để 0biến nó thành001011110 tương đương với số nguyên thập phân 94, đầu ra. Đây là OEIS A053645 .


19
Xóa bit đáng kể nhất từ 10rõ ràng mang lại 0: D
clabacchio

@clabacchio Tôi .. nó ... ờ ... sao? (tốt đẹp)
Baldrickk

12
Dường như với tôi rằng các số 0 cũng quan trọng như các số không. Khi bạn nói "bit đáng kể nhất", bạn có nghĩa là "bit quan trọng nhất được đặt thành một".
Michael Kay

Câu trả lời:


12

C (gcc) , 49 44 40 39 byte

i;f(n){for(i=1;n/i;i*=2);return n^i/2;}

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


1
Bạn có thể thay thế i<=nbằng n/i-1 byte. Đây không phải là golf của tôi, một người khác đã cố chỉnh sửa nó vào bài viết của bạn nhưng tôi đã quay lại vì các chỉnh sửa cho các bài đăng golf không được chấp nhận theo quy tắc cộng đồng của chúng tôi.
HyperNeutrino

1
@HyperNeutrino Tôi đã thấy và chấp thuận chỉnh sửa ngay bây giờ. Không biết về quy tắc đó nhưng đó là một mẹo chơi golf tuyệt vời!
cleblanc

À được rồi. Vâng, thông thường mọi người nên đăng bình luận cho các mẹo chơi gôn và OP nên thực hiện các chỉnh sửa, nhưng nếu bạn chấp nhận nó, thì đó không thực sự là vấn đề. :)
HyperNeutrino


9

05AB1E , 5 byte

.²óo-

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

Loại bỏ các bit quan trọng nhất từ một số nguyên N là tương đương với việc tìm kiếm các khoảng cách từ N đến sức mạnh nguyên cao nhất của 2 thấp hơn so với N .

Vì vậy, tôi đã sử dụng công thức N - 2 tầng (log 2 N) :

  • - Logarit với cơ sở 2 .
  • ó - Tầng đến một số nguyên.
  • o- 2 nâng lên sức mạnh của kết quả trên.
  • - - Sự khác biệt.

1
b¦Ccũng hoạt động ... phải không? Chuyển đổi thành nhị phân, MSB luôn ở chỉ số 1, loại bỏ MSB, chuyển đổi trở lại.
Bạch tuộc ma thuật Urn

2
@MagicOctopusUrn Không có gì sai, thất bại cho 1!
Ông Xcoder

8

Thạch , 3 byte

BḊḄ

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

Giải trình

BḊḄ  Main Link
B    Convert to binary
 Ḋ   Dequeue; remove the first element
  Ḅ  Convert from binary

2
Không có hai byte mã? Điều này sẽ thay đổi kích thước tổng thể thành 5 byte.
Bartek Banachewicz

3
@BartekBanachewicz Jelly sử dụng codepage của riêng mình , trong đó các ký tự chỉ có 1 byte.
steenbergh

1
Cảm ơn bạn đã hỏi và trả lời điều này, điều đó đã làm tôi khó chịu trong một thời gian dài!
Ukko

8

C (gcc) - 59 byte

main(i){scanf("%d",&i);return i&~(1<<31-__builtin_clz(i));}

Câu trả lời gcc này chỉ sử dụng các số nguyên bit và các phép toán số học. Không có logarit ở đây! Nó có thể có vấn đề với đầu vào bằng 0 và hoàn toàn không thể mang theo được.

Đây là câu trả lời đầu tiên của tôi trên trang web này, vì vậy tôi rất thích phản hồi và cải tiến. Tôi chắc chắn đã có niềm vui với việc học các biểu thức bitwise.


1
Chào mừng bạn đến với PPCG, và câu trả lời đầu tiên tuyệt vời! Chúng tôi hy vọng bạn sẽ thích tham gia vào nhiều thử thách hơn :-)
Sản phẩm ETH

Bạn không cần một chương trình đầy đủ với main, một chức năng là một đệ trình hợp lệ . Thay đổi điều này thành một hàm và lấy đầu vào làm đối số cho hàm nói sẽ tiết kiệm 18 byte .
Steadybox

1
Bạn thậm chí có thể viết nó dưới dạng macro để lưu thêm hai byte .
Steadybox

7

MATL , 8 6 byte

B0T(XB

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

Đã lưu hai byte nhờ Cinaski. Chuyển sang lập chỉ mục gán thay vì lập chỉ mục tham chiếu ngắn hơn 2 byte :)

Giải trình:

          % Grab input implicitly: 267
B         % Convert to binary: [1 0 0 0 0 1 0 1 1]
 0T(      % Set the first value to 0: [0 0 0 0 0 1 0 1 1]
    XB    % Convert to decimal: 11

1
Bạn có thể đã sử dụng lập chỉ mục tham chiếu (cũng cho 6 byte), nếu bạn đã sử dụng 4Lchứ không phải [2J]. 6 byte thú vị khác: tZlcW-(chỉ hoạt động trong MATLAB, không hoạt động trong TIO / Octave)
Sanchise

6

Java (OpenJDK 8) , 23 byte

n->n^n.highestOneBit(n)

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

Xin lỗi, tích hợp: - /


Java có tích hợp sẵn mà một số ngôn ngữ phổ biến khác như .NET và Python không có?! o.Ô +1 đến đó. Đã sắp đăng một cái gì đó dài hơn mà không cần xây dựng .. Của bạn ngắn hơn 15 byte. XD
Kevin Cruijssen

@KevinCruijssen Một cái gì đó giống như n->n^1<<(int)Math.log2(n)sẽ hoạt động và có khả năng ngắn hơn 38 byte. Đó là ý tưởng thứ hai (chưa được kiểm chứng) của tôi, nếu ý tưởng highestOneBitđó không hoạt động phù hợp. Vì tò mò, giải pháp của bạn là gì
Olivier Grégoire

Của tôi là n->n^1<<(int)(Math.log(n)/Math.log(2))Math.log2không tồn tại trong Java. ; P Chỉ Math.log, Math.log10Math.loglpcó sẵn.
Kevin Cruijssen

2
I was going to post the same, only minus instead of xor. Remembered the method from this
JollyJoker

1
@KevinCruijssen Oops, Math.log2 doesn't exist indeed... My bad. See? One nice method (highestOneBit) exists but not another one (Math.log2). Java is weird ;-)
Olivier Grégoire

6

Husk, 3 bytes

ḋtḋ

Try it online!

Explanation:

    -- implicit input, e.g. 350
  ḋ -- convert number to list of binary digits (TNum -> [TNum]): [1,0,1,0,1,1,1,1,0]
 t  -- remove first element: [0,1,0,1,1,1,1,0]
ḋ   -- convert list of binary digits to number ([TNum] -> TNum): 94

Similarly to the Jelly solution, this seems like it's actually 5 bytes, not 3.
Bartek Banachewicz

1
@BartekBanachewicz Similarly to Jelly, Husk uses its own codepage, so this is actually 3 bytes :P
HyperNeutrino

@BartekBanachewicz See here for the codepage: github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2, 27 bytes

lambda n:n-2**len(bin(n))/8

Try it online!

Explanation

lambda n:n-2**len(bin(n))/8  # Lambda Function: takes `n` as an argument
lambda n:                    # Declaration of Lambda Function
              len(bin(n))    # Number of bits + 2
           2**               # 2 ** this ^
                         /8  # Divide by 8 because of the extra characters in the binary representation
         n-                  # Subtract this from the original

...Just when I was working the bitwise math out. :P
totallyhuman

@totallyhuman heh sorry but beat you to it :P
HyperNeutrino

2**len(bin(n))/8 can also be spelled 1<<len(bin(n))-3, and then it will work in both 2 and 3 (no bytes saved/added).
Mego

@Mego Cool, thanks for the addition!
HyperNeutrino

5

Python 3, 30 bytes

-8 bytes thanks to caird coinheringaahing. I typed that from memory. :o

lambda n:int('0'+bin(n)[3:],2)

Try it online!



Well, a) that would error on 1, b) I'm dumb enough to not think of that. But I did fix it with a minor change. Thanks!
totallyhuman

I've edited the code so that it works, (and saves 4 bytes)
caird coinheringaahing

That still errors on 1.
totallyhuman

@cairdcoinheringaahing That was my original answer, but then I realised it errored on 1. The workaround ends up longer than a simple XOR method
FlipTack


4

JavaScript, 22 20 bytes

Saved 2 bytes thanks to ovs

a=>a^1<<Math.log2(a)

Try it online!

Another approach, 32 bytes

a=>'0b'+a.toString`2`.slice`1`^0

Try it online!


why would you do .slice`1`^0 when .slice(1)^0 would work just as well, haha
ETHproductions

@ETHproductions. This one looks better :)

4

J, 6 bytes

}.&.#:

Pretty simple.

Explanation

}.&.#:
    #:  convert to list of binary digits
  &.    apply right function, then left, then the inverse of right
}.      behead

I was going to post this :(
Cyoce

@Cyoce Me too...
Adám

4

APL (Dyalog), 10 bytes

Tacit prefix function.

212∘⊥⍣¯1

Try it online!

2∘⊥… decode from base-2…
 …⍣¯1 negative one time (i.e. encode in base-2)

1↓ drop the first bit

2⊥ decode from base-2


4

Ruby, 26 bytes

-7 Bytes thanks to Ventero. -2 Bytes thanks to historicrat.

->n{/./=~'%b'%n;$'.to_i 2}

You can save a few bytes by just skipping the first character and dropping redundant parentheses: ->n{n.to_s(2)[1..-1].to_i 2}
Ventero

->n{/./=~'%b'%n;$'.to_i 2}
histocrat

4

C (gcc), 38 bytes

Built-in in gcc used.

f(c){return c^1<<31-__builtin_clz(c);}

Replacing 31- with ~ should save two bytes.

@ThePirateBay it depends on hardware whether the shift is masked. On my computer, it will output 0.
Colera Su

4

ARM Assembly, 46 43 bytes

(You can omit destination register on add when same as source)

clz x1,x0
add x1,1
lsl x0,x1
lsr x0,x1
ret

What flavour of ARM assembly syntax is this? My GNU assembler doesn't understand shr/shl/ret and wants instead something like lsr/lsl/bx lr.
Ruslan

Probably mixing syntax across multiple versions (ret is from aarch64), though I thought that the assembler would pseudo op these for you. For purposes of here, though, using the older and direct lsl/lsr is probably correct.
Michael Dorgan

Funny thing, i can do it in 1 less operation, but I the byte size goes up by 2. Ah code golf.
Michael Dorgan

3

Pyth, 5 bytes

a^2sl

Test suite.

Explanation:

    l   Log base 2 of input.
   s    Cast ^ to integer (this is the position of the most significant bit.)
 ^2     Raise 2 to ^ (get the value of said bit)
a       Subtract ^ from input

3

Alice, 8 bytes

./-l
o@i

Try it online!

Explanation

.   Duplicate an implicit zero at the bottom of the stack. Does nothing.
/   Switch to Ordinal mode, move SE.
i   Read all input as a string.
l   Convert to lower case (does nothing, because the input doesn't contain letters).
i   Try reading all input again, pushes an empty string.
/   Switch to Cardinal mode, move W.
.   Duplicate. Since we're in Cardinal mode, this tries to duplicate an integer.
    To get an integer, the empty string is discarded implicitly and the input is 
    converted to the integer value it represents. Therefore, at the end of this,
    we get two copies of the integer value that was input.
l   Clear lower bits. This sets all bits except the MSB to zero.
-   Subtract. By subtracting the MSB from the input, we set it to zero. We could
    also use XOR here.
/   Switch to Ordinal, move NW (and immediately reflect to SW).
o   Implicitly convert the result to a string and print it.
/   Switch to Ordinal, move S.
@   Terminate the program.

3

Japt, 6 bytes

^2p¢ÊÉ

Try it online!

Explanation

^2p¢ÊÉ
   ¢     Get binary form of input
    Ê    Get length of that
     É   Subtract 1
 2p      Raise 2 to the power of that
^        XOR with the input

If input 1 can fail: 4 bytes

¢Ån2

Try it online!

Explanation: get input binary (¢), slice off first char (Å), parse as binary back to a number (n2).




3

CJam, 7 bytes

{2b()b}

Try it online!

Explanation:

{     }  Block:         267
 2b      Binary:        [1 0 0 0 0 1 0 1 1]
   (     Pop:           [0 0 0 0 1 0 1 1] 1
    )    Increment:     [0 0 0 0 1 0 1 1] 2
     b   Base convert:  11

Reuse the MSB (which is always 1) to avoid having to delete it; the equivalent without that trick would be {2b1>2b} or {2b(;2b}.


3

Retina, 15 13 bytes

^(^1|\1\1)*1

Try it online!

Input and output in unary (the test suite includes conversion from and to decimal for convenience).

Explanation

This is quite easy to do in unary. All we want to do is delete the largest power of 2 from the input. We can match a power of 2 with some forward references. It's actually easier to match values of the form 2n-1, so we'll do that and match one 1 separately:

^(^1|\1\1)*1

The group 1 either matches a single 1 at the beginning to kick things off, or it matches twice what it did on the last iteration. So it matches 1, then 2, then 4 and so on. Since these get added up, we're always one short of a power of 2, which we fix with the 1 at the end.

Due the trailing linefeed, the match is simply removed from the input.


3

R, 28 bytes

function(x)x-2^(log2(x)%/%1)

Try it online!

Easiest to calculate the most significant bit via 2 ^ floor(log2(x)) rather than carry out base conversions, which are quite verbose in R


3

PARI/GP, 18 bytes

n->n-2^logint(n,2)

Alternate solution:

n->n-2^exponent(n)

The first one seems to give wrong answers. Should it be n->n-2^logint(n,2)? The second one is not supported in my version of PARI/GP, nor in the version used by tio.run. Is that a new function?
Jeppe Stig Nielsen

@JeppeStigNielsen Oops, fixed -- that's what I get for submitting from my phone. Yes, the second one is a new function.
Charles

@JeppeStigNielsen I just checked, exponent was added 5 days ago, compared to this challenge which was added yesterday. :)
Charles



3

Excel, 36 31 bytes

-5 bytes thanks to @IanM_Matrix1

=BIN2DEC(MID(DEC2BIN(A1),2,99))

Nothing interesting.


Reduce the size to 31 bytes by replacing REPLACE with a MID: =BIN2DEC(MID(DEC2BIN(A1),2,99))
IanM_Matrix1
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.