การแปลงฐานจริง


19

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

ความท้าทาย

ปัจจัยการผลิต:

  • จำนวน จริงบวกxแสดงในฐาน 10 ซึ่งสามารถนำมาเป็นทศนิยมความแม่นยำสองเท่าหรือเป็นสตริง เพื่อหลีกเลี่ยงปัญหาความแม่นยำจำนวนที่สามารถสันนิษฐานว่าจะเป็นมากกว่า 10 -6และน้อยกว่า 10 15
  • ฐานเป้าหมาย นี่จะเป็นจำนวนเต็มตั้งแต่ 2 ถึง 36
  • จำนวนเศษส่วนตัวเลข n นี่จะเป็นจำนวนเต็มตั้งแต่ 1 ถึง 20

เอาท์พุท: การเป็นตัวแทนของxในฐานกับตัวเลขเศษส่วนn

เมื่อคำนวณนิพจน์ผลลัพธ์ตัวเลขที่เกินn- th ควรถูกปัดเศษ (ไม่ปัดเศษ) ตัวอย่างเช่นx = 3.141592653589793ในฐานb = 3คือ10.0102110122...ดังนั้นสำหรับn = 3ผลลัพธ์จะเป็น10.010(ตัด) ไม่ใช่10.011(ปัดเศษ)

สำหรับxและbที่สร้างจำนวน จำกัด ของตัวเลขในส่วนที่เป็นเศษส่วนอนุญาตให้ใช้การแทนค่าอนันต์ที่เทียบเท่ากัน (ตัดให้เหลือnหลัก) ยกตัวอย่างเช่นในทศนิยมนอกจากนี้ยังสามารถแสดงเป็น4.54.49999...

ไม่ต้องกังวลเกี่ยวกับข้อผิดพลาดจุดลอย

รูปแบบอินพุตและเอาต์พุต

xจะได้รับโดยไม่มีศูนย์นำหน้า หากxเกิดขึ้นเป็นจำนวนเต็มคุณสามารถสันนิษฐานได้ว่าจะได้รับส่วนทศนิยมศูนย์ ( 3.0) หรือไม่มีส่วนทศนิยม ( 3)

ผลผลิตมีความยืดหยุ่น ตัวอย่างเช่นมันอาจเป็น:

  • สตริงที่แทนตัวเลขด้วยตัวคั่นที่เหมาะสม (จุดทศนิยม) ระหว่างจำนวนเต็มและเศษส่วน ตัวเลข11, 12ฯลฯ (สำหรับเกิน 10) สามารถแสดงเป็นตัวอักษรA, Bตามปกติหรือเป็นตัวละครที่แตกต่างอื่น ๆ (โปรดระบุ)
  • สตริงสำหรับส่วนจำนวนเต็มและสตริงอื่นสำหรับส่วนที่เป็นเศษส่วน
  • สองอาร์เรย์ / รายการหนึ่งสำหรับแต่ละส่วนที่มีตัวเลขจาก0การ35เป็นหลัก

ข้อ จำกัด เพียงอย่างเดียวคือชิ้นส่วนจำนวนเต็มและเศษส่วนสามารถแยกออกจากกันได้ (ตัวคั่นที่เหมาะสม) และใช้รูปแบบเดียวกัน (ตัวอย่างเช่นไม่มี[5, 11]รายการที่แสดงถึงส่วนจำนวนเต็มและ['5', 'B']รายการแทนส่วนที่เป็นเศษส่วน)

กฎเพิ่มเติม

กรณีทดสอบ

เอาท์พุทจะแสดงเป็นสตริงด้วยตัวเลข0, ... , 9, A, ... , Zใช้.เป็นตัวคั่นทศนิยม

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

ขอให้เรายังคงอภิปรายนี้ในการแชท
Erik the Outgolfer

สำหรับ42, 13, 1เราสามารถมี33แทน33.0?
LiefdeWen

@LiefdeWen ไม่ส่วนที่สำคัญของความท้าทายคือผลลัพธ์จะต้องมีnตัวเลขทศนิยม
Luis Mendo

คำตอบ:


1

เยลลี่ขนาด 16 ไบต์

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

ลองออนไลน์!

โปรดทราบว่าพิมพ์ครั้งเดียวเป็นองค์ประกอบในการส่งออก


เฮ้เกิดอะไรขึ้นกับรูปภาพของคุณ
Luis Mendo เมื่อ

@LuisMendo บางคนไม่สามารถแสดงผลได้เนื่องจากมันเชื่อมต่อกับ Facebook
Leaky Nun

คุณรู้หรือไม่ว่าคุณสามารถอัพโหลดรูปภาพได้ที่นี่ ค่าเริ่มต้นเหล่านั้นไม่มีตัวตนมาก
Luis Mendo

7

JavaScript (ES8), 81 74 71 ไบต์

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>

การทำงานสำหรับxระหว่าง1e-6และ1e21, bจาก2ไป36(ตรงตามที่จำเป็น) และnจาก1การอะไรจาก10การ48ขึ้นอยู่กับฐานก่อนที่ข้อผิดพลาดจุดลอยตัวคืบคลานเข้ามาแก้ไข:. ที่บันทึกไว้ 7 ไบต์ด้วยความช่วยเหลือจาก @Birjolaxew บันทึกอีก 3 ไบต์ด้วยความช่วยเหลือจาก @tsh เวอร์ชัน 74- ไบต์ก่อนหน้านี้ยังทำงานกับตัวเลขลบ:

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
การแปลงฐานกับ regex มีวิธีการอย่างไร?!
Erik the Outgolfer

@EriktheOutgolfer ฉันไม่ได้เป็นเพียงนักกอล์ฟ (หวังว่า) วิธีการแยกn"ตัวเลข" ออกจากสตริง
Neil

แล้วสิ่งที่เป็นตรรกะหลักของฟังก์ชั่นของคุณหรือไม่
Erik the Outgolfer

@EriktheOutgolfer ทำไมฟังก์ชั่นการแปลงฐานในตัวของ JavaScript แน่นอน (คำแนะนำ: ดูที่ฉันใช้พารามิเตอร์ฐาน)
Neil

โอ้มันบอกว่า.toString(b)... ทำให้ฉันโง่> _ <
เอริคผู้เล่นนอกรีต

5

Python 2 , 153 149 144 137 135 109 ไบต์

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

ไม่ได้สังเกตว่าฉันสามารถส่งกลับตัวเลขเป็นตัวเลขได้เพื่อให้ง่ายขึ้นมาก ส่งคืนรายการตัวเลขสองรายการก่อนอื่นสำหรับส่วนจำนวนเต็มอันดับที่สองสำหรับเศษส่วน

ลองออนไลน์!


ในกรณีที่มันช่วย: ฉันได้เพิ่มบันทึกย่อที่คุณจะต้องสนับสนุนตัวเลขที่มากกว่า1e-6(และน้อยกว่า1e15ก่อนหน้านี้)
Luis Mendo

5

Perl 6 , 25 ไบต์

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

ลองมัน

ขยาย:

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

โปรดทราบว่าพื้นที่ที่เป็นเพื่อที่จะแยกวิเคราะห์เป็นไม่ได้(+x).base(b,n)
+( x.base(b,n) )


ในกรณีที่มันช่วย: ฉันได้เพิ่มบันทึกย่อที่คุณจะต้องสนับสนุนตัวเลขที่มากกว่า1e-6(และน้อยกว่า1e15ก่อนหน้า)
Luis Mendo

3

Mathematica, 158 ไบต์

เนื่องจากความท้าทายนี้ได้รับคำตอบที่ดีมากใน mathematica โดย @KellyLowder ฉันพยายามที่จะสร้างผลลัพธ์ที่ตรงตามที่แสดงในกรณีทดสอบ

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


อินพุต

[12944892982609, 29, 9]

เอาท์พุต

PPCGROCKS.000000000


3

Rubyขนาด 45 ไบต์

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

ทำไม?

เนื่องจาก b ^ n ในฐาน b คือ 10 ^ n เราจึงคูณ x ด้วยตัวเลขนั้นแล้วเพิ่มจุดทศนิยมที่เป็นสมาชิก

ลองออนไลน์!


-1 ไบต์ + แก้ไขข้อผิดพลาดโดยแทนที่.roundด้วย.to_i; สิ่งนี้จะแก้ไขหลักสุดท้ายของเอาต์พุตสำหรับตัวเลขที่ไม่ตรงกับเอาต์พุตทดสอบ -1 ไบต์เพิ่มเติมโดยใช้.insert ~n,?.โดยไม่มีวงเล็บ
Nnnes

3

C (gcc) ,157 152 ไบต์

ต้องการ 64 บิตlong intเพื่อให้การทำงานกับกรณีทดสอบที่ใหญ่ขึ้น

-5 ไบต์ขอบคุณ 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;}}

ลองออนไลน์!

แก้ไข: สองสามไบต์สามารถโกนถ้ามันได้รับอนุญาตให้ส่งออกสองสายคั่นด้วยตัวคั่นบรรทัดใหม่:

149 ไบต์:

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

แก้ไข: การส่งนี้ไม่ได้ยาวที่สุดใช่!


2
คุณสามารถใช้printf(z+r)หากไม่มี%อักขระใด ๆ (นี่คือรหัสกอล์ฟความปลอดภัยและแนวปฏิบัติที่ดีออกไปนอกหน้าต่าง: P) คุณสามารถใช้puts(z+r)เพื่อรับบรรทัดใหม่ฟรี (บันทึกputs("")ในรุ่นที่สอง)
ปีเตอร์กอร์เดส

ขอบคุณ! ฉันลืมเกี่ยวกับการให้ถ่าน * โดยตรงเป็นรูปแบบซึ่งจะช่วยประหยัดไม่กี่ไบต์ :-) ฉันไม่สามารถใช้ put (z + r) ในรุ่นที่สองเนื่องจากนั่นหมายความว่าทศนิยมแต่ละอันจะถูกพิมพ์ในบรรทัดใหม่
scottinet

อ่าส่วนสุดท้ายนั้นไม่ชัดเจนหากไม่มีเวอร์ชันที่ไม่ได้แสดงความคิดเห็น
Peter Cordes

floatสั้นกว่าdoubleแต่ดูเหมือนคำถามที่ต้องการdoubleอินพุตหรือสตริง
Peter Cordes

1
ไม่จำเป็นสำหรับสิ่งนั้น การใช้งานทั่วไปของ C มี 64 บิตlongและตามกฎของ code-golf นั่นคือทั้งหมดที่คุณต้องการเพื่อให้คำตอบของคุณถูกต้อง (นอกจากนี้ยังเป็นเรื่องปกติสำหรับคำตอบรหัส C-C ++ สำหรับกอล์ฟสมมติว่า 64 บิตlongเนื่องจากเป็นสิ่งที่ Try It Online ใช้) ฉันขอแนะนำให้ย้อนกลับการแก้ไขของคุณและเพียงเพิ่มหมายเหตุเช่น " longต้องเป็น 64 บิตสำหรับ เพื่อรองรับกรณีทดสอบขนาดใหญ่ "
Peter Cordes

2

Mathematica 47 Bytes

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

การเรียกRealDigitsสองครั้งถึงตัวเลขแรกจะคำนวณจำนวนหลักทางด้านซ้ายของทศนิยม


ในกรณีที่มันช่วย: ฉันได้เพิ่มบันทึกย่อที่คุณจะต้องสนับสนุนตัวเลขที่มากกว่า1e-6(และน้อยกว่า1e15ก่อนหน้า)
ลูอิสเมนโด

1
ฉันคิดว่าคำถามกำลังขอให้TakeDrop@@RealDigits[##]& แต่จากนั้นฉันก็รู้ว่าฉันมีสิ่งผิดพลาด - วิธีการแก้ปัญหาของคุณดูดีที่สุด
มาร์คเอส.


1

Haskell , 188 ไบต์

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]))

ลองออนไลน์!

g แปลงตัวเลขเป็นรายการที่แสดงถึงตัวเลขนั้นในฐานที่กำหนด

zแม็พจำนวนเต็มกับตัวอักษร ( 36 = .)

h ใช้ฟังก์ชันก่อนหน้านี้กับส่วนจำนวนเต็มและเศษส่วนของตัวเลข


1

ความจริง 566 ไบต์

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

มันยากโดยเฉพาะคำถามนี้; หลังจากใช้เวลาเขียนบางอย่างผลลัพธ์ที่ถูกต้องที่ดูเหมือนว่าสร้างโดยใช้มาโครหนึ่งตัวเพื่อสงวนตัวเลข () ... ผลลัพธ์ไม่ได้กอล์ฟมากเกินไป ... ผลลัพธ์:

(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

เป้าหมายที่แท้จริงคือฟังก์ชั่นหนึ่งที่แปลงเป็นฐาน 2..36 แต่ละโฟลต [ที่มี k: = ดิจิต ()] หรือแต่ละจำนวนที่คำนวณได้เป็น% pi หรือ% e หรือการหารของสองโฟลต / int เหมือนใน 1./3 . [ตัวเลข 'oo']

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

1

ความจริง 127 ไบต์

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)

ผล

(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

มันมีปัญหาเล็กน้อยสำหรับตัวอย่างสุดท้าย

 f(4.5,10,5)

จะส่งคืน '4.5' และไม่ใช่ '4.50000'

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