การสลับบิตละเลง


12

บทนำ

ความท้าทายนี้ต้องการให้คุณตั้งค่าศูนย์ต่อท้ายของการแสดงเลขฐานสองจำนวนเต็ม010101…เป็นตัวอย่างนี้อธิบายได้ดีที่สุดด้วย:

รับจำนวนเต็ม400ขั้นตอนแรกคือการแปลงเป็นไบนารี:

110010000

เนื่องจากเราสามารถเห็นบิตที่ห้าเป็นบิตที่มีนัยสำคัญน้อยที่สุด1ดังนั้นเริ่มจากตรงนั้นเราแทนค่าศูนย์ล่างโดย0101:

110010101

ในที่สุดเราแปลงกลับเป็นทศนิยม: 405

ท้าทาย

รับคืนจำนวนเต็มบวก / ค่าผลลัพธ์ที่สอดคล้องกันของกระบวนการที่กำหนดไว้ข้างต้น

กฎระเบียบ

  • ลำดับนี้ถูกกำหนดไว้สำหรับเลขจำนวนเต็มอย่างน้อยหนึ่ง1บิตดังนั้นอินพุตจะเป็น≥ 1 เสมอ
  • คุณอาจจะใส่เป็นสตริงรายการของตัวเลข (ทศนิยม) แทน
  • คุณไม่ต้องจัดการอินพุตที่ไม่ถูกต้อง

Testcases

ต่อไปนี้เป็นบททดสอบเพิ่มเติมที่มีขั้นตอนตัวกลาง (คุณไม่ต้องพิมพ์ / ส่งคืนสิ่งเหล่านี้):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298

เราสามารถใช้จำนวนเต็ม 32 บิตได้หรือไม่?
Arnauld

@Annauld: แน่นอน!
ბიმო

9
แนวคิดการตีกอล์ฟบางอย่าง: หากnพลังสูงสุดของ 2 ที่แบ่งการป้อนข้อมูลออกมาคำตอบก็คือ(input) + ceil((2^n - 2)/3)
JungHwan Min

คำตอบ:


12

Python 3 , 20 ไบต์

lambda n:(n&-n)//3+n

ลองออนไลน์!

คำอธิบาย

ใช้192เป็นตัวอย่าง รูปแบบไบนารีของมันคือและเราจำเป็นต้องแปลงเป็น1100000011010101

เราทราบว่าเราจำเป็นต้องเพิ่ม10101จำนวน นี่คือชุดเรขาคณิต ( 4^0 + 4^1 + 4^2) (4^3-1)/(4-1)ซึ่งมีรูปแบบปิดเป็น นี่เป็นเช่นเดียวกับ4^3//3ที่//หมายถึงการหารจำนวนเต็ม

ถ้าเป็น101010เช่นนั้นมันจะยังคงเป็นชุดเรขาคณิต ( 2×4^0 + 2×4^1 + 2×4^2) ซึ่งเป็น2×4^3//3เหตุผลด้านบน

อย่างไรก็ตาม4^3และ2×4^3จะเป็นบิตที่สำคัญน้อยที่สุดซึ่งเราได้รับจากn&-n:

เราสังเกตเห็นว่าส่วนประกอบของคือn 00111111หากเราเพิ่มอันใดอันหนึ่งมันก็จะกลายเป็น01000000และมันจะทับกับn=11000000หลักที่สำคัญน้อยที่สุดเท่านั้น โปรดทราบว่า "เติมเต็มและเพิ่มหนึ่ง" เป็นเพียงการปฏิเสธ


6
@ Mr.Xcoder มีน้ำใจนักกีฬาที่ดี
Leaky Nun

1
อาจเป็นไปlambda n:(n&-n)//3+nได้เช่นกัน? ผ่านการทดสอบตัวอย่างทั้งหมดแต่ตามสัญชาตญาณของฉันมันไม่ถูกต้องใช่มั้ย
Mr. Xcoder

@ Mr.Xcoder มันถูกต้องแน่นอน
Leun Nun

1
ทำไมไม่ใช้ Python 2 เพื่อบันทึกไบต์? TIO
FlipTack

4
@FlipTack ฉันเกลียดหลาม python 2
Nun

8

เยลลี่ 5 ไบต์

&N:3+

ลองออนไลน์!

คราวนี้เป็นท่าของLeaky Nun (อย่างน้อยฉันก็ช่วยเขาตีมันลงเล็กน้อย: P)

เยลลี่ขนาด 7 ไบต์

^N+4:6ạ

ลองออนไลน์!

ใช้วิธีการที่ยอดเยี่ยมจองฮวานมินด้วยความช่วยเหลือทางอ้อมจากมาร์ตินเอนเดอร์


เดนนิสโพสต์แล้วลบเป็นทางออกที่ 5 ไบต์ที่คล้ายกันมากเพียงหลังจากที่คุณทำแก้ไขว่า &N:3|สิ่งที่ชอบ ขอแสดงความยินดี; คุณชนะเดนนิสในเยลลี่! (แต่ไม่ค่อยออกกอล์ฟเลย)
wizzwizz4

@ wizzwizz4 ฉันไม่ได้ทำอะไรมากนอกจากแนะนำกอล์ฟเล็ก ๆ ให้กับแนวทางของ Leaky และจากนั้นก็ย้ายมัน แต่เอ๊ะ :-)
นาย Xcoder

นี่เป็นคำตอบเดียวของเยลลี่ ASCII เดียวที่ฉันเคยเห็น
MD XF

6

ภาษา Wolfram (Mathematica) , 36 28 26 24 ไบต์

-8 ไบต์ขอบคุณ @MartinEnder และ -2 ไบต์ขอบคุณ @ Mr.Xcoder

#+⌊(#~BitAnd~-#)/3⌋&

ลองออนไลน์!

เราจะต้องค้นหาจำนวนของศูนย์ต่อท้ายในการป้อนข้อมูลและหาจำนวนที่มีการสลับ0s และ1s ที่มีความยาวหนึ่งน้อยกว่านั้นและเพิ่มลงในอินพุต

ดังนั้น, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

สูตรที่ชัดเจนสำหรับnตัวเลขที่มีการสลับ1s และ0s ในA000975บน OEIS เราสามารถใช้nหมายเลข th เนื่องจากไม่มีเลขสองตัวที่แตกต่างกันสามารถมีความยาวเท่ากันในไบนารีและมีตัวเลขหลัก


1
2^#~IntegerExponent~2คือ(BitXor[#,#-1]+1)/2
Martin Ender

@MartinEnder ว้าว! จากนั้นฉันก็สามารถรวมเศษส่วนเพื่อลดจำนวนไบต์ได้มากขึ้น
JungHwan Min

1
24 ไบต์ คุณสามารถใช้#+⌊(#~BitAnd~-#)/3⌋&แทน
Mr. Xcoder

@ Mr.Xcoder แก้ไข :)
Min

5

J , 19 18 ไบต์

+(2|-.i.@#.-.)&.#:

ลองออนไลน์!

คำอธิบายด่วน

นี่เป็นคำตอบเก่า แต่มันมีความคล้ายคลึงกันมากกับธรรมชาติในปัจจุบันมันแค่นับเลขศูนย์ต่อท้ายต่างกัน ดูความคิดเห็นสำหรับลิงก์ที่อธิบายวิธีการทำงาน

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

คำตอบอื่น ๆ :

คำตอบก่อนหน้า (19 ไบต์)

+(2|i.@i.&1@|.)&.#:

นานกว่าที่ควรจะเป็นเพราะ\ไปจากขวาไปซ้าย

+(2|#*-.#.-.)\&.(|.@#:)

1
18 ไบต์+(2|-.i.@#.-.)&.#:
ไมล์

@ ใจฉันอธิบายว่าเกิดอะไรขึ้นกับการแปลงฐานที่นั่น? ฉันเดาว่ามันมีบางอย่างที่เกี่ยวข้องกับศูนย์ แต่ฉันไม่แน่ใจ
โคล

#.~ การนับจำนวนของความจริงต่อท้ายดังนั้นสิ่งที่เราต้องการคือ#.~ -. #:การนับจำนวนเลขท้าย
ไมล์

@miles Ah! ช่างฉลาดจริงๆ
โคล

4

Julia 0.6 , 12 ไบต์

!n=n|n&-n÷3

ลองออนไลน์!


ดูเหมือนว่าวิธีที่มีประสิทธิภาพคุณสามารถอธิบายความสำคัญของผู้ปฏิบัติงานได้หรือไม่ ตัวอย่างเช่นฉันไม่สามารถบอกได้ว่ามีการประเมินผลเป็น((!n=(n|n))&-n)/3หรือหรือ!n=(((n|n)&(-n))/3)ไม่
MD XF

ในจูเลียผู้ประกอบการระดับบิตมี precedences เช่นเดียวกับคู่ของเลขคณิตของพวกเขาจึง|เป็นเหมือน+และเป็นเหมือน& *ดังนั้นจะแยกเป็นn|n&-n÷3 n | ((n&-n) ÷3)
เดนนิส

3

JavaScript (ES6), 40 39 ไบต์

รับอินพุตเป็นจำนวนเต็ม 32 บิต

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

กรณีทดสอบ


2

05AB1E , 13 8 5 ไบต์

บันทึก 5 ไบต์ด้วยMr. Xcoderและสูตรที่ประณีตของ JungHwan Min
บันทึกอีก 3 ขอบคุณMr. Xcoder

(&3÷+

ลองออนไลน์!

คำอธิบาย

(      # negate input
 &     # AND with input
  3÷   # integer divide by 3
    +  # add to input

1
อาจคุ้มค่าที่จะกล่าวถึงว่าการย้ายคำตอบ Mathematica ให้8 ไบต์
Mr. Xcoder

@ Mr.Xcoder: โอ้เป็นสูตรที่เรียบร้อย
Emigna

1
05ab1e มีค่าบิตและหรือไม่ ถ้าเป็นเช่นนั้น(<bitwise and here>3÷+ควรใช้งานได้ถึง 5 ไบต์
Mr. Xcoder

2

R , 71 58 ไบต์

ขอบคุณ NofP สำหรับ -6 ไบต์

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

ลองออนไลน์!

ถือว่าอินพุตเป็นจำนวนเต็ม 32 บิต R เท่านั้นที่ได้ลงนามจำนวนเต็ม 32- บิต (หล่อdoubleเมื่อจำนวนเต็มล้น) อยู่แล้วและไม่มี int 64- บิตหรือไม่ได้ลงนาม


คุณสามารถแปลงเป็นwhich.max(n):1-1เพื่อ!cumsum(n)ให้ได้โซลูชันขนาด 65 ไบต์
NofP

@NofP ขอบคุณ! เป็นความคิดที่ดีมาก.
Giuseppe

2

brainfuck , 120 ไบต์

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

ลองออนไลน์!

เริ่มต้นด้วยค่าในเซลล์ปัจจุบันและสิ้นสุดในเซลล์ด้วยค่าเอาต์พุต เห็นได้ชัดว่าจะไม่ทำงานกับตัวเลขที่สูงกว่า 255 ซึ่งเป็นขีด จำกัด ของเซลล์สำหรับ brainfuck ทั่วไป แต่จะใช้งานได้ถ้าคุณสมมติขนาดเซลล์ที่ไม่สิ้นสุด


1

PowerShellขนาด 168 ไบต์

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

ลองออนไลน์!

อุ๊ยตาย การแปลงเป็น / จากไบนารีและการแบ่งอาร์เรย์ไม่ใช่ชุดที่แข็งแกร่งของ PowerShell

รับอินพุต$nเป็นตัวเลข เราทันทีconvertที่ฐานไบนารี2และเก็บไว้ใน$aนั้น ต่อไปเราจะสร้าง if / else ถ้าประโยคทดสอบว่าregex Matchต่อ 1 หรือมากกว่า0นั้นในตอนท้ายของสตริง ( '0+$') มีindexที่มากกว่า0(เช่นการเริ่มต้นของสตริงไบนารี) ถ้าเป็นเช่นนั้นเรามีบางอย่างที่จะทำงานelseเราก็แค่เอาท์พุทตัวเลข

ข้างในifเราแบ่งส่วนที่หนึ่งของxตัวเลขหลักและเรียงค่าตัวเลขที่ต่อกัน+กับตัวเลขที่เหลือ อย่างไรก็ตามสำหรับตัวเลขที่เหลือเราวนรอบพวกมันและเลือก a 0หรือ1เพื่อเอาท์พุทแทนโดยใช้$i++%2เพื่อเลือก นี่ทำให้เรามี010101...ลวดลายแทนที่จะ0เป็นตอนท้าย จากนั้นเราจะ-joinว่ากลับมารวมกันเป็นสตริงและ$convert มันกลับลงไปจากฐานInt322

ในสถานการณ์ใดสถานการณ์หนึ่งหมายเลขจะถูกทิ้งไว้บนไพพ์ไลน์






1

Python 3 , 56 ไบต์

lambda n:eval((bin(n).rstrip("0")+"01"*n)[:len(bin(n))])

ลองออนไลน์!

ไม่ได้มีความสุขจริงๆกับเรื่องนี้เลย แต่ผมไม่ต้องการที่จะใช้สูตร ... -2 ขอบคุณที่ร็อด -1 ขอบคุณที่โจนาธาน Frech


eval(...)แทนที่จะint(...,2)สามารถบันทึกไบต์
Jonathan Frech





1

C, 56 ไบต์

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;return n|k;}

ลองออนไลน์!

C (gcc), 50 ไบต์

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;k|=n;}

ลองออนไลน์!

 51  48 ไบต์โดยใช้โซลูชันของ Arnauld :

ขอบคุณ @ l4m2 สำหรับการบันทึกสามไบต์!

m;f(n){return n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

ลองออนไลน์!

43 กับ gcc:

m;f(n){m=n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

ลองออนไลน์!


0xAAAAAAAA=>-1u/3*2
l4m2


0

เยลลี่ 13 ไบต์

BŒgṪµ2Ḷṁ×CḄ+³

ลองออนไลน์!

คำอธิบาย

รับ 24 เป็นตัวอย่างอินพุต

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.