แปลงตัวเลขเป็นไบนารี่ ... แต่คุณสามารถใช้ twos ได้เช่นกัน


20

ขึ้นอยู่กับ "ไบนารี แต่เจ้าตัว" สัญกรณ์กล่าวถึงในวิดีโอ Numberphile นี้เขียนฟังก์ชั่นที่ใช้หมายเลขเดียวเป็น input และผลทุกรูปแบบของตัวเลขที่อยู่ในระบบ "ฐาน" ที่เจ้าตัวได้รับอนุญาต

กฎระเบียบ

  • รหัสจะต้องเป็นฟังก์ชั่น / วิธีไม่ใช่โปรแกรมเต็มรูปแบบ
  • อินพุตเป็นจำนวนเต็มที่ส่งผ่านเป็นพารามิเตอร์ตัวเดียวกับฟังก์ชัน
  • เอาท์พุทเป็นรูปแบบที่ถูกต้องทั้งหมดของหมายเลขอินพุตที่แปลงเป็น "ไบนารี แต่ด้วยเครื่องหมายสอง"
  • เอาท์พุทเป็นค่าตอบแทนของฟังก์ชั่น แต่สามารถอยู่ในรูปแบบใดก็ได้ที่สะดวกตราบเท่าที่มันชัดเจน (เช่น 3 ints, 3 สตริง, สตริงคั่นด้วยเครื่องหมายจุลภาค / ช่องว่าง, อาร์เรย์ของ ints, ฯลฯ ) ลำดับไม่สำคัญ
  • ในกรณีที่ไม่น่าเป็นไปได้ที่ภาษาจะมีฟังก์ชันในตัวเพื่อให้ได้ผลลัพธ์ก็จะไม่ได้รับอนุญาต
  • รหัสที่สั้นที่สุดในหน่วยไบต์เป็นผู้ชนะ

คำอธิบายของการส่งออก

ตัวอย่างเช่นหากคุณผ่านหมายเลข9คุณสามารถแปลงเป็นไบนารี่เป็น1001แต่ถ้าคุณอนุญาตให้2s ในแต่ละตำแหน่งคุณสามารถเขียนมันเป็น201(เช่น2*4 + 0*2 + 1*1) หรือ121(เช่น1*4 + 2*2 + 1*1) ดังที่แสดงในตารางนี้:

+----+----+----+----+
| 8s | 4s | 2s | 1s |
+----+----+----+----+
|  1 |  0 |  0 |  1 |
|  0 |  2 |  0 |  1 |
|  0 |  1 |  2 |  1 |
+----+----+----+----+

ดังนั้นถ้าผ่าน9ฟังก์ชั่นของคุณจะต้องกลับหมายเลขสาม1001, และ201121

รูปแบบและการสั่งซื้อไม่เกี่ยวข้องตราบเท่าที่มันเห็นได้ชัด (เช่น[121,201,1001], "0201 0121 1001", ("1001","121","201")เป็นผลที่ถูกต้องเมื่อได้รับการป้อนข้อมูลของ9)

ตัวอย่าง

  • 2 => 10, 2
  • 9 => 1001, 201, 121
  • 10 => 1010, 210, 202, 1002, 122
  • 23 => 2111, 10111
  • 37 => 100101, 20101, 100021, 20021, 12101, 12021, 11221


1
สอง? ในไบนารี? การคำนวณควอนตัมนี้หรือไม่
Matthew Roh

คำตอบ:


10

GolfScript (25 ไบต์) / CJam ( 19 17 ไบต์)

GolfScript:

{:^.*,{3base}%{2base^=},}

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่ระบุตัวตน (ดูที่การสนทนาเมตาเกี่ยวกับการอนุญาตของฟังก์ชั่นที่ไม่ระบุชื่อ )

การสาธิตออนไลน์

การแปลเป็น CJam โดยตรง (ด้วยMartin Büttnerสำหรับการโกนตัวละครสองตัว)

{:X_*,3fb{2bX=},}

การผ่า

{             # Function boilerplate
  :^          # Store parameter as variable ^
  .*          # Square parameter - see detailed explanation below
  ,{3base}%   # Produce an array of 0 to ^*^-1 in ternary
  {2base^=},  # Filter to those which evaluate to ^ in binary
}

เหตุผลสำหรับการดำเนินงาน squaring ^คือการที่เราต้องย้ำถึงความคุ้มค่าที่เป็นไปได้ที่ใหญ่ที่สุดที่มีการแสดงประกอบไปตีความในไบนารีจะมีค่าเท่ากับ เนื่องจาก2 = 10การแสดงไบนารีแบบ "ปกติ" ของรายการ^นั้นเป็นสิ่งที่สำคัญ หากเราแปลงสิ่งนั้นให้เป็นไตรภาคเราจะพบว่าคดีที่ "แย่ที่สุด" คือพลังของ 2 วิธีการที่เหมาะสมที่สุดคือการโต้แย้งว่าอำนาจของln 3/ln 2 ~= 1.585มัน แต่กำลังสองนั้นสั้นกว่ามาก


ฉันพนันได้เลยว่าการแปล CJam นั้นจะเล็กกว่ามาก
เครื่องมือเพิ่มประสิทธิภาพ

1
@Optimizer ลุยต่อไป ;-)
John Dvorak

GolfScript? ผู้ชายฉันช่างเป็น noob
pythonian29033

8

Python 2 (59 ไบต์)

S=lambda n,B="":[B][n:]or~n%2*S(n/2-1,"2"+B)+S(n/2,`n&1`+B)

(ขอขอบคุณ @grc, @xnor และ @PeterTaylor ที่ช่วยในการแชท)

เรียกซ้ำง่าย ๆ โทรออกด้วยS(23)หรือคล้ายกัน

คำอธิบาย

แนวคิดทั่วไปคือว่าถ้าn's ไบนารีการขยายตัวปลายใน1แล้วใด ๆ หลอกไบนารี ( 'ไบนารี แต่เจ้าตัว') 1การขยายตัวยังต้องจบลงด้วยการ มิฉะนั้นมันอาจจะจบลงด้วยหรือ02

ดังนั้นเรามองไปที่บิตสุดท้ายของการnแบ่งและสาขาตาม

การผ่า

S=lambda n,B="":           # Lambda expression
[B][n:]or                  # Short circuit, return [B] if n==0 else what follows
~n%2*                      # Keep next list result if n is even else turn into []
S(n/2-1,"2"+B)             # Add a "2" to B, recurse
+
S(n/2,`n&1`+B)             # Add "0" or "1" to B depending on n's last bit, recurse

ตัวแปร:

  • n: จำนวนที่เราต้องการค้นหาส่วนขยายหลอกของไบนารี
  • B: สตริงหลอกหลอกไบนารีถูกสร้างจากขวาไปซ้าย

5

Bash + coreutils, 77

f()(seq `dc -e2o$1p`|sed '/[3-9]/d;s/.*/&n9P2i&pAi/'|dc|grep -Po ".*(?= $1)")

(นั่นคือTABอักขระในนิพจน์ grep)

นี่คือก้มกฎนี้เล็กน้อย:

"ในกรณีที่ไม่น่าเป็นไปได้ที่ภาษาจะมีฟังก์ชันในตัวเพื่อให้ได้ผลลัพธ์ก็จะไม่ได้รับอนุญาต"

ปรากฎว่าdcมีสิ่งที่ตรงกันข้ามกับสิ่งที่เราต้องการในตัวเช่นถ้าเราตั้งค่าฐานอินพุตเป็น 2 และใส่เลขฐานสองด้วย twos มันจะแยกวิเคราะห์ได้อย่างถูกต้อง (ในทำนองเดียวกันถ้าโหมดการป้อนข้อมูลเป็นฐาน 10 แล้ว AF จะถูกแยกวิเคราะห์เป็นทศนิยม "หลัก" 10-15)

seqสร้างรายการของตัวเลขทศนิยมทั้งหมดจนถึงการแสดงไบนารีแบบมาตรฐานของ n แยกวิเคราะห์เป็นทศนิยม จากนั้นตัวเลขทั้งหมดที่มีสิ่งอื่นนอกเหนือจาก {0,1,2} จะถูกกรองออก จากนั้นdcแยกตัวเลขที่เหลือเป็นไบนารีเพื่อดูว่าการประเมินใดกลับไปที่ n

ฟังก์ชั่น Bash สามารถ "คืน" จำนวนเต็มสเกลาร์ได้ 0-255 เท่านั้น ดังนั้นฉันจึงใช้เสรีภาพในการพิมพ์รายการไปยัง STDOUT เพื่อให้เป็น "การย้อนกลับ" นี่เป็นสำนวนสำหรับเชลล์สคริปต์

เอาท์พุท:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$

4

Haskell, 82

t n=[dropWhile(==0)s|s<-mapM(\_->[0..2])[0..n],n==sum[2^(n-i)*v|(i,v)<-zip[0..]s]]

นี่เป็นเพียงวิธีแก้ปัญหาที่ไร้เดียงสา มันไม่มีประสิทธิภาพมากเพราะคาดว่าจะเกิดความเป็นไปได้ใน 3 ^ n


3

ความท้าทายของเยลลี่ , 10 ไบต์, ภาษาลงวันที่

ṗ@3Ḷ¤Ḅ=¥Ðf

ลองออนไลน์!

โซลูชัน bruteforce ถึงจำนวนของไฮเปอร์บิตเท่ากับอินพุต (รูปแบบนี้เรียกว่า "ไฮเปอร์ไบนารี่") เช่นนี้มันไม่มีประสิทธิภาพอย่างเหลือเชื่อทำงานใน O (3 n )

คำอธิบาย

ṗ@3Ḷ¤Ḅ=¥Ðf
ṗ@            Construct all lists with the given length, and elements taken from
  3Ḷ¤         the list [0,1,2]
        Ðf    then take only those elements which
     Ḅ=¥      when interpreted as binary, equal {the original number}

2

PHP, 138 ไบต์

function p($v,$i=0,$r=""){global$a;if($v==0)$a[]=$r?:0;elseif($v>0)for(;$l<3;)p($v-2**$i*$l,$i+1,+$l++.$r);}p($argv[1]);echo join(",",$a);

ชำรุด

function p($v,$i=0,$r=""){
    global$a;
    if($v==0)$a[]=$r?:0;  # fill result array
    elseif($v>0) # make permutations
        for(;$l<3;)
            p($v-2**$i*$l,$i+1,+$l++.$r); #recursive
}
p($argv[1]);
echo join(",",$a); # Output


1

k, 21 ไบต์

ใช้วิธีเดียวกันกับคำตอบ Golfscript ของ Peter Taylor

{X@&x=2/:'X:3\:'!x*x}

ตัวอย่าง:

k) {X@&x=2/:'X:3\:'!x*x}9
(1 2 1;2 0 1;1 0 0 1)
k) {X@&x=2/:'X:3\:'!x*x}10
(1 2 2;2 0 2;2 1 0;1 0 0 2;1 0 1 0)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.