แปลงจากฐาน 10 เป็นฐาน 2 โดยไม่มีการแปลงในตัว


16

พื้นหลัง :

คุณได้รับมอบหมายให้แปลงเลขฐาน 10 เป็นฐาน 2 โดยไม่ต้องใช้ฟังก์ชันการแปลงพื้นฐานใด ๆ คุณไม่สามารถใช้ห้องสมุดที่นำเข้ามาได้

ปัญหา :

แปลงสตริงอินพุตจากฐาน 10 (ฐานสิบ) เป็นฐาน 2 (ไบนารี) คุณไม่สามารถใช้รหัสการแปลง / ฟังก์ชัน / วิธีการแปลงพื้นฐานหรือไลบรารีที่นำเข้ามา เนื่องจากนี่คือคำตอบที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

อินพุตจะเป็นอะไรก็ได้ตั้งแต่ -32768 ถึง 32767 (รวมถึงการจัดการไบต์สัญญาณในรหัสของคุณ)


3
ถาม: "การจัดการสัญญาณแบบ byte" หมายถึงอะไร - ฉันจะเอาท์พุท "-xxxx" สำหรับจำนวนลบหรือไม่ ถ้าอย่างนั้นเราบางคนก็ผิด ฉันที่ฉันส่งออก "11 ... 11" สำหรับ -1 (หรือที่ไม่ได้ลงชื่อ)
blabla999

การจัดการไบต์ของสัญญาณ - MSB ของตัวแปรที่เซ็นชื่อจะควบคุมว่ามันเป็นค่าลบหรือไม่
TheDoctor

1
แน่นอน แต่ฉันต้อง> พิมพ์ <พวกเขาเป็นเครื่องหมาย '-' ตามด้วยขนาดหรือไม่
blabla999

@ blabla999 - คุณไม่ทำหรอก
TheDoctor

3
the MSB of signed variables controls if they are negative- ที่ฟังดูเหมือนบิต แต่เป็นช่วงที่-32768..32767แนะนำคุณต้องการส่วนประกอบของ 2 คุณต้องการแบบไหน .. ..
mniip

คำตอบ:


4

GolfScript - 17 ไบต์

~{.1&\2/}16*;]-1%

~2baseไม่มากเกินไปมากขึ้นอย่างละเอียดกว่าในตัว


1
ฉันไม่ทราบ golfscript แต่มีบางตัวอย่างที่นำฉันไปสู่ข้อสรุปว่าคุณควรลบ~
user12205

@ace เนื่องจากอินพุตเริ่มต้นเป็นสตริง"37"ตัวอย่างเช่นการดำเนินการ"37" & 1(เป็นมัด) คือการดำเนินการที่กำหนดไว้ ~ที่ด้านหน้าแปลงการป้อนข้อมูลที่เป็นจำนวนเต็ม
primo

ฉันทำการทดสอบที่นี่golfscript.apphb.com/นี่หมายความว่าล่ามนี้ไม่ถูกต้องหรือไม่? (ขออภัยฉันไม่รู้อะไรเลยเกี่ยวกับ golfscript)
user12205

2
ล่ามนั้นถูกต้อง เนื่องจากคุณได้ใส่ค่าจำนวนเต็ม10ลงในสแต็กจึงไม่จำเป็นต้องประเมินค่า อย่างไรก็ตามเมื่ออ่านจากstdinอินพุตจะเป็นสตริง ( ทดสอบที่นี่ ) คำอธิบายปัญหาระบุอย่างชัดเจนด้วยว่าอินพุตเป็นสตริง
primo

12

JavaScript, 46

for(x=prompt(o='');x;x>>>=1)o=(x&1)+o;alert(o)

ฮ่า ๆ ฉันไม่รู้ด้วยซ้ำว่ามีตัวละคร 4 ตัว ( >>>=) อยู่! +1 (นอกจากนี้หากคุณเรียกใช้ในคอนโซลคุณสามารถบันทึกอักขระ 9 ตัวสุดท้ายได้)
Doorknob

1
ไม่ใช่ตัวอักษร 4 ตัวมันคือโอเปอเรเตอร์สองตัว: >>> คือการเปลี่ยนบิตขวา 0 ระดับการเติมตามด้วยการมอบหมาย ลอง: x=8; x>>>=1; x;และx=8; x>>>1; x;- ในกรณีแรกค่าของ x มีการเปลี่ยนแปลง; ในครั้งที่สองมันไม่ได้
เกรแฮมชาร์ลส์

3
@GrahamCharles >>>=เป็นผู้ประกอบการเดียว
primo

ดูนั่นสิ! ขอบคุณ @primo ... คุณเรียนรู้ทุกวัน!
Graham Charles

2
@ComFreek นั่นจะกลับคำสั่งของตัวเลข
คัดลอก

4

Brainf * ck, 98 77

เห็นได้ชัดว่านี่ไม่ใช่เพื่อจุดประสงค์ในการชนะ แต่สิ่งที่การแข่งขันจะเป็นถ้ามันไม่ได้มีวิธีแก้ปัญหาสมอง

++++[>++++<-]>>,<[->>++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++[->++++++++<]>.[-]>[-<<<+>>>]<<<<]

เนื่องจาก brainfk สามารถจัดการจำนวนเต็ม 8 บิตได้เท่านั้นและไม่มีเชิงลบเลยฉันคิดว่ามันไม่ได้ปฏิบัติตามกฎอย่างเต็มที่ แต่เดี๋ยวก่อนฉันไม่เคยชนะเลย

วิธีนี้ใช้ได้กับอินพุต 16 บิตหากล่ามของคุณรองรับ

ฉันยังได้รับมันเพื่อส่งออกในค่า ASCII

นี่คือรหัสอธิบายประกอบ:

++[>++++<-]                       preload 8 onto cell 1
>>,<                                input into cell 2
[-                                  iterate over cell 1
    >>++<                               put 2 in cell 3
    [->-[>+>>]>[+[-<+>]>+>>]<<<<<]      division algorithm: converts {n d} into {0 d_minus_n%d n%d n/d}
    >[-]++++++[->++++++++<]>           clears cell 4 and puts 48(ascii of 0) into cell 5
    .[-]                                output n%2 and clear it (the bit)
    >[-<<<+>>>]                         bring n/2 into cell 2 (to be used for division in next iteration)
<<<<]                               end iterate

อัลกอริทึมที่สั้นกว่า (77):

+>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+>+>+>+>+>+<<<<<<<<]>[.>]

อันนี้สามารถจัดการจำนวนเต็ม 8 บิตเท่านั้น

อัลกอริธึมทำงานโดยใช้ตัวนับไบนารีซึ่งสั้นมากจริง ๆ (เพิ่มทีละหนึ่ง>[->]++[-<+]-<-ซึ่งวางบิตออก) ปัญหาคือมันยากที่จะพิมพ์บิตทั้งหมด

อัลกอริทึมสุดท้ายนั้นสามารถปรับให้พอดีกับจำนวนบิตใด ๆ ที่มีค่าใช้จ่ายของไบต์ เพื่อให้สามารถจัดการกับจำนวนเต็ม N บิตจะต้องใช้ 53 + 3 * N ไบต์ในการเข้ารหัส

ตัวอย่าง:

(1 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+<]>[.>]
(2 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+<<]>[.>]
(3 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+<<<]>[.>]
etc

3

APL ที่ได้รับคำตอบ - 21 22

"01"[1+2|⌊⎕÷2⋆⊖0,⍳15]

ตัวอย่าง:

      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 0
0000000000000000
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 13
0000000000001101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 9999
0010011100001111
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: -3
1111111111111101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 32767
0111111111111111

คุณสามารถลดเกือบ 50% โดยใช้และกลับอาร์เรย์ของบิตแทนสตริง:⎕IO←0 2|⌊⎕÷2*⊖⍳16
59

3

ทัวริงรหัสเครื่อง 272 ไบต์

ตามปกติฉันใช้ไวยากรณ์ตารางกฎที่กำหนดไว้ที่นี่ คุณสามารถทดสอบบนไซต์นั้นหรือใช้การใช้จาวานี้

รหัสจำนวนมากถูกคัดลอกจากตัวแปลงทศนิยมเป็นฐานสิบหกของฉันที่นี่

0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 9 l 1
1 1 0 l 2
1 2 1 l 2
1 3 2 l 2
1 4 3 l 2
1 5 4 l 2
1 6 5 l 2
1 7 6 l 2
1 8 7 l 2
1 9 8 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 0 l 3
4 * * r 4
4 _ _ r A

นับถอยหลังจากอินพุตในฐาน 10 ในขณะที่นับจาก 0 ในฐาน 2 เมื่อลดลงเป็นศูนย์มันจะลบบล็อกอินพุตและสิ้นสุด



2

Perl, 44

นี่เป็นโปรแกรม Perl ครั้งแรกของฉันดังนั้นโปรดยกโทษให้ฉันถ้าสิ่งนี้สามารถเล่นกอล์ฟได้ง่ายขึ้น แก้ไข: ขอบคุณ @primo ที่สละ 7 ตัวอักษรออกไปจากคำตอบของฉัน

$x=<>;do{@s=($x&1,@s)}while($x>>=1);print@s

$x=<>;do{push@s,$x&1}while($x>>=1);print reverse@s

ตรรกะเป็นหลักเหมือนกับโซลูชัน C ก่อนหน้าของฉัน

นอกจากนี้ยังใช้ 64 บิต


1
คุณสามารถบันทึกโดยการสร้างถอยหลังอาร์เรย์:reverse @s=($x&1,@s)
primo

1
ตอนนี้การประกวดที่มีมากกว่าที่ดีที่สุดที่ฉันพบคือ $\=$_%2 .$\while$_=$_>>1||<>;print34: หรือถ้าเลือกบรรทัดคำสั่งนับหนึ่งไบต์แต่ละ 27: การใช้1while$\=$_%2 .$\,$_>>=1}{ -p
primo

2

Javascript - 56 48 และ36 28 ตัวอักษร

  • ไม่ทำงานกับจำนวนลบ

ขอบคุณ @Blender สำหรับการโกน 8 ตัวอักษร

แบบฟอร์มนี้รับอินพุตและแสดงเอาต์พุต 48 ตัวอักษร:

x=prompt();for(a="";x;x=~~(x/2))a=x%2+a;alert(a)

หากเพียงแค่คำสั่งที่ทำให้aตัวแปรxจำเป็นต้องใช้รูปแบบไบนารีของตัวแปร(และคุณไม่ต้องกังวลกับการทำลายxค่าที่เป็นผลข้างเคียง) นี่คืออักขระ 28 ตัว:

for(a="";x;x=~~(x/2))a=x%2+a

1
คุณสามารถแทนที่Math.floorด้วย~~เนื่องจากช่วงสำหรับตัวเลขมีขนาดเล็ก
เครื่องปั่น

@ Blender ขอบคุณฉันรู้ว่ามีบางวิธีที่ไม่สามารถหาได้
Victor Stafusa

@Victor ฉันไม่รู้จัก javascript ดังนั้นฉันอาจจะผิด แต่ท้ายที่สุดเมื่อคุณบอกว่าa=x%2+aสิ่งนี้อาจสั้นลงได้a+=x%2หรือ มันทำงานได้ในทุกภาษาที่ฉันรู้
Albert Renshaw

@AlbertRenshaw ไม่นี่จะเหมือนกันa=a+x%2แต่+สำหรับการต่อสตริง นั่นคือข้อเสนอแนะของคุณให้ผลลัพธ์เป็นตัวเลขตามลำดับย้อนหลัง
Victor Stafusa

@Victor Ah! ขอขอบคุณ!
Albert Renshaw

2

Python - 61ตัวอักษร 60

x=input();print"".join("01"[x>>i&1]for i in range(15,-1,-1))

2
คุณสามารถกำจัดช่องว่างระหว่างและprint ""
เครื่องปั่น

@Blender ฉันเป็นเพียงเกี่ยวกับการให้คำแนะนำในสิ่งเดียวกัน :)
อัลเบิร์ Renshaw

@ Blender Ha จริงไม่ได้สังเกต ทำ!
C0deH4cker

ถ้าคุณเรียกมันจากบรรทัดคำสั่งคุณสามารถทิ้งไว้ได้printเพราะมันจะส่งคืนผลลัพธ์โดยอัตโนมัติ
paul.oderso

2

C, 55 ตัวอักษร

พิมพ์ศูนย์นำหน้าพิเศษ (เพื่อประโยชน์ 2 ไบต์)
การเรียกซ้ำภายในการprintfกลับคำสั่งพิมพ์ดังนั้นอัลกอริทึมจะแยกบิตจากขวาไปซ้าย แต่พิมพ์จากซ้ายไปขวา

แก้ไข : บันทึกถ่านโดยใช้แทนputcharprintf

f(x){(x*=x<0?-printf("-"):1)&&f(x/2);putchar(48+x%2);}

2

Dyalog APL ขนาด 11 ไบต์

2|⌊⎕÷2*⌽⍳16

2|ส่วนที่เหลือเมื่อลดลงครึ่งหนึ่งของ
ค่าที่ถูกปัดเศษลงของ
อินพุต
÷หารด้วยแต่ละ
2*สองถึงพลังของแต่ละ
⍳16{0, 1, 2, ... , 15}

ต้องการ⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ

ลองใช้ออนไลน์!


1

C, 81

char b[17];i=15;main(x){scanf("%d",&x);while(i+1)b[i--]=(x&1)+48,x>>=1;puts(b);}

เอาต์พุตมี 16 บิตอย่างเคร่งครัด (รวมถึงศูนย์ padding)


1

แอพสคริปต์ + Google ชีต, 147 144 121 ไบต์

ต้นฉบับ

function j(decNumb){var str='';do{str=String(decNumb%2)+str;decNumb=decNumb/2|0;}while(decNumb>=1);return parseInt(str);}

แผ่น

=j(b1)

เวอร์ชั่นที่แก้ไขของสคริปต์นี้โดย ZygD


คุณสามารถลบช่องว่างใด ๆ
NoOneIsHere

1

Haskell, 66 ไบต์

c 0=0
c n=c(div n 2)*10+mod n 2
b('-':r)='-':b r
b r=show.c.read$r

โทรด้วยb "-1023"เพิ่มmain=interact bสำหรับโปรแกรมที่สมบูรณ์หรือ ลองบน Ideon

cทำการแปลงสำหรับจำนวนเต็มบวก
b r=show.c.read$rแปลงสตริงเป็นตัวเลขใช้cและแปลงกลับเป็นสตริง
b('-':r)='-':b rดึงแถบที่เป็นไปได้-และผนวกต่อท้ายผลลัพธ์อีกครั้ง


1

PowerShell, 59 87 82 70 ไบต์

+28 ไบต์สำหรับรองรับจำนวนลบ
-12 ไบต์ขอบคุณ @ ASCII-only

param($d)$m=$d-lt0;while($d){$n="01"[$d%2]+$n;$d=($d-$d%2)/2}'-'*$m+$n

ลองออนไลน์!

ดัดแปลงมาจากรหัสนี้ -dจะเข้าผ่านพารามิเตอร์ commandline


แล้วตัวเลขที่มีเครื่องหมายล่ะ
mazzy




1

APL (NARS), 17 ตัวอักษร, 34 ไบต์

{2∣⌊⍵÷2*(⍺-1)..0}

เป็นสำเนาและแก้ไขคำตอบของอดัม/codegolf//a/90107 ในวิธีที่เราสามารถเพิ่มพารามิเตอร์สำหรับบิตที่มีความยาวได้และ⎕IOสำหรับฟังก์ชันนี้ (นี่คือ⎕IO = 1) ไม่มีความสำคัญ ...

  f←{2∣⌊⍵÷2*(⍺-1)..0}
  16 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  16 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  64 f ¯12345678
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 

มันดูเหมือนง่ายต่อการจัดการจำนวนบิตด้วยวิธีนี้ (ฉัน cheked ว่าผลลัพธ์สุดท้ายควรจะถูก)


0

Smalltalk (Smalltalk / X), 63/78

รุ่นแรกสร้างสตริงกลาง (78):

t:=Number readFrom:Stdin.
((15to:1by:-1)collect:[:i|$0+(t>>i&1)]as:String)print

ที่จริงแล้วไม่จำเป็นต้องสร้างสตริง เพียงแค่เอาตัวอักษร (63):

t:=Number readFrom:Stdin.
15to:1by:-1 do:[:i|($0+(t>>i&1))print]

mhmh - มีวิธีที่สั้นกว่าในการอ่านตัวเลขหรือไม่?



0

Bash, 44

f=b+=n/2**e%2*10**e,2**e++/n?f=b:f;echo $[f]

nผ่านค่าเข้ากับสคริปต์ที่ผ่านตัวแปรสภาพแวดล้อม LONG_MAXแสดงทศนิยมของผลไบนารีไม่สามารถเกิน

สิ่งนี้ควรเข้ากันได้กับksh93และzshถ้าbและและeจะถูกเตรียมใช้งาน0และการขยายตัวทางคณิตศาสตร์ที่เหมาะสมจะใช้


1
ฉันไม่เชื่อว่าสิ่งนี้ถูกต้องเพราะถือว่าnมีการกำหนดไว้แล้วทำให้เป็นข้อมูลโค้ด ที่สามารถแก้ไขได้โดยการป้อนข้อมูลเป็นอาร์กิวเมนต์บรรทัดคำสั่งและการตั้งค่าnที่ในสคริปต์ของคุณ
ปาเก็ตตี้

@quartata ตัวแปรในบริบททางคณิตศาสตร์ในเชลล์เป็นศูนย์โดยปริยาย สำหรับวัตถุประสงค์ของกอล์ฟก็จะทำให้รู้สึกมากขึ้นที่จะทำมากกว่าn=127 sh -c '...' sh -c 'n=$1 ...' _ 127ไม่มีเหตุผลที่จะชอบสิ่งใดสิ่งหนึ่งเหนือสิ่งอื่นใดในกรณีนี้เนื่องจากทั้งสองวิธีเป็นวิธีที่ดีที่สุดในการส่งผ่านค่า
ormaaj

0

C # - 104

string p(int d){var r="";long i=1;while(r.Length<=64){var g=d&i;r=(g!=0)? "1"+r:"0"+r;i=i<<1;}return r;}

วิธีนี้จะแปลงทศนิยมให้เป็นไบนารีถึง64บิต

เมื่อดำเนินการวิธีการข้างต้นใน Linqpad - rr = p (-32768); rr.Dump ();

เอาท์พุท: 01111111111111111111111111111111111111111111111111000000000000000


ข้อมูลจำเพาะเรียกร้องให้ "สตริงการป้อนข้อมูล" intดูเหมือนว่าวิธีนี้ยอมรับ
Poke

0

Java 8, 80 71 ไบต์

n->{String r="";for(int i=n<0?-n:n;i>0;i/=2)r=i%2+r;return n==0?"0":r;}

-9 ไบต์เนื่องจากกฎในความคิดเห็น .. อินพุตฐาน 10 ลบอาจส่งคืนค่าบวก / สัมบูรณ์เบส -2 ตามที่เห็นได้ชัดเอาท์พุท

คำอธิบาย:

ลองออนไลน์

n->{                   // Method with integer parameter and String return-type
  String r="";         //  Result-String, starting empty
  for(int i=n<0?-n:n;  //  Start `i` at the absolute (non-negative) value of the input
      i>0;             //  Loop as long as `i` is not 0
      i/=2)            //    After every iteration: integer-divide `i` by 2
    r=i%2+r;           //   Prepend the result with `i` modulo-2
  return n==0?         //  If the input is 0:
          "0"          //   Return literal "0"
         :             //  Else:
          r;           //   Return the result-String


0

พื้นฐานขนาดเล็ก 133 ไบต์

สคริปต์ที่อินพุตและเอาต์พุตไปยังTextWindowคอนโซล

n=TextWindow.Read()
While n>0
c=c+1
x[c]=Math.Remainder(n,2)
n=Math.Floor(n/2)
EndWhile
For i=0To c-1
TextWindow.Write(x[c-i])
EndFor

ลองที่ SmallBasic.com ต้องใช้ Silverlight และจะต้องทำงานใน IE

I / O ถ่าย / รับจากคอนโซลสีดำ

-22 ไบต์ขอบคุณ@Neil


คุณไม่สามารถใช้For i=0To c-1?
Neil

@ Neil - ฉันทำได้อย่างแน่นอน เยี่ยมมาก!
เทย์เลอร์สกอตต์

0

MATL , 15 17 ไบต์

t0<?16Ww+]`2&\t]x

ลองใช้กับ MATL Online

TIO

(+2 ไบต์นำหน้าหมายเลข 0 ออกเพื่อลบจำนวนบิตเครื่องหมายบิตควรเป็นบิตแรก)

เอาต์พุตบน MATL Online ควรอ่านจากล่างขึ้นบน (MSB อยู่ด้านล่าง)

ส่วนหลักเรียบง่าย: `2&\t = ในขณะที่ค่ามากกว่า 0 หารด้วย 2 และสะสมส่วนที่เหลือ

การจัดการตัวเลขติดลบและให้การแทนสมบูรณ์แบบ 2 นั้นเป็นส่วนที่ยุ่งยาก ในที่สุดฉันก็ไปกับ " ลบออกจาก2ยังไม่มีข้อความ"วิธีการรับส่วนประกอบสองตัวเนื่องจากเราจำเป็นต้องจัดการค่าสูงสุด -32768 เท่านั้นสำหรับตัวเลขติดลบที่โค้ดสร้างขึ้น 216=65536ด้วย16Wเพิ่มอินพุตให้กับ (เช่น 65536 + (-42)) ซึ่งให้อะไรบางอย่างที่ MATLAB เห็นว่าเป็นตัวเลขบวก




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