Реальне базове перетворення


19

У нас було кілька викликів щодо перетворення базових даних, але всі вони, здається, стосуються цілих значень. Давайте зробимо це з реальними цифрами!

Змагання

Вхідні дані:

  • Дійсне додатне число x , виражене в базі 10. Це може сприйматися як поплавок подвійної точності або як струна. Щоб уникнути проблем з точністю, їх число можна вважати більшим за 10 −6 та менше 10 15 .
  • Цільові базові б . Це буде ціле число від 2 до 36.
  • Ряд дробових цифр n . Це буде ціле число від 1 до 20.

Вихід: уявлення про х в базовій Ь з п дрібних цифр.

Обчислюючи вихідний вираз, цифри за межами n- ї повинні бути усічені (не округлені). Наприклад, x = 3.141592653589793в базі b = 3є 10.0102110122..., тому для n = 3виходу буде 10.010(усічення), а не 10.011(округлення).

Для x і b, які дають кінцеву кількість цифр у дробовій частині, також допускається еквівалентне нескінченне подання (усічене до n цифр). Наприклад, 4.5у десятковій формі також можна представити як 4.49999....

Не хвилюйтеся з приводу помилок з плаваючою комою .

Формат вводу та виводу

x буде задано без провідних нулів. Якщо x має бути цілим числом, ви можете припустити, що воно буде задано з нульовою десятковою частиною ( 3.0) або без десяткової частини ( 3).

Вихід є гнучким. Наприклад, це може бути:

  • Рядок, що представляє число з відповідним роздільником (десятковою точкою) між цілою та дробовою частинами. Digits 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


бо 42, 13, 1ми можемо мати 33замість 33.0?
LiefdeWen

@LiefdeWen Ні, суттєвою складовою завдання є те, що вихід повинен мати nдесяткові цифри
Луїс Мендо

Відповіді:


1

Желе , 16 байт

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

Спробуйте в Інтернеті!

Зауважте, що одиночні кнопки друкуються як елемент у висновку.


Гей, що сталося з твоєю картиною?
Луїс Мендо

@LuisMendo деякі люди не можуть це зробити, оскільки він був підключений до Facebook
Leaky Nun

Ви знаєте, що можете завантажити сюди картинку, правда? Ті за замовчуванням настільки безособові
Луїс Мендо

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залежності від підстави до плаваючою точки помилок повзати в Edit :. Збережені 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
Як можна перетворити базу за допомогою регулярного вираження?!?
Erik the Outgolfer

@EriktheOutgolfer Я ні, це просто гольфіст (сподіваємось) спосіб вилучення до n"цифр" з рядка.
Ніл

Тоді що є основною логікою вашої функції?
Erik the Outgolfer

@EriktheOutgolfer Чому, звичайно, вбудована функція перетворення JavaScript в JavaScript. (Підказка: подивіться, де я використовую базовий параметр.)
Ніл

О, це каже .toString(b)... німий мене> _ <
Ерік Позашляховик

5

Пітон 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, як раніше)
Луїс Мендо

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, як раніше)
Луїс Мендо

3

Математика, 158 байт

оскільки цей виклик уже отримав дуже приємну відповідь з математики від @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

Рубін , 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 байти

long intДля роботи з більшими тестовими кейсами потрібно 64 біти .

-5 байт завдяки Пітеру Кордесу

#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("")у другій версії).
Пітер Кордес

Спасибі! Я забув про надання символу * безпосередньо як візерунок, це дійсно економить досить багато байтів :-) Я не можу використовувати введення (z + r) у другій версії, оскільки це означатиме, що кожен десятковий знак буде надрукований у
новому рядку

А, ця остання частина не була очевидною без неперевершеної версії з коментарями.
Пітер Кордес

floatкоротше double, але, мабуть, питання вимагає введення doubleабо рядка
Пітер Кордес

1
Не потрібно в цьому. У деяких поширених реалізаціях C є 64-розрядні long, і згідно з правилами коду-гольфу, це все, що потрібно, щоб відповідь була достовірною. (Крім того, для C і C ++ код-гольф відповідей прийнято вважати 64-розрядною long, оскільки саме це і застосовується Try It Online.) Я б запропонував скасувати свою редагування, і просто додавання примітки типу " longповинно бути 64-бітним для це для підтримки великих тестових випадків ".
Пітер Кордес

2

Математика 47 байт

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 кожного Float [, що має k: = цифри ()] або кожне обчислене число як% pi або% e або ділення двох float / 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"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.