การล้างบิตที่สำคัญที่สุดจากจำนวนเต็ม


29

อินพุต

อินพุตเป็นจำนวนเต็มบวกเดียว n

เอาท์พุต

เอาท์พุทเป็นชุดบิตมากที่สุดอย่างมีนัยสำคัญn0

กรณีทดสอบ

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

ตัวอย่างเช่นในไบนารี350 101011110การตั้งค่าบิตที่สำคัญที่สุดของมัน (เช่น1บิตซ้ายสุด) เพื่อ0เปลี่ยนให้เป็น001011110ซึ่งเทียบเท่ากับจำนวนเต็มทศนิยม94คือผลลัพธ์ นี่คือOEIS A053645


19
การล้างบิตที่สำคัญที่สุดจากการ10ให้ชัด0: D
clabacchio

@clabacchio ฉัน .. มัน ... เอ่อ ... เอ๊ะ? (คนดี)
Baldrickk

12
สำหรับฉันแล้วมันดูเหมือนว่าเลขศูนย์นั้นสำคัญเท่ากับของศูนย์ เมื่อคุณพูดว่า "บิตที่สำคัญที่สุด" คุณหมายถึง "บิตที่สำคัญที่สุดที่ตั้งค่าเป็นหนึ่ง"
Michael Kay

คำตอบ:


12

C (gcc) , 49 44 40 39 ไบต์

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

ลองออนไลน์!


1
คุณสามารถแทนที่i<=nด้วยn/i-1 ไบต์ นี่ไม่ใช่กอล์ฟของฉันคนอื่นพยายามแก้ไขในโพสต์ของคุณ แต่ฉันย้อนกลับเพราะการแก้ไขโพสต์กอล์ฟไม่ได้รับการยอมรับตามกฎชุมชนของเรา
HyperNeutrino

1
@HyperNeutrino ฉันเห็นและอนุมัติการแก้ไขในตอนนี้ ไม่ทราบถึงกฎนั้น แต่มันก็เป็นทิปกอล์ฟที่ดี!
cleblanc

อ่าโอเค. โดยปกติแล้วคนทั่วไปควรโพสต์ความคิดเห็นสำหรับเคล็ดลับการเล่นกอล์ฟและ OP ควรทำการแก้ไข แต่ถ้าคุณยอมรับมันก็ไม่ได้เป็นปัญหามากนัก :)
HyperNeutrino


9

05AB1E , 5 ไบต์

.²óo-

ลองออนไลน์!

การถอดบิตที่สำคัญที่สุดจากจำนวนเต็มNเทียบเท่ากับการหาระยะทางจากNอำนาจสูงสุดของจำนวนเต็ม2ต่ำกว่าN

ดังนั้นฉันใช้สูตรN - 2 ชั้น (บันทึก2 N) :

  • - ลอการิทึมฐาน2
  • ó - ชั้นถึงจำนวนเต็ม
  • o- 2ยกกำลังของผลลัพธ์ที่ได้จากด้านบน
  • - - ความแตกต่าง

1
b¦Cยังใช้งานได้ ... แปลงเป็นไบนารี่, MSB อยู่ที่ดัชนี 1, ลบ MSB, แปลงกลับ
Magic Octopus Urn

2
@MagicOctopusUrn ไม่ผิดมันล้มเหลว1!
นาย Xcoder

8

เยลลี่ 3 ไบต์

BḊḄ

ลองออนไลน์!

คำอธิบาย

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

2
ไม่ได้และสองไบต์ codepoints? นี่จะเปลี่ยนขนาดโดยรวมเป็น 5 ไบต์
Bartek Banachewicz

3
@BartekBanachewicz Jelly ใช้เพจรหัสของตัวเองโดยที่ตัวอักษรเหล่านั้นมีขนาดเพียง 1 ไบต์
steenbergh

1
ขอบคุณที่ถามและตอบคำถามนี้ที่บั๊กฉันมานาน!
Ukko

8

C (gcc) - 59 ไบต์

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

คำตอบ gcc นี้ใช้การดำเนินการทางเลขคณิตบิตเลขจำนวนเต็มเท่านั้น ไม่มีลอการิทึมที่นี่! มันอาจมีปัญหากับการป้อนข้อมูลเป็น 0 และเป็นแบบพกพาโดยสิ้นเชิง

มันเป็นคำตอบแรกของฉันในเว็บไซต์นี้ดังนั้นฉันชอบข้อเสนอแนะและการปรับปรุง ฉันแน่ใจว่าสนุกกับการเรียนรู้การแสดงออกในระดับบิต


1
ยินดีต้อนรับสู่ PPCG และคำตอบแรกที่ยอดเยี่ยม! เราหวังว่าคุณจะสนุกกับการมีส่วนร่วมในความท้าทายอื่น ๆ อีกมากมาย :-)
ETHproductions

คุณไม่จำเป็นต้องเป็นโปรแกรมที่เต็มไปด้วยmain, ฟังก์ชั่นเป็นส่งที่ถูกต้อง การเปลี่ยนแปลงนี้ในการทำงานและการป้อนข้อมูลเป็นอาร์กิวเมนต์ฟังก์ชั่นกล่าวว่าจะช่วยประหยัด 18 ไบต์
Steadybox

1
คุณยังสามารถเขียนเป็นแมโครเพื่อบันทึกไบต์ที่สองมากขึ้น
Steadybox

7

MATL , 8 6 ไบต์

B0T(XB

ลองออนไลน์!

บันทึกสองไบต์ด้วย Cinaski การสลับเป็นการทำดัชนีที่ได้รับมอบหมายแทนที่จะทำดัชนีอ้างอิงนั้นสั้นกว่า 2 ไบต์ :)

คำอธิบาย:

          % 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
คุณอาจจะมีการจัดทำดัชนีการอ้างอิงที่ใช้ (หรือ 6 bytes) ถ้าคุณใช้มากกว่า4L [2J]ความสนุกอีก 6 ไบต์: tZlcW-(ใช้ได้เฉพาะใน MATLAB ไม่ใช่ใน TIO / Octave)
Sanchises

6

Java (OpenJDK 8) , 23 ไบต์

n->n^n.highestOneBit(n)

ลองออนไลน์!

ขออภัยในตัว: - /


Java ที่มี build-in ซึ่งภาษายอดนิยมอื่น ๆ เช่น. NET และ Python ไม่มี! o.Ô +1 ถึงสิ่งนั้น กำลังจะโพสต์บางอย่างให้นานขึ้นโดยไม่ต้องมีบิลด์อิน .. คุณสั้นกว่า 15 ไบต์ XD
Kevin Cruijssen

@KevinCruijssen สิ่งที่ต้องการn->n^1<<(int)Math.log2(n)จะทำงานได้และมีแนวโน้มสั้นกว่า 38 ไบต์ มันเป็นความคิดที่สองของฉัน (ยังไม่ทดลอง) ถ้าแนวคิดนี้ใช้highestOneBitไม่ได้ ทางออกของคุณคืออะไร
Olivier Grégoire

Mine เป็นn->n^1<<(int)(Math.log(n)/Math.log(2))เพราะMath.log2ไม่มีอยู่ใน Java ; P เท่านั้นMath.log, Math.log10และMath.loglpที่มีอยู่
Kevin Cruijssen

2
ฉันจะโพสต์สิ่งเดียวกันเพียงลบแทน xor จำวิธีการนี้ได้
JollyJoker

1
@KevinCruijssen โอ๊ะโอMath.log2ไม่มีอยู่จริง ... ฉันไม่ดี ดู? มีวิธีการที่ดี ( highestOneBit) อยู่ แต่ไม่ใช่วิธีอื่น ( Math.log2) Java เป็นเรื่องแปลก ;-)
Olivier Grégoire

6

Husk ขนาด 3 ไบต์

ḋtḋ

ลองออนไลน์!

คำอธิบาย:

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

คล้ายกับโซลูชันของเจลลี่ดูเหมือนว่านี่จะเป็น 5 ไบต์ไม่ใช่ 3
Bartek Banachewicz

1
@BartekBanachewicz คล้ายกับ Jelly, Husk ใช้ codepage ของตัวเองดังนั้นนี่คือ 3 ไบต์: P
HyperNeutrino

@BartekBanachewicz ดูที่นี่สำหรับเพจรหัส: github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2 , 27 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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

... ตอนที่ฉันกำลังคำนวณเลขคณิตบิต : P
มนุษย์

@tallyallyhuman heh ขอโทษ แต่เอาชนะคุณมัน: P
HyperNeutrino

2**len(bin(n))/8ยังสามารถสะกด1<<len(bin(n))-3และจากนั้นจะสามารถใช้ได้ทั้ง 2 และ 3 (ไม่มีการบันทึก / เพิ่มไบต์)
Mego

@Mego Cool ขอบคุณสำหรับการเพิ่ม!
HyperNeutrino

5

Python 3 , 30 ไบต์

-8 ไบต์ขอบคุณ caird coinheringaahing ฉันพิมพ์จากหน่วยความจำ : o

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

ลองออนไลน์!



a) ข้อผิดพลาดในวันที่1ข) ฉันโง่พอที่จะไม่คิดอย่างนั้น แต่ฉันแก้ไขด้วยการเปลี่ยนแปลงเล็กน้อย ขอบคุณ!
มนุษย์

ฉันได้แก้ไขรหัสเพื่อให้ทำงานได้ (และประหยัด 4 ไบต์)
38417 caird coinheringaahing

ข้อผิดพลาดยังคงว่าเมื่อวันที่1
สิ้นเชิงมนุษย์

@cairdcoinheringaahing นั่นคือคำตอบเดิมของฉันแต่แล้วฉันก็ตระหนักว่ามันเกิดข้อผิดพลาดในวันที่ 1 การแก้ปัญหาจบลงนานกว่าวิธี XOR แบบง่าย ๆ
FlipTack


4

จาวาสคริปต์, 22 20 ไบต์

บันทึก 2 ไบต์ขอบคุณovs

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

ลองออนไลน์!

วิธีการอื่น 32 ไบต์

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

ลองออนไลน์!


ทำไมคุณถึงทำงาน.slice`1`^0เมื่อ.slice(1)^0ทำงานเช่นกันฮ่าฮ่า
ETHproductions

@ETHproductions อันนี้ดูดีกว่า :)

4

J, 6 ไบต์

}.&.#:

ค่อนข้างง่าย

คำอธิบาย

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

ฉันจะโพสต์สิ่งนี้ :(
Cyoce

@Cyoce ฉันเกินไป ...
อดัม

4

APL (Dyalog)ขนาด 10 ไบต์

ฟังก์ชั่นนำหน้า Tacit

212∘⊥⍣¯1

ลองออนไลน์!

2∘⊥... ถอดรหัสจากฐาน-2 ...
 ... ⍣¯1 ครั้งหนึ่งในเชิงลบ (เช่นการเข้ารหัสในฐาน 2)

1↓ ปล่อยบิตแรก

2⊥ ถอดรหัสจากฐาน -2


4

ทับทิมขนาด 26 ไบต์

-7 ไบต์ขอบคุณ Ventero -2 ไบต์ขอบคุณสำหรับ historicalrat

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

คุณสามารถบันทึกไม่กี่ไบต์โดยเพียงแค่ข้ามตัวอักษรตัวแรกและวางวงเล็บซ้ำซ้อน:->n{n.to_s(2)[1..-1].to_i 2}
Ventero

->n{/./=~'%b'%n;$'.to_i 2}
ฮิสโทแกต

4

C (gcc), 38 ไบต์

ใช้ gcc ในตัว

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

การแทนที่31-ด้วย~ควรบันทึกสองไบต์

@ThePirateBay ขึ้นอยู่กับฮาร์ดแวร์ไม่ว่าจะเปลี่ยนหน้ากาก ในคอมพิวเตอร์ของฉันมันจะส่งออก 0
Colera Su

4

ชุดประกอบ ARM 46 43 ไบต์

(คุณสามารถละเว้นการลงทะเบียนปลายทางเมื่อเพิ่มเช่นเดียวกับแหล่งที่มา)

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

ไวยากรณ์ของชุดประกอบ ARM มีรสชาติแบบใด ประกอบ GNU ฉันไม่เข้าใจshr/ shl/ retและความต้องการบางอย่างเช่นแทนที่จะlsr/ /lsl bx lr
Ruslan

อาจผสมไวยากรณ์ในหลาย ๆ เวอร์ชัน (ret มาจาก aarch64) แต่ฉันคิดว่าแอสเซมเบลอร์จะหลอก op เหล่านี้ให้คุณ สำหรับจุดประสงค์ของที่นี่แม้ว่าการใช้ lsl / lsr แบบเก่าและโดยตรงนั้นอาจถูกต้อง
Michael Dorgan

สิ่งที่ตลกฉันสามารถทำได้ใน 1 การทำงานน้อยลง แต่ฉันขนาดไบต์เพิ่มขึ้น 2 อารหัสกอล์ฟ
Michael Dorgan


3

อลิซ 8 ไบต์

./-l
o@i

ลองออนไลน์!

คำอธิบาย

.   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

Japtap , 6 ไบต์

^2p¢ÊÉ

ลองออนไลน์!

คำอธิบาย

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

หากอินพุต1สามารถล้มเหลว: 4 ไบต์

¢Ån2

ลองออนไลน์!

คำอธิบาย : รับอินพุตไบนารี ( ¢), ตัดส่วนแรก char ( Å), แยกเป็นไบนารี่กลับไปที่ตัวเลข ( n2)



3

APL (Dyalog Unicode)ขนาด 9 ไบต์

⊢-2*∘⌊2⍟⊢

ลองออนไลน์!

-1 ไบต์ต้องขอบคุณอดัม


ถูกต้องสมบูรณ์แม้ว่าฉันจะใช้TIOเพื่อสร้างแม่แบบสำหรับฉัน อย่างไรก็ตาม⊢-2*∘⌊2⍟⊢บันทึกไบต์
อดัม

ฉันเสียใจที่ APL ไม่ได้เป็นตัวแทนและมีเกือบหายไปในม้วน! ฉันคิดถึง APL
cmm

@cmm APL ยังมีชีวิตอยู่และดี รู้สึกอิสระที่จะออกไปเที่ยวในห้องสนทนาแลกเปลี่ยน Stack APL
อดัม

3

CJam , 7 ไบต์

{2b()b}

ลองออนไลน์!

คำอธิบาย:

{     }  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

ใช้ MSB (ซึ่งเป็น 1 เสมอ) เพื่อหลีกเลี่ยงการลบ โดยไม่ต้องเทียบเท่าเคล็ดลับที่จะเป็นหรือ{2b1>2b}{2b(;2b}


3

เรติน่า15 15ไบต์

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

ลองออนไลน์!

อินพุทและเอาท์พุทเป็นเอกภาพ (ชุดทดสอบประกอบด้วยการแปลงจากและเป็นทศนิยมเพื่อความสะดวก)

คำอธิบาย

มันค่อนข้างง่ายที่จะทำใน unary สิ่งที่เราต้องการทำคือลบกำลังที่ใหญ่ที่สุด 2 จากอินพุต เราสามารถจับคู่กำลัง 2 กับการอ้างอิงไปข้างหน้า จริง ๆ แล้วมันง่ายกว่าที่จะจับคู่ค่าของแบบฟอร์ม2 n -1ดังนั้นเราจะทำอย่างนั้นและจับคู่1แยกกัน:

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

กลุ่ม1จะจับคู่เดี่ยว1ที่จุดเริ่มต้นเพื่อเตะสิ่งต่าง ๆ หรือจับคู่สองครั้งกับสิ่งที่ทำในการทำซ้ำครั้งล่าสุด ดังนั้นมันจึงตรงกัน1และจาก2นั้น4เป็นต้น เนื่องจากสิ่งเหล่านี้ได้รับการรวมเข้าด้วยกันเราจึงขาดพลัง 2 อย่างซึ่งเราแก้ไขได้1ในตอนท้าย

เนื่องจากการป้อนบรรทัดต่อท้ายการจับคู่จะถูกลบออกจากอินพุต


3

R , 28 ไบต์

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

ลองออนไลน์!

ง่ายที่สุดในการคำนวณบิตที่สำคัญที่สุดผ่าน2 ^ floor(log2(x))แทนที่จะทำการแปลงพื้นฐานซึ่งค่อนข้างละเอียดใน R


3

PARI / GP ขนาด 18 ไบต์

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

ทางเลือกอื่น:

n->n-2^exponent(n)

คนแรกดูเหมือนจะให้คำตอบที่ผิด มันควรจะเป็นn->n-2^logint(n,2)อย่างไร คนที่สองไม่ได้รับการสนับสนุนในรุ่นของฉัน PARI / GP หรือในรุ่นที่ใช้โดยtio.run นั่นคือฟังก์ชั่นใหม่หรือไม่?
Jeppe Stig Nielsen

@JeppeStigNielsen โอ๊ะโอคงที่นั่นคือสิ่งที่ฉันได้รับจากการส่งจากโทรศัพท์ของฉัน ใช่คนที่สองเป็นฟังก์ชั่นใหม่
ชาร์ลส์

@JeppeStigNielsen ฉันเพิ่งตรวจสอบexponentถูกเพิ่ม 5 วันที่ผ่านมาเมื่อเทียบกับความท้าทายที่เพิ่มเข้ามาเมื่อวานนี้ :)
ชาร์ลส์

3

Haskell , 32 29 ไบต์

(!1)
x!y|2*y>x=x-y|z<-2*y=x!z

ลองออนไลน์!

-3 ไบต์ขอบคุณ @Laikoni

โซลูชันที่เก่ากว่า 32 ไบต์

f x=last[x-2^i|i<-[0..x],2^i<=x]

ลองออนไลน์!


1
อนุญาตให้ใช้ฟังก์ชันที่ไม่ระบุชื่อดังนั้นคุณไม่จำเป็นต้องใช้f=ตัวแปรแรก นอกจากนี้z<-2*y=x!zจะบันทึกไบต์: ลองออนไลน์!
Laikoni


3

Excel, 36 31 ไบต์

-5 ไบต์ต้องขอบคุณ @ IanM_Matrix1

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

ไม่มีอะไรน่าสนใจ.


ลดขนาดเป็น 31 ไบต์โดยแทนที่ REPLACE ด้วย MID: = BIN2DEC (MID (DEC2BIN (A1), 2,99))
IanM_Matrix1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.