การขยายไบนารีไบนารี่


9

โดยปกติเราจะแยกตัวเลขออกเป็นเลขฐานสองโดยการกำหนดด้วยกำลังของ 2 ด้วยสัมประสิทธิ์ของ0หรือ1สำหรับแต่ละเทอม:

25 = 1*16 + 1*8 + 0*4 + 0*2 + 1*1

ทางเลือกของ0และ1ก็คือ ... ไม่ได้เป็นแบบไบนารีมาก เราจะทำการขยายฐานสองจริงโดยขยายด้วยพลัง 2 แต่ด้วยสัมประสิทธิ์1หรือ-1แทน:

25 = 1*16 + 1*8 + 1*4 - 1*2 - 1*1

ตอนนี้ดูเป็นเลขฐานสอง

ด้วยจำนวนที่เป็นบวกใด ๆ คุณควรเห็นว่า:

  • ทุกเลขคี่จะมีการขยายไบนารีจริงจำนวนมากอย่างไม่ จำกัด
  • เลขคู่ทุกตัวไม่มีการขยายไบนารีที่แท้จริง

ดังนั้นสำหรับการขยายแบบไบนารีที่แท้จริงที่จะกำหนดไว้อย่างดีเราจำเป็นต้องมีการขยายตัวให้น้อยที่สุดนั่นคือด้วยความยาวที่สั้นที่สุด


รับค่าบวกเลขจำนวนเต็มคี่ใด ๆnส่งคืนการขยายไบนารีที่แท้จริงจากตัวเลขที่สำคัญที่สุดไปยังตัวเลขที่มีนัยสำคัญน้อยที่สุด (หรือในลำดับที่กลับกัน)

กฎ:

  • เช่นนี้คือ คุณควรตั้งเป้าหมายให้เป็นไบต์ที่สั้นที่สุด อนุญาตให้สร้างเครื่องได้
  • เอาต์พุตใด ๆ ที่สามารถเป็นตัวแทนและแสดงรายการสัมประสิทธิ์เป็นที่ยอมรับได้: อาเรย์สตริงของสัมประสิทธิ์ที่มีตัวคั่น ฯลฯ ...
  • มีช่องโหว่มาตรฐานสำหรับการเล่นกอล์ฟ
  • โปรแกรมของคุณควรทำงานกับค่าภายในขนาดจำนวนเต็มมาตรฐานของภาษาของคุณ

กรณีทดสอบ

25 -> [1,1,1,-1,-1]
47 -> [1,1,-1,1,1,1]
1 -> [1]
3 -> [1,1]
1234567 -> [1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1]

ที่เกี่ยวข้องแต่ค่อนข้างแตกต่าง
Giuseppe

4
อัลกอริทึมง่าย ๆ : แปลงเป็นฐาน 2 แทนที่ 0 ด้วย 1 ของใส่ LSD ที่ด้านหน้า
โยสิยาห์พระพุทธเจ้าพระพุทธเจ้า

Voile: ฉันไม่ได้อธิบาย downvote ฉันเพิ่งจะสรุปอัลกอริทึมสำหรับผู้ที่มีคำสั่งการแปลงพื้นฐานในภาษาของพวกเขา
โยสิยาห์พระพุทธเจ้าทรงพระพุทธเจ้า

เนื่องจากคุณกระตือรือร้นที่จะเป็นเลขฐานสองอย่างแท้จริงเราสามารถคืนค่าเป็นบิตที่บรรจุด้วยค่าสถานที่ปกติ แต่การตีความใหม่ของทั้งสองรัฐหรือไม่ นั่นคือทางไฟฟ้ามันเป็นเพียงแรงดันไฟฟ้าสูงหรือต่ำ (หรืออะไรก็ตาม) และไม่ใช่ความผิดของฉันถ้า debuggers มาตรฐานพิมพ์0แทน-1สถานะแรงดันไฟฟ้าต่ำ ผู้เรียกที่รับบิตรู้ว่าพวกเขาหมายถึงอะไร (มันยังคงเป็นแบบฝึกหัดการจัดการบิตที่ไม่สำคัญเนื่องจากการหมุนทางขวานั้นจะทำงานได้ก็ต่อเมื่อมันมี 32 บิตที่สำคัญเช่นจำนวน 5 บิตต้องการความกว้างการหมุนที่ 5)
Peter Cordes

เอาต์พุตจำเป็นต้องมีตัวคั่นหรือไม่? คือ111-1-1การส่งออกที่ถูกต้องสำหรับ25?
โอลิเวอร์

คำตอบ:



3

Pyth ,  12  11 ไบต์

|R_1.>jQ2 1

ลองที่นี่!


อย่างไร?

| R_1.> jQ2 1 โปรแกรมเต็มรูปแบบ

      jQ2 แปลงอินพุตเป็นรายการไบนารี่
     .> 1 หมุนรายการข้างต้นโดย 1 ตำแหน่งไปทางขวา
| R_1 แทน 0 ด้วย -1
               เอาต์พุตโดยปริยาย

ก่อนอื่นเราสังเกตว่างานเป็นเพียง "แทนที่0s ในการเขียนเลขฐานสองด้วย-1s และเลื่อนไปทางขวา 1 ตำแหน่ง" - นั่นคือสิ่งที่เราควรทำ! การแปลงแบบไบนารีทำให้เราเห็นรายการ0s และ1s ทั้งหมดที่เราควรจะทำอย่างไรที่นี่คือการหาวิธีที่ golfy การแปลงไป0 -1ผู้ประกอบการระดับบิต|(bitwise OR) คือเพื่อนของเรา แผนที่มากกว่าแทน binary ขยับตัวด้วยและ| -1หากจำนวนปัจจุบันคือจะได้รับการแปลงเป็น0-1


ฉันไม่คิดว่าจะมีวิธีที่ดีกว่า ;)
Josiah Winslow

@JosiahWinslow ฉันทำ ... กำลังพยายามหามัน
Mr. Xcoder

หืม? อัลกอริทึมดูดีที่สุดอาจเป็นเพราะฉันไม่รู้จัก Pyth
โยสิยาห์พระพุทธเจ้าทรงพระพุทธเจ้า

@JosiahWinslow พบวิธีที่ดีกว่า วิธีทางที่ดีกว่าการซินแท็กซ์
Mr. Xcoder

@ Mr.Xcoder และตอนนี้มีอย่างน้อยจริงๆสำหรับฉัน
Erik the Outgolfer



2

Perl 6 , 72 ไบต์

มีวิธีที่ดีกว่าแน่นอน แต่นี่คือสิ่งที่ฉันมี ...

->$a {grep {$a==[+] @^a.reverse Z+< ^∞},[X] (1,-1)xx $a.base(2).chars}

ลองออนไลน์!

คำอธิบาย : เป็นฟังก์ชันที่ใช้อาร์กิวเมนต์หนึ่งตัว ( ->$a) ครั้งแรกที่เราได้รับหมายเลขของสัมประสิทธิ์จำเป็น (คน$a.base(2).chars= จำนวนอักขระในฐานตัวแทน 2) แล้วให้ผลิตภัณฑ์ Cartesian ( X) (1,-1)จากการที่หลายคู่ (ค่า[X]เฉลี่ย: ลดรายการต่อไปนี้ด้วยX.) ดังนั้นเราจะได้รายการชุดค่าผสมที่เป็นไปได้ทั้งหมดของ 1s และ -1s จากนั้นเราก็กรอง ( grep) $aเฉพาะรายการที่เข้ารหัสจำนวนที่กำหนด มีเพียงรายการเดียวดังนั้นเราจึงได้รายการของรายการที่มีค่าสัมประสิทธิ์

บล็อก grep ไม่นี้: ใช้เวลาอาร์กิวเมนต์เป็นรายการ ( @^a) ฝืนมันและซิปกับรายการที่ไม่มีที่สิ้นสุด0,1,2,...การใช้ "ซ้ายกะบิต" +<ผู้ประกอบการ การซิปจะหยุดทันทีที่รายการที่สั้นลงหมดลง (ดีสำหรับเรา!) จากนั้นเราจะรวมผลลัพธ์ทั้งหมดและเปรียบเทียบกับหมายเลขที่กำหนด เราต้องใช้.reverseเพราะ OP ต้องการให้ค่าสัมประสิทธิ์อยู่ในลำดับที่สำคัญที่สุดถึงสำคัญน้อยที่สุด




1

J, 11 ไบต์

1-~2*_1|.#:

ลองออนไลน์!

ขอบคุณ @JosiahWinslow สำหรับอัลกอริทึม

มีความคิดเห็นเกี่ยวกับการทำให้การแปลงสั้นลงไหม? ความคิดของฉันคือการใช้!.-fit (nvm มันแค่เปลี่ยนความอดทนของการแปลง)

การใช้{-take นั้นยาวกว่า 1 ตัวอักษร

_1 1{~_1|.#:

1

Java 8, 101 ไบต์

n->{String s=n.toString(n,2);return(s.charAt(s.length()-1)+s.replaceAll(".$","")).replace("0","-1");}

คำตอบJaptของ@Oliverของพอร์ตโดยมีอีกไม่กี่ไบต์ .. ;)

สามารถเล่นกอล์ฟได้อย่างแน่นอนโดยใช้วิธีการทางคณิตศาสตร์แทนวิธีการของสตริงนี้

คำอธิบาย:

ลองที่นี่

n->{                             // Method with Integer parameter and String return-type
  String s=n.toString(n,2);      //  Convert the Integer to a binary String
  return(s.charAt(s.length()-1)  //  Get the last character of the binary String
    +s.replaceAll(".$","")       //   + everything except the last character
   ).replace("0","-1");          //  Then replace all zeroes with -1, and return the result
}                                // End of method

1

R , 90 88 46 ไบต์

function(n)c((n%/%2^(0:log2(n))%%2)[-1],1)*2-1

ลองออนไลน์!

ใช้อัลกอริทึมของ Oliverแต่คืนค่าตัวเลขในลำดับย้อนกลับ เนื่องจากเรารับประกันว่าnจะไม่เคยแม้แต่น้อยบิตที่สำคัญ (แรก) อยู่เสมอ1ดังนั้นเราจึงลบมันและผนวก1ท้ายเพื่อจำลองการหมุนในอาร์ขอบคุณ Shaggy ที่ทำให้ฉันแก้ไขคณิตศาสตร์ของฉันรับผมที่จะแก้ไขปัญหาคณิตศาสตร์ของฉัน

เพียงแค่ใส่ rev( )การเรียกใช้ฟังก์ชันในส่วนท้ายควรคืนค่าในลำดับเดียวกัน

คำตอบเดิม 88 ไบต์:

function(n,b=2^(0:log2(n)))(m=t(t(expand.grid(rep(list(c(-1,1)),sum(b|1))))))[m%*%b==n,]

ฟังก์ชั่นไม่ระบุชื่อ; ส่งคืนค่าในลำดับย้อนกลับที่มีชื่อคอลัมน์ที่แนบมา

ลองออนไลน์!

คำอธิบาย:

function(n){
 b <- 2^(0:log2(n))         # powers of 2 less than n
 m <- expand.grid(rep(list(c(-1,1)),sum(b|1))) # all combinations of -1,1 at each position in b, as data frame
 m <- t(t(m))               # convert to matrix
 idx <- m%*%b==n            # rows where the matrix product is `n`
 m[idx,]                    # return those rows
}

ฉันจะไม่ถือว่าผลลัพธ์นั้นถูกต้อง แนะนำให้ถามผู้เขียนคำถามเพื่อยืนยัน
ขนดก

@Shaggy กลับคำสั่งซื้อได้รับอนุญาตอย่างชัดเจน: from the most significant digit to the least significant digit (or in reversed order).ดังนั้นสิ่งนี้ควรเป็นที่ยอมรับอย่างสมบูรณ์
Giuseppe

1
ตรงกันข้ามเพื่อไม่ย้อนกลับสัญญาณ ความหมายที่ถูกต้องสำหรับการส่งออก25เช่นจะเป็นหรือ[1,1,1,-1,-1] [-1,-1,1,1,1]
Shaggy

1
@Shaggy อาคุณพูดถูกฉันเพิ่งทำผิดคณิตศาสตร์! ควรจะแทน2*bits - 1 1-2*bitsขอบคุณ.
จูเซปเป้




0

Golfscript, 14 13 14 ไบต์

-1 ไบต์เพราะฉันลืมไป%แล้ว +1 byte เพราะฉันยังลืมอินพุตเป็นสตริง

~2base{.+(}%)\

1
หากคุณจะสมมติว่าอินพุตมาเป็นจำนวนเต็มคุณควรใส่โค้ดไว้{}เพื่อให้เป็นบล็อก โปรแกรมแบบเต็มสามารถรับอินพุตเป็นสตริงเท่านั้น
Peter Taylor

อืม ... อะไร? ฉันหมายถึงจำนวนจะถูกผลักเป็นจำนวนเต็มแทนที่จะเป็นสตริงที่มีตัวเลข
โยสิยาห์พระพุทธเจ้าทรงพระพุทธเจ้า

ในกรณีนั้นคำตอบของคุณไม่ใช่โปรแกรมเต็มและต้องเป็น "ฟังก์ชัน"หรือในกรณีของ GolfScript บล็อก ดังนั้นมันจึงมี{2base{.+(}%\}ขนาด 15 ไบต์ ในทำนองเดียวกันคำตอบ CJam ของคุณ
Peter Taylor

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

ฉันมีความคุ้นเคยกับ GolfScriptบ้าง ( และ CJam ) ~หากคุณต้องการที่จะอ้างว่ามันเป็นโปรแกรมเต็มรูปแบบที่คุณต้องนำหน้าด้วย
Peter Taylor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.