Перетворіть дріб у повторне десяткове


17

Майже полярна протилежність, якщо це виклик, і я підозрюю, що це буде трохи легше.

Ваше завдання - взяти два цілих числа у форматі a/b(Формування раціонального числа), а потім вивести це число точно в десятковій формі .

Наприклад, якби ви ввели 1/3, він виводить:

0.33333333333333333

І буде тримати друк 3s до кінця часу, з необов'язковим початковим числом 0. (Ви також можете надрукувати по одному символу на рядок, якщо і лише тоді, коли ваша мова не дозволяє друкувати на цьому ж рядку.)

Поведінка для x/0не буде визначеною. Для числа, яке виглядає так, що воно не повторюється (як, скажімо 5/4), воно насправді повторюється. Будь-яка з наступних двох форм була б прийнятною для 5/4:

1.25000000000000000
1.24999999999999999

(Те саме з цілими числами, 1.9999999або2.000000 )

Фракція не може бути в своїй простій формі, aабо bможе бути негативним (Примітка -a/b = -(a/b), -a/-b = a/b, a/-b = -a/bі -.6249999є недійсним, але -0.6249999прийнятно, але ви все ще можете використовувати.


Чи можемо ми використовувати Unix bc, чи це обман?
David R Tribble

Перш ніж продовжувати займатися гольфом, я можу відповісти: Чи можна aта / або bбути негативним?
Денніс

@Dennis Так, але aабо b(або обидва) можуть бути негативними)

@DavidRTribble Я думаю, що це стандартна лазівка, тому ні.

Чи свідчить ваша остання редакція, що нульові нулі добре з позитивними числами, але не з негативними? Якщо так, то в чому причина цього?
Геобіт

Відповіді:


2

CJam, 38 37 байт

l'/%:i2*~*0<'-*o:Dmd\zo'.{oA*Dmd\z1}g

Як це працює

l     e# Read line from STDIN.            STACK '17/-13'
'/%   e# Split at '/'.                    STACK ['17' '-13']
:i    e# Cast each element to int.        STACK [17 -13]
2*~   e# Duplicate and dump the array.    STACK 17 -13 17 -13
*     e# Multiply.                        STACK 17 -13 -221
0<    e# Compare with zero.               STACK 17 -13 1
'-*o  e# Print '-' that many times.       STACK 17 -13
:D    e# Save the topmost integer in D.   STACK 17 -13
md    e# Perform modular division.        STACK -1 4
\z    e# Swap and take absolute value.    STACK 4 1
o'.   e# Print and push '.'.              STACK 4 '.'
{     e# do:
  o   e#   Print.                         STACK 4
  A*  e#   Multiply by 10.                STACK 40
  Dmd e#   Divide modulo D.               STACK -3 1
  \z  e#   Swap and take absolute value.  STACK 1 3
  o   e#   Print.                         STACK 1
1}g   e# while(1)

Оскільки ви використовуєте подвійний поділ, чи не все це повністю порушено для великих чисел?
orlp

@orlp: Повністю. Це зараз виправлено.
Денніс

6

С, 108 79

Редагувати Змінено для роботи з від'ємними числами.

Введення від stdin. Старий стиль K&R

main(a,b){char*s="-%d.";scanf("%d/%d",&a,&b);for(a*b<0?(a<0?a=-a:(b=-b)):++s;printf(s,a/b);s="%d")a=a%b*10;}

4

Рубі, 83 69 102 91 89 байт

->s{a,b=s.scan(/\d+/).map &:to_i
eval(s+?r)<0&&$><<?-
$><<a/b<<?.
loop{a=a%b*10
$><<a/b}}

Проста реалізація ручного цілого поділу на основі цілочисельного поділу комп'ютера.

Дякуємо @blutorange за допомогу в гольфі.

Редагувати: виправлено рішення для включення від'ємних чисел.


2
Використовуючи деякі ярлики в рубіні, ви можете звести це до 66 байт: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Мені просто подобається цей рубін.
blutorange

Нічого собі, я просто дізнався багато речей, дякую! Я не пам’ятав про те, ?/щоб позначити символи, і не знав про $><<друк чи loopключове слово. Дуже дякую!!
rorlork

1
Запрошуємо вас, я не знав про багато цих хитрощів, поки хтось не зазначив цього. $>скорочено $stdout, і <<є оператором. Ви можете зберегти ще один байт у другому рядку, змінивши його на c*d<0&&$><<?-; кілька байтів, комбінуючи 3-й / 4-й рядок до $><<a/b<<?., і ще один, видаливши пробіл <<в останньому рядку. І ось ідея звести її до 91 байт: ->s{a,b=s.scan(/\d+/).map &:to_i;1==s.count(?-)&&$><<?-;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}(ruby 2.2.0)
blutorange

Синтаксис $><<a/bне працював правильно, тому я помістив простір туди. Решта здається гарною, дуже дякую!
rorlork

1
Якщо ви все ще зацікавлені, є також раціональний літерал ( Rational(2,3) == 2/3r) з моменту рубіну 2.1 (про який я дізнався 10 хвилин тому), який можна використати для скорочення другого рядка:eval(s+?r)<0&&$><<?-
blutorange

2

Ява, 177 176 170

s->{try{int x=new Integer(s.split("/")[0]),y=new Integer(s.split("/")[1]),z=1;for(;;x=x%y*10,Thread.sleep(999))System.out.print(x/y+(z-->0?".":""));}catch(Exception e){}}

Алгоритм прямий; складна частина полягала в тому, щоб друк працював. Зрештою, я заснув комп'ютер на секунду між кожним кроком, щоб він міг друкувати.

Розширена версія для запуску

public class RepeatedDecimal {
    public static void main(String[] args) {
        java.util.function.Consumer<String> f = s -> {
                try {
                    int x = new Integer(s.split("/")[0]),
                        y = new Integer(s.split("/")[1]),
                        z = 1;
                    for (;; x = x % y * 10, Thread.sleep(999)) {
                        System.out.print(x / y + (z-- > 0 ? "." : ""));
                    }
                } catch (Exception e) { }
                };

        f.accept("5/7");
    }
}

У той час як у виході є проблема змивання, я зміг змусити його показувати вихід, сплячи 9 мс, який би поголив два байти.

@Snowman Це, мабуть, залежить від обладнання або ОС; мій комп'ютер не працюватиме менше, ніж за 250 мс.
Ypnypn

2

R, 103 137 109 103

Трохи щасливіше з цим зараз. Використовуючи сканування з роздільником, економте багато байтів. Можливо, ще є можливість покращитись. Замінено <-на =. Не завжди пощастило з цим, але це спрацювало цього разу.

cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)

Тестові пробіжки

> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -1/3
3: 
Read 2 items
-0.33333333333333333333...
> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -5/-4
3: 
Read 2 items
1.250000000000000000000...

1

Python 3, 107 115 байт

a,b=map(int,input().split("/"))
print(("%.1f"%(a/b))[:-1],end="")
b=abs(b)
while 1:a=abs(a)%b*10;print(a//b,end="")

Досить прямо:

  • Введіть чисельник та знаменник
  • Виведіть коефіцієнт 1 цифрою після десяткової крапки, а потім зніміть останню цифру (наприклад -1/3-> -0.)
  • Прийміть абсолютні значення *
  • Петля:
    • Чисельник залишається після поділу знаменника
    • Помножте чисельник на 10
    • Вивести цілочисельний коефіцієнт як наступну цифру

* (Хоча обчислення для aпереміщено всередині циклу, щоб зберегти кілька байт.)

Редагувати: виправлена ​​помилка з негативними частками> -1.


0

Python 2.7, 209 байт

from sys import*;m,o=1,lambda x:stdout.write(str(x));a,b=[int(x)for x in argv[1].split('/')]
o(str(a*b)[0]);a,b=abs(a),abs(b);o('0'*(b>a))
while 1:
 while not((m*a)/b):o('0.'[m==1]);m*=10
 o((m*a)/b);a=(m*a)%b

редагувати:

Тепер виводить усі символи в одному рядку, як і запитували.

edit2:

Тепер читає дріб з аргументу командного рядка, як вимагається :)


1
Кілька порад: 1) використання mapзамість розуміння списку економить досить багато; 2) не потрібні круглі дужки m*aв будь-якому зі своїх місць, так як *, %і/ все ж пріоритет і левоассоціатівние; 3) логіку 0 або крапки в рядку 3 можна спростити "0."[m==1], оскільки ви все одно просто друкуєте її; 4) напевно збереже символи просто встановити o=stdout.writeта перетворити числові аргументи в рядок із зворотними посиланнями, якщо це потрібно.
DLosc

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