Chuyển đổi cơ sở thực


19

Chúng tôi đã có một vài thách thức đối với chuyển đổi cơ sở, nhưng tất cả chúng dường như áp dụng cho các giá trị nguyên. Hãy làm điều đó với những con số thực!

Các thách thức

Đầu vào:

  • Số dương thực x , được biểu thị trong cơ sở 10. Điều này có thể được coi là số float chính xác kép hoặc dưới dạng chuỗi. Để tránh các vấn đề chính xác, số có thể được giả định là lớn hơn 10 −6 và nhỏ hơn 10 15 .
  • Một căn cứ mục tiêu b . Đây sẽ là một số nguyên từ 2 đến 36.
  • Một số chữ số phân số n . Đây sẽ là một số nguyên từ 1 đến 20.

Đầu ra: biểu diễn của x trong cơ sở b với n chữ số phân số.

Khi tính toán biểu thức đầu ra, các chữ số nằm ngoài n -th nên được cắt bớt (không làm tròn). Ví dụ, x = 3.141592653589793trong cơ sở b = 310.0102110122..., vì vậy đối n = 3với đầu ra sẽ là 10.010(cắt ngắn), không phải 10.011(làm tròn).

Đối với xb tạo ra một số chữ số hữu hạn trong phần phân số, biểu diễn vô hạn tương đương (cắt ngắn thành n chữ số) cũng được cho phép. Ví dụ, 4.5trong thập phân cũng có thể được biểu diễn dưới dạng 4.49999....

Đừng lo lắng về lỗi dấu phẩy động .

Định dạng đầu vào và đầu ra

x sẽ được đưa ra mà không có số không dẫn đầu. Nếu x tình cờ là một số nguyên, bạn có thể giả sử rằng nó sẽ được cung cấp với phần thập phân bằng không ( 3.0) hoặc không có phần thập phân ( 3).

Đầu ra là linh hoạt. Ví dụ: nó có thể là:

  • Một chuỗi đại diện cho số có dấu phân cách phù hợp (dấu thập phân) giữa các phần nguyên và phần phân số. Chữ số 11, 12v.v (đối với b ngoài 10) có thể được biểu diễn dưới dạng chữ cái A, Bnhư bình thường hoặc như bất kỳ ký tự riêng biệt nào khác (vui lòng ghi rõ).
  • Một chuỗi cho phần nguyên và một chuỗi khác cho phần phân số.
  • Hai mảng / danh sách, một cho mỗi phần, chứa các số từ 0đến 35dưới dạng chữ số.

Các hạn chế duy nhất là các phần nguyên và phần phân số có thể được phân tách (dấu phân cách phù hợp) và sử dụng cùng định dạng (ví dụ: không có [5, 11]danh sách đại diện cho phần nguyên và ['5', 'B']cho danh sách đại diện cho phần phân số).

Quy tắc bổ sung

Các trường hợp thử nghiệm

Đầu ra được hiển thị như là một chuỗi với chữ số 0, ..., 9, A, ..., Z, sử dụng .phân số thập phân.

x, b, n                    ->  output(s)

4.5, 10, 5                 ->  4.50000 or 4.49999
42, 13, 1                  ->  33.0 or 32.C
3.141592653589793, 3, 8    ->  10.01021101
3.141592653589793, 5, 10   ->  3.0323221430
1.234, 16, 12              ->  1.3BE76C8B4395
10.5, 2, 8                 ->  1010.10000000 or 1010.01111111
10.5, 3, 8                 ->  101.11111111
6.5817645, 20, 10          ->  6.BCE2680000 or 6.BCE267JJJJ
0.367879441171442, 25, 10  ->  0.94N2MGH7G8
12944892982609, 29, 9      ->  PPCGROCKS.000000000


42, 13, 1chúng ta có thể có 33thay vì 33.0?
LiefdeWen

@LiefdeWen Không, một phần thiết yếu của thử thách là đầu ra phải có nchữ số thập phân
Luis Mendo

Câu trả lời:


1

Thạch , 16 byte

*×⁵b⁸ḞðṖḣ⁹,ṫø⁹N‘

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

Lưu ý rằng singletons được in là phần tử trong đầu ra.


Này, chuyện gì đã xảy ra với bức tranh của bạn vậy?
Luis Mendo

@LuisMendo một số người không thể kết xuất nó, vì nó được kết nối với Facebook
Leaky Nun

Bạn biết bạn có thể tải lên một hình ảnh ở đây, phải không? Những cái mặc định đó rất cá nhân
Luis Mendo

7

JavaScript (ES8), 81 74 71 byte

f=
(x,b,n,g=x=>x.toString(b))=>g(x-x%1)+'.'+g(x%1).substr(2,n).padEnd(n,0)
<div oninput=o.textContent=f(+x.value,b.value,n.value)><input id=x><input type=number min=2 max=36 value=10 id=b><input type=number min=1 max=20 value=10 id=n><pre id=o>

Công trình cho xgiữa 1e-61e21, btừ 2đến 36(chính xác theo yêu cầu) và ntừ 1bất cứ điều gì từ 10để 48tùy thuộc vào cơ sở trước dấu chấm động lỗi leo vào Edit:. Saved 7 byte với sự giúp đỡ từ @Birjolaxew. Đã lưu thêm 3 byte với sự trợ giúp từ @tsh. Phiên bản 74 byte trước đây cũng hoạt động với các số âm:

f=
(x,b,n,[i,d]=`${x.toString(b)}.`.split`.`)=>i+`.`+d.slice(0,n).padEnd(n,0)
<div oninput=o.textContent=f(+x.value,b.value,n.value)><input id=x><input type=number min=2 max=36 value=10 id=b><input type=number min=1 max=20 value=10 id=n><pre id=o>


1
Làm thế nào để một người chuyển đổi cơ sở với regex?!?
Erik the Outgolfer 17/8/17

@EriktheOutgolfer Tôi không phải, đó chỉ là cách chơi golf (hy vọng) trích xuất đến n"chữ số" từ một chuỗi.
Neil

Sau đó, những gì logic lõi của các chức năng của bạn?
Erik the Outgolfer

@EriktheOutgolfer Tại sao, tất nhiên, chức năng chuyển đổi cơ sở tích hợp sẵn của JavaScript. (Gợi ý: nhìn vào nơi tôi sử dụng tham số cơ sở.)
Neil

Ôi nó nói .toString(b)... làm tôi ngớ ngẩn> _ <
Erik the Outgolfer 17/08/17

5

Python 2 , 153 149 144 137 135 109 byte

def f(x,b,m):
 i=int(x);s=[];t=[]
 while i:s=[i%b]+s;i/=b
 while m:m-=1;x=x%1*b;t+=[int(x)]
 return s or[0],t

Tôi không nhận thấy tôi chỉ có thể trả về các chữ số dưới dạng số, vì vậy điều đó làm cho nó đơn giản hơn rất nhiều. Trả về hai danh sách các chữ số, đầu tiên cho phần nguyên, thứ hai cho phân số.

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


Trong trường hợp có ích: Tôi đã thêm một lưu ý rằng bạn chỉ cần hỗ trợ các số lớn hơn 1e-6(và ít hơn 1e15, như trước đây)
Luis Mendo

5

Perl 6 , 25 byte

->\x,\b,\n{+x .base(b,n)}

Thử nó

Mở rộng:

-> \x, \b, \n {
  +x            # make sure it is a Numeric
  .base( b, n ) # do the base conversion
}

Lưu ý rằng không gian là để nó được phân tích cú pháp là (+x).base(b,n)
không +( x.base(b,n) ).


Trong trường hợp có ích: Tôi đã thêm một lưu ý rằng bạn chỉ cần hỗ trợ các số lớn hơn 1e-6(và ít hơn 1e15, như trước đây)
Luis Mendo

3

Toán học, 158 byte

Vì thử thách này đã có câu trả lời rất hay trong toán học của @KellyLowder, tôi đã cố gắng tạo ra (với một cách tiếp cận khác) kết quả chính xác như trong các trường hợp thử nghiệm

ToUpperCase[""<>Insert[StringReplace[ToString@BaseForm[#,p]&/@PadRight[#&@@(d=RealDigits[#,p=#2]),w=(#3+d[[2]])][[;;w]],"\n "<>ToString@p->""],".",d[[2]]+1]]&


đầu vào

[12943612982609, 29, 9]

đầu ra

PPCGROCKS.000000000


3

Ruby , 45 byte

->x,b,n{(x*b**n).round.to_s(b).insert(~n,?.)}

Tại sao?

Vì b ^ n trong cơ sở b là 10 ^ n, chúng tôi nhân x với số đó và sau đó thêm dấu thập phân nơi nó thuộc về.

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


-1 byte + lỗi bằng cách thay thế .roundbằng .to_i; cái này sửa chữ số cuối của đầu ra cho những cái không khớp với đầu ra thử nghiệm. -1 byte hơn bằng cách sử dụng .insert ~n,?., không có dấu ngoặc đơn.
Nnnes

3

C (gcc) ,157 152 byte

Cần 64 bit long intđể làm việc với các trường hợp thử nghiệm lớn hơn.

-5 byte nhờ Peter Cordes

#define P r=99;i=l=x;do{z[--r]=48+7*(l%b>9)+l%b;}while(l/=b);printf(z+r)
long i,r,l;char z[99];f(x,b,n)double x;{P;putchar(46);while(n--){x=(x-i)*b;P;}}

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

chỉnh sửa: một vài byte có thể được cạo nếu nó được phép xuất hai chuỗi được phân tách bằng dấu tách dòng mới:

149 byte:

#define P r=99;i=l=x;do{z[--r]=48+7*(l%b>9)+l%b;}while(l/=b);printf(z+r)
long i,r,l;char z[99];f(x,b,n)double x;{P;puts("");while(n--){x=(x-i)*b;P;}}

chỉnh sửa: bài này không phải là bài dài nhất, yay!


2
Bạn có thể sử dụng printf(z+r)nếu nó không chứa bất kỳ %ký tự nào . (Đây là môn đánh gôn; an ninh và thực hành tốt đi ra ngoài cửa sổ: P). Bạn cũng có thể sử dụng puts(z+r)để có được một dòng mới miễn phí (lưu puts("")phiên bản thứ hai).
Peter Cordes

Cảm ơn! Tôi quên mất việc cung cấp char * trực tiếp dưới dạng mẫu, điều này thực sự tiết kiệm được một vài byte :-) Tôi không thể sử dụng đặt (z + r) trong phiên bản thứ hai vì điều đó có nghĩa là mỗi số thập phân sẽ được in trên một dòng mới
scottinet

Ah, phần cuối đó không rõ ràng nếu không có phiên bản không có ý kiến.
Peter Cordes

floatngắn hơn double, nhưng có vẻ như câu hỏi yêu cầu doubleđầu vào hoặc chuỗi.
Peter Cordes

1
Không cần điều đó. Một số triển khai phổ biến của C có 64 bit longvà theo quy tắc golf-code đó là tất cả những gì bạn cần để câu trả lời của bạn có giá trị. (Ngoài ra, thông thường các câu trả lời golf-mã C và C ++ giả sử là 64 bit long, vì đó là những gì mà Try It Online sử dụng.) Tôi khuyên bạn nên quay lại chỉnh sửa của mình và chỉ cần thêm một ghi chú như " longphải là 64 bit cho cái này để hỗ trợ các trường hợp thử nghiệm lớn hơn. "
Peter Cordes

2

Toán học 47 byte

TakeDrop@@r[#,#2,#3+Last@(r=RealDigits)[#,#2]]&

Gọi RealDigitshai lần để đầu tiên tìm ra số chữ số ở bên trái của số thập phân.


Trong trường hợp có ích: Tôi đã thêm một lưu ý rằng bạn chỉ cần hỗ trợ các số lớn hơn 1e-6(và ít hơn 1e15, như trước đây)
Luis Mendo

1
Tôi nghĩ rằng câu hỏi chỉ là yêu cầu TakeDrop@@RealDigits[##]& nhưng sau đó tôi nhận ra mình đã đọc sai - giải pháp của bạn có vẻ tối ưu.
Đánh dấu S.

2

SageMath , 68 byte

def f(n,b,k):y=n.str(b).split('.')+[''];return y[0],(y[1]+'0'*k)[:k]

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


Trong trường hợp có ích: Tôi đã thêm một lưu ý rằng bạn chỉ cần hỗ trợ các số lớn hơn 1e-6(và ít hơn 1e15, như trước đây)
Luis Mendo

1

Haskell , 188 byte

f=fromIntegral
g 0 _=[]
g n p=g(div n p)p++[mod n p]
z=(!!)(['0'..'9']++['A'..'Z']++['.'])
h x p l|(i,d)<-properFraction x=z<$>(g i p++[36]++(last$g(floor$d*(f p**f l))p:[0<$[1..l]|d==0]))

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

g chuyển đổi một số thành một danh sách đại diện cho số đó trong một cơ sở nhất định

zánh xạ các số nguyên sang chữ cái ( 36 = .)

h áp dụng các hàm trước cho phần nguyên và phần phân số của một số.


1

Tiên đề, 566 byte

c:=alphanumeric()::List Character
f(a:INT,b:PI):List Character==(r:=[];repeat(y:=a rem b;r:=cons(c.(y+1),r);a:=a quo b;a=0=>break);r)
g(x)==floor(x)::INT
F(x)==>for i in 1..#x repeat z:=concat(z,x.i)
w(a:Float,b:PI,n:NNI):String==
  z:="";b<2 or b>36 or a<0=>z
  ip:=g(a);    fp:=g((a-ip)*b^n)
  ipb:=f(ip,b);fpb:=f(fp,b);cnt:=n-#fpb
  for i in 1..cnt repeat fpb:=cons(c.1,fpb)
  F(ipb);z:=concat(z,".");F(fpb)
  z

h(a,b,n)==>(n>=0 and b>0=>(nd123:=10+g(n*log_2(b)/log_2(10));mxv123456:=digits(nd123::PI);res78484:=w(a,b,n);digits(mxv123456);res78484);"")

câu hỏi này đặc biệt khó khăn; Sau một thời gian viết một cái gì đó, kết quả đúng mà nó dường như tạo ra bằng cách sử dụng một macro để giữ các chữ số () ... nó không bị đánh gôn quá nhiều ... kết quả:

(7) -> h(4.5,10,5)
   (7)  "4.50000"
                                                             Type: String
(8) -> h(42,13,1)
   (8)  "33.0"
                                                             Type: String
(9) -> h(%pi,3,8)
   (9)  "10.01021101"
                                                             Type: String
(10) -> h(%pi,5,10)
   (10)  "3.0323221430"
                                                             Type: String
(11) -> h(1.234,16,12)
   (11)  "1.3BE76C8B4395"
                                                             Type: String
(12) -> h(0.367879441171442,25,10)
   (12)  "0.94N2MGH7G8"
                                                             Type: String
(13) -> h(12944892982609,29,9)
   (13)  "PPCGROCKS.000000000"
                                                             Type: String
(14) -> h(6.5817645,20,10)
   (14)  "6.BCE267JJJJ"
                                                             Type: String

mục tiêu thực là một hàm chuyển đổi sang cơ sở 2..36 mỗi Float [có k: = chữ số ()] hoặc mỗi số được tính là% pi hoặc% e hoặc chia hai float / int như trong 1./3 . ['oo' chữ số]

(15) -> h(%pi,13,800)
   (15)
  "3.1AC1049052A2C77369C0BB89CC9883278298358B370160306133CA5ACBA57614B65B410020
  C22B4C71457A955A5155B04A6CB6CC2C494843A8BBBBA9A039B77B34CB0C036CAC761129B3168
  B8BAB860134C419787C911812985646C7AAA3025BAA118B3AB8265CB347852065667291482145
  6C533447BC53A5262177C9985455C395626091A2CC3126B395C91B65B654A1804226197528410
  29A8A4A55CC7937B347B77B5A914127B11C6A57A84510775A9A467819A468B6B74339CC1290B2
  24921C6A771BC2AB6AB41735119C2231545A86399483119AAA5AC34B46B7B5C9089946A364860
  9B26CB0BAC0ABCBA182C12881933AA93C3942C71AA664753989A3C82166BA2109796C4A134607
  59725A72C9117AC980556A147557C319438287226C94725B125753B009387A48AA45CB1960A04
  A064052C00A6069371949872B14590895C555CB01A39B7589824B8621618A8B1971841201A2AB
  B04B80C7534CC1CB079581491995B46C679555316288C82665645A1A600C1A669B865651B6B842470C018B03C1115B3C4306C015C0B45C"
                                                             Type: String

1

Tiên đề, 127 byte

g(a)==floor(a)::INT;f(a:Float,b:PI,n:NNI):Any==(b<2 or n>28=>%i;x:=g(a);radix(x,b)+radix(g((a-x)*b^n),b)::RadixExpansion b/b^n)

các kết quả

(4) -> f(%e,2,10)
   (4)  10.1011011111
                                                   Type: RadixExpansion 2
(5) -> f(%e,3,10)
   (5)  2.2011011212
                                                   Type: RadixExpansion 3
(6) -> f(%e,35,10)
   (6)  2.P4VBNEB51S
                                                  Type: RadixExpansion 35
(7) -> f(1.4,35,10)
   (7)  1.DYYYYYYYYY
                                                  Type: RadixExpansion 35
(8) -> f(%pi,3,8)
   (8)  10.01021101
                                                   Type: RadixExpansion 3
(9) -> f(%pi,5,10)
   (9)  3.032322143
                                                   Type: RadixExpansion 5
(10) -> f(1.234,16,12)
   (10)  1.3BE76C8B4395
                                                  Type: RadixExpansion 16

Nó có một vấn đề nhỏ cho ví dụ không cuối cùng

 f(4.5,10,5)

Sẽ trả về '4,5' chứ không phải '4,50000'

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.