Konwertuj ułamek zwykły na dziesiętny


17

Prawie przeciwne biegunowo, jeśli to wyzwanie, i podejrzewam, że będzie nieco łatwiej.

Twoim zadaniem jest pobranie dwóch liczb całkowitych w formacie a/b(tworzenie liczby wymiernej), a następnie wypisanie dokładnie liczby dziesiętnej.

Na przykład, gdybyś wprowadził dane 1/3wyjściowe:

0.33333333333333333

I drukowałby 3 s do końca czasu, z opcjonalnym początkowym 0. (Możesz także wydrukować jeden znak w wierszu, jeśli i tylko wtedy, gdy twój język nie pozwala na drukowanie w tym samym wierszu).

Zachowanie dla x/0będzie niezdefiniowane. Dla liczby, która wygląda na to, że się nie powtarza (powiedzmy, powiedzmy, 5/4że tak się dzieje), to się powtarza. Każda z dwóch poniższych form byłaby akceptowalna dla 5/4:

1.25000000000000000
1.24999999999999999

(To samo z liczbami całkowitymi 1.9999999lub 2.000000)

Frakcja nie może być w swojej najprostszej formie, a aczy bmoże być ujemna (Uwaga -a/b = -(a/b), -a/-b = a/b, a/-b = -a/b, i -.6249999to nieważne, ale -0.6249999jest do przyjęcia, ale nadal można korzystać.


Czy możemy używać Uniksa bc, czy to oszustwo?
David R Tribble

Zanim zacznę grać w golfa, moja odpowiedź: czy ai / lub może bbyć negatywna?
Dennis

@Dennis Tak, ale jeden alub b(lub oba) mogą być negatywne)

@DavidRTribble Myślę, że to standardowa luka, więc nie.

Czy Twoja ostatnia edycja mówi, że zera na początku są poprawne z liczbami dodatnimi, ale nie zerowymi? Jeśli tak, jaki jest tego powód?
Geobity

Odpowiedzi:


2

CJam, 38 37 bajtów

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

Jak to działa

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)

Ponieważ używasz podwójnego podziału, czy nie jest to całkowicie podzielone dla dużych liczb?
lub

@orlp: Całkowicie. Teraz jest naprawione.
Dennis

6

C 108 79

Edytuj Zmodyfikowany, aby działał z liczbami ujemnymi.

Dane wejściowe ze standardowego wejścia. Stary styl 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

Rubin, 83 69 102 91 89 bajtów

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

Prosta implementacja ręcznego podziału liczb całkowitych na podstawie podziału liczb całkowitych komputera.

Dzięki @blutorange za pomoc w grze w golfa.

Edycja: Naprawiono rozwiązanie uwzględniające liczby ujemne.


2
Używając niektórych skrótów w rubinie, możesz sprowadzić to do 66 bajtów: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Po prostu uwielbiam to w ruby.
blutorange

Wow, właśnie nauczyłem się wielu rzeczy, dziękuję! Nie pamiętam, ?/aby oznaczać znaki, ani nie wiedziałem o $><<drukowaniu ani o loopsłowach kluczowych. Wielkie dzięki!!
rorlork

1
Proszę bardzo, nie wiedziałem też o wielu z tych sztuczek, dopóki ktoś tego nie zauważył. $>jest skrótem od $stdouti <<jest operatorem. Możesz zapisać jeszcze jeden bajt w drugiej linii, zmieniając go na c*d<0&&$><<?-; kilka bajtów przez połączenie trzeciej / czwartej linii z $><<a/b<<?.i jeszcze jeden przez usunięcie spacji po <<w ostatniej linii. A oto pomysł sprowadzenia go do 91 bajtów: ->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

Składnia for $><<a/bnie działała poprawnie, dlatego umieściłem tam miejsce. Reszta wydaje się dobra, dziękuję bardzo!
rorlork

1
Jeśli nadal jesteś zainteresowany, istnieje również racjonalna literał ( Rational(2,3) == 2/3r) od Ruby 2.1 (którego nauczyłem się około 10 minut temu), którego można użyć do skrócenia drugiej linii:eval(s+?r)<0&&$><<?-
blutorange

2

Java, 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){}}

Algorytm jest prosty; trudną częścią było uruchomienie drukowania. W końcu miałem sen z komputera na sekundę między każdym krokiem, aby mógł drukować.

Rozszerzona wersja do uruchomienia

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

Podczas gdy wyjście ma problem z płukaniem, udało mi się sprawić, aby wyświetlało wyjście przez uśpienie przez 9 ms, co goli dwa bajty.

@ Snowman To prawdopodobnie zależy od sprzętu lub systemu operacyjnego; mój komputer nie będzie działał krócej niż 250 ms.
Ypnypn

2

R, 103 137 109 103

Trochę szczęśliwsi z tym teraz. Używając skanowania z separatorem oszczędzasz dużo bajtów. Może jeszcze mieć miejsce na ulepszenia. Zastąpione <-z =. Nie zawsze miałem z tym szczęście, ale tym razem się udało.

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

Przebiegi testowe

> 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 bajtów

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

Całkiem proste:

  • Wprowadź licznik i mianownik
  • Podaj iloraz z 1 cyfrą po przecinku, a następnie zdejmij ostatnią cyfrę (np. -1/3-> -0.)
  • Weź wartości bezwzględne *
  • Pętla:
    • Licznik jest resztą po podzieleniu mianownika
    • Pomnóż licznik przez 10
    • Wyjściowy iloraz liczby całkowitej jako następnej cyfry

* (Chociaż obliczenia azostały przeniesione do pętli, aby zaoszczędzić kilka bajtów.)

Edycja: Naprawiono błąd z ujemnymi ułamkami> -1.


0

Python 2.7, 209 bajtów

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

edytować:

Teraz wypisuje wszystkie znaki w tym samym wierszu, zgodnie z zapytaniem.

edycja2:

Teraz odczytuje ułamek argumentu wiersza poleceń, zgodnie z żądaniem :)


1
Kilka wskazówek: 1) Używanie mapzamiast listowego zrozumienia znacznie oszczędza; 2) nie są potrzebne w nawiasach m*aw każdym ze swoich miejsc, jak *, %i /są tym samym priorytecie i lewostronna; 3) Można uprościć logikę 0 lub kropki w linii 3 "0."[m==1], ponieważ i tak ją drukujesz; 4) prawdopodobnie zapisze znaki, aby po prostu ustawić o=stdout.writei przekonwertować argumenty liczbowe na ciąg znaków z backticks w razie potrzeby.
DLosc

1
Ponadto kod nie działa z negatywami: 1/-3daje -1.666666666zamiast -0.333333333.
DLosc
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.