Chuyển đổi từ cơ sở 10 sang cơ sở 2 mà không chuyển đổi cơ sở tích hợp


16

Bối cảnh :

Bạn đã được giao nhiệm vụ chuyển đổi số 10 cơ sở sang cơ sở 2 mà không sử dụng bất kỳ chức năng chuyển đổi cơ sở có sẵn nào. Bạn không thể sử dụng bất kỳ thư viện nhập khẩu.

Vấn đề :

Chuyển đổi một chuỗi đầu vào từ cơ sở 10 (thập phân) sang cơ sở 2 (nhị phân). Bạn không được sử dụng bất kỳ mã / chức năng / phương thức chuyển đổi cơ sở nào hoặc các thư viện đã nhập. Vì đây là , câu trả lời ngắn nhất tính bằng byte sẽ thắng.

Đầu vào sẽ là bất cứ thứ gì từ -32768 đến 32767 (bao gồm xử lý byte ký hiệu trong mã của bạn)


3
Hỏi: "xử lý byte ký hiệu" nghĩa là gì - tôi sẽ xuất "-xxxx" cho số âm? Sau đó, một số người trong chúng ta là sai, bao gồm. tôi, khi tôi xuất "11 ... 11" cho -1 (còn gọi là chưa ký)
blabla999

Xử lý byte ký hiệu - MSB của các biến đã ký kiểm soát nếu chúng âm tính
TheDoctor

1
chắc chắn, nhưng tôi có phải> in <chúng dưới dạng dấu '-' theo sau là độ lớn không?
blabla999

@ blabla999 - Không bạn không
TheDoctor

3
the MSB of signed variables controls if they are negative- nghe có vẻ như bit dấu, tuy nhiên như phạm vi -32768..32767gợi ý, bạn muốn phần bù của 2. Vì vậy, bạn muốn gì? ..
mniip

Câu trả lời:


4

GolfScript - 17 byte

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

Không quá nhiều dài dòng hơn so với tích hợp ~2base.


1
Tôi không biết bản đánh gôn nhưng một vài mẫu chạy khiến tôi kết luận rằng bạn nên xóa~
user12205

@ace Bởi vì đầu vào ban đầu là một chuỗi "37", ví dụ, hoạt động "37" & 1(trong infix) là một hoạt động khôn ngoan. Ở ~phía trước chuyển đổi đầu vào thành một số nguyên.
primo

Tôi đã làm bài kiểm tra của mình ở đây golfscript.apphb.com/. Điều này có nghĩa là trình thông dịch này không chính xác? (Xin lỗi tôi thực sự không biết gì về golfscript)
user12205

2
Thông dịch viên là chính xác; bởi vì bạn đã đẩy giá trị nguyên 10lên ngăn xếp, không cần thiết phải đánh giá nó. Tuy nhiên, khi đọc từ stdin, đầu vào sẽ là một chuỗi ( kiểm tra ở đây ). Mô tả vấn đề cũng nói rõ rằng đầu vào là một chuỗi.
primo

12

JavaScript, 46

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

Lol, tôi thậm chí còn không biết rằng một toán tử 4 ký tự ( >>>=) đã tồn tại! +1 (Ngoài ra, nếu bạn chạy nó trong bảng điều khiển, bạn có thể lưu 9 ký tự cuối cùng.)
Doorknob

1
Đó không phải là 4 ký tự, đó là hai toán tử: >>> là dịch chuyển bên phải theo bit 0, theo sau là một bài tập. Hãy thử: x=8; x>>>=1; x;x=8; x>>>1; x;- trong trường hợp đầu tiên, giá trị của x đã thay đổi; trong lần thứ hai, nó không có.
Graham Charles

3
@GrahamCharles >>>=là một toán tử duy nhất .
primo

Chà, nhìn kìa! Cảm ơn, @primo ... bạn học được điều gì đó mỗi ngày!
Graham Charles

2
@ComFalet Điều đó sẽ đảo ngược thứ tự của các chữ số
sao chép

4

Brainf * ck, 98 77

Rõ ràng điều này không nhằm mục đích chiến thắng nhưng cạnh tranh sẽ là gì nếu nó không có giải pháp brainfk

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

Vì brainfk chỉ có thể xử lý các số nguyên 8 bit và không có tiêu cực nào, tôi đoán nó không hoàn toàn tuân thủ các quy tắc nhưng hey tôi chưa bao giờ ở trong đó để giành được nó.

Điều này thực sự hoạt động cho đầu vào 16 bit nếu trình thông dịch của bạn hỗ trợ

Tôi thậm chí đã có nó để đầu ra trong các giá trị ascii

Đây là mã chú thích:

++[>++++<-]                       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

Thuật toán ngắn hơn (77):

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

Điều này chỉ có thể xử lý số nguyên 8 bit.

Thuật toán hoạt động bằng cách sử dụng bộ đếm nhị phân thực sự rất ngắn (một mức tăng >[->]++[-<+]-<-sau đó đưa ra các bit. Vấn đề là rất khó để in ra tất cả các bit

Thuật toán cuối cùng đó có thể được điều chỉnh để phù hợp với bất kỳ số bit nào với chi phí byte. Để có thể xử lý các số nguyên N bit, cần phải có byte 53 + 3 * N để mã hóa.

ví dụ:

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

3

Câu trả lời APL bắt buộc - 21 22

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

Ví dụ:

      "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

Bạn có thể giảm gần 50% bằng cách sử dụng ⎕IO←0và trả về một mảng bit thay vì chuỗi : 2|⌊⎕÷2*⊖⍳16.
Adám

3

Mã máy Turing, 272 byte

Như thường lệ, tôi đang sử dụng cú pháp bảng quy tắc được xác định ở đây. Bạn có thể kiểm tra nó trên trang web đó hoặc, thay vào đó, bằng cách sử dụng triển khai java này.

Rất nhiều mã được sao chép từ trình chuyển đổi thập phân sang hex của tôi ở đây.

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

Đếm ngược từ đầu vào trong cơ sở 10 trong khi đếm từ 0 trong cơ sở 2. Khi giảm 0, nó sẽ xóa khối đầu vào và chấm dứt.


2

Javascript 59

o='';i=parseInt(prompt());do{o=(i&1)+o}while(i>>=1)alert(o)

Bạn có thể sử dụng +xthay vìparseInt(x)
Cyoce

2

Perl, 44

Đây là chương trình Perl đầu tiên của tôi từ trước đến giờ, vì vậy xin vui lòng tha thứ cho tôi nếu điều này có thể dễ dàng đánh gôn hơn nữa. Chỉnh sửa: Cảm ơn bạn @primo vì đã lấy đi 7 ký tự từ câu trả lời của tôi.

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

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

Logic về cơ bản giống như giải pháp C trước đây của tôi.

Ngoài ra, sử dụng 64 bit.


1
Bạn có thể lưu reversebằng cách xây dựng mảng ngược : @s=($x&1,@s).
primo

1
Bây giờ cuộc thi đã kết thúc, điều tốt nhất tôi tìm thấy là 34 : $\=$_%2 .$\while$_=$_>>1||<>;print. Hoặc, nếu các tùy chọn dòng lệnh đếm một byte mỗi, 27: 1while$\=$_%2 .$\,$_>>=1}{bằng cách sử dụng -p.
primo

2

Javascript - 56 48 và 36 28 ký tự

  • Không hoạt động với số âm.

Cảm ơn @Blender đã cạo 8 ký tự.

Biểu mẫu này nhận đầu vào và hiển thị đầu ra, 48 ký tự:

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

Nếu chỉ cần một lệnh đặt trong một biến a, dạng nhị phân của biến xlà cần thiết (và bạn không bận tâm đến việc phá hủy xgiá trị dưới dạng hiệu ứng phụ), thì đây là 28 ký tự:

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

1
Bạn có thể thay thế Math.floorbằng ~~, vì phạm vi cho các số là nhỏ.
Máy xay sinh tố

@Blender Cảm ơn, tôi biết rằng đã có một số cách, chỉ không thể tìm thấy nó.
Victor Stafusa

@Victor Tôi không biết javascript nên tôi có thể sai nhưng cuối cùng khi bạn nói a=x%2+ađiều này có thể rút ngắn được a+=x%2không? Nó hoạt động trong tất cả các ngôn ngữ tôi biết.
Albert Renshaw

@AlbertRenshaw Không, Điều này sẽ giống như a=a+x%2, nhưng đó +là để nối chuỗi. Tức là, đề xuất của bạn dẫn đến các chữ số theo thứ tự ngược.
Victor Stafusa

@Victor ơi! Cảm ơn bạn!
Albert Renshaw

2

Python - 61 60 ký tự

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

2
Bạn có thể thoát khỏi không gian giữa print"".
Máy xay sinh tố

@Blender Tôi chỉ đề nghị điều tương tự :)
Albert Renshaw

@Blender Ha đúng, thậm chí không để ý. Làm xong!
C0deH4cker

nếu bạn gọi nó từ dòng lệnh, bạn có thể bỏ qua một bên printvì nó tự động trả về kết quả
paul.oderso

2

C, 55 ký tự

In một số 0 đứng đầu (vì lợi ích của 2 byte).
Đệ quy trong printfđảo ngược thứ tự in, do đó thuật toán trích xuất các bit từ phải sang trái nhưng in từ trái sang phải.

EDIT : Đã lưu một char bằng cách sử dụng putcharthay vì printf.

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

2

APL Dyalog , 11 byte

2|⌊⎕÷2*⌽⍳16

2|Phần còn lại khi giảm một nửa
giá trị làm tròn xuống của
đầu vào
÷chia cho mỗi
2*hai cho công suất của mỗi
⍳16{0, 1, 2, ..., 15}

Yêu cầu ⎕IO←0mặc định trên nhiều hệ thống.

Dùng thử trực tuyến!


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);}

Đầu ra có đúng 16 bit (bao gồm cả số không đệm)


1

Tập lệnh ứng dụng + Google Sheets, 147 144 121 byte

Kịch bản

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

Tấm

=j(b1)

Phiên bản sửa đổi của tập lệnh này bởi ZygD.


Bạn có thể loại bỏ bất kỳ không gian?
NoOneIsHãy

1

Haskell, 66 byte

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

Gọi với b "-1023", thêm main=interact bcho một chương trình hoàn chỉnh hoặc thử nó trên Ideon.

cthực hiện chuyển đổi cho số nguyên dương.
b r=show.c.read$rchuyển đổi một chuỗi thành một số, áp dụng cvà chuyển đổi trở lại chuỗi.
b('-':r)='-':b rtước một dẫn đầu có thể -và nối lại nó vào kết quả.



1

APL (NARS), 17 ký tự, 34 byte

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

Nó là bản sao và sửa đổi câu trả lời của Adam /codegolf//a/90107 theo cách người ta có thể thêm tham số cho các bit chiều dài và ⎕IO cho hàm này (ở đây là ⎕IO = 1) không quan trọng ...

  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 

Nó dễ dàng xử lý số bit theo cách này (tôi đã nói rằng kết quả cuối cùng sẽ đúng)


0

Smalltalk (Smalltalk / X), 63/78

phiên bản đầu tiên tạo ra một chuỗi trung gian (78):

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

thực tế, không cần phải tạo chuỗi; chỉ cần xuất ký tự (63):

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

mhmh - có cách nào ngắn hơn để đọc đến một số không?


0

Python 3.x: 65 ký tự

b=lambda n:n<2 and'01'[n]or b(n//2)+b(n%2);print(b(int(input())))

0

Bash, 44

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

Truyền một giá trị đầu vào cho tập lệnh thông qua biến môi trường n. Đại diện thập phân của kết quả nhị phân không thể vượt quá LONG_MAX.

Điều này cũng phải tương thích với ksh93zshnếu beđược khởi tạo 0và mở rộng số học thích hợp được sử dụng.


1
Tôi không tin rằng điều này là hợp lệ vì nó giả định nđã được xác định, biến nó thành một đoạn trích. Điều đó có thể được khắc phục bằng cách lấy đầu vào làm đối số dòng lệnh và đặt thành đối số ntrong tập lệnh của bạn.
một spaghetto

@quartata Các biến trong ngữ cảnh toán học trong shell hoàn toàn bằng không. Đối với mục đích của golf, nó có ý nghĩa hơn để làm n=127 sh -c '...'hơn sh -c 'n=$1 ...' _ 127. Không có lý do nào để thích cái này hơn cái kia trong trường hợp này vì cả hai đều là cách hoàn hảo điển hình để vượt qua các giá trị.
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;}

Phương pháp này sẽ chuyển đổi thập phân thành nhị phân lên đến 64bit.

Khi thực hiện phương thức trên trong Linqpad - rr = p (-32768); rr.Dump ();

Đầu ra: 01111111111111111111111111111111111111111111111111000000000000000


Thông số kỹ thuật gọi "chuỗi đầu vào". Có vẻ như phương pháp này chấp nhận một int.
Chọc

0

Java 8, 80 71 byte

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

-9 byte do một quy tắc trong các nhận xét .. Các đầu vào cơ sở-10 âm có thể trả về giá trị dương / tuyệt đối cơ sở-2 như đầu ra rõ ràng.

Giải trình:

Hãy thử trực tuyến.

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

Cơ bản nhỏ , 133 byte

Một tập lệnh nhập từ và đầu ra đến TextWindowbàn điều khiển.

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

Dùng thử tại SmallBasic.com Yêu cầu Silverlight và do đó phải được chạy trong IE.

I / O được lấy / cho từ bảng điều khiển màu đen.

-22 byte nhờ @Neil


Bạn không thể sử dụng For i=0To c-1?
Neil

@Neil - Tôi hoàn toàn có thể. Cú bắt tuyệt vời!
Taylor Scott

0

MATL , 15 17 byte

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

Dùng thử trên MATL Online

TIO

(+2 byte loại bỏ hàng đầu 0 cho số âm, bit dấu phải là bit đầu tiên.)

Đầu ra trên MATL Online nên được đọc từ dưới lên (MSB ở dưới cùng).

Phần chính khá đơn giản: `2&\t= trong khi giá trị lớn hơn 0, chia cho 2 và tích lũy phần còn lại.

2N216=6553616W




Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.