Konvertieren Sie einen Bruch in eine wiederholte Dezimalzahl

17

Fast das Gegenteil, wenn diese Herausforderung, und ich vermute, es wird etwas einfacher sein.

Ihre Aufgabe ist es, zwei Ganzzahlen im Format a/b(Bildung einer rationalen Zahl) zu nehmen und die Zahl dann genau dezimal auszugeben.

Wenn Sie beispielsweise eingeben 1/3, wird Folgendes ausgegeben:

0.33333333333333333

Und würde 3s bis zum Ende der Zeit mit einer optionalen führenden 0 drucken. (Sie können auch ein Zeichen pro Zeile drucken, wenn Ihre Sprache nicht das Drucken in derselben Zeile zulässt.)

Das Verhalten für x/0wird undefiniert sein. Für eine Zahl, die so aussieht, als würde sie sich nicht wiederholen (etwa 5/4), wird sie tatsächlich wiederholt. Eine der beiden folgenden Formen wäre akzeptabel für 5/4:

1.25000000000000000
1.24999999999999999

(Dasselbe mit ganzen Zahlen 1.9999999oder 2.000000)

Die Fraktion kann nicht in seiner einfachsten Form sein, und aoder bkann negativ sein (Hinweis -a/b = -(a/b), -a/-b = a/b, a/-b = -a/b, und -.6249999ist ungültig, aber -0.6249999akzeptabel ist , aber man kann immer noch verwenden.

Gemeinschaft
quelle
Können wir Unix verwenden bc, oder ist das Betrug?
David R Tribble
Bevor ich weiter Golf spiele, meine Antwort: Kann aund / oder bnegativ sein?
Dennis
@ Tennis Ja, aber entweder aoder b(oder beide) können negativ sein)
@DavidRTribble Ich denke, das ist eine Standardlücke, also nein.
Sagt Ihre letzte Änderung, dass führende Nullen bei positiven Zahlen in Ordnung sind, aber nicht bei negativen? Wenn ja, woran liegt das?
Geobits

Antworten:

2

CJam, 38 37 Bytes

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

Wie es funktioniert

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)
Dennis
quelle
Da Sie die doppelte Teilung verwenden, ist das nicht für große Zahlen völlig kaputt?
Orlp
@orlp: Völlig. Es ist jetzt behoben.
Dennis
6

C 108, 79

Bearbeiten Geändert, um mit negativen Zahlen zu arbeiten.

Eingabe von stdin. Alter K & R-Stil.

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;}
edc65
quelle
4

Ruby, 83 69 102 91 89 Bytes

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

Einfache Implementierung einer manuellen Ganzzahldivision basierend auf der Ganzzahldivision des Computers.

Vielen Dank an @blutorange für die Hilfe beim Golfen.

Bearbeiten: Die Lösung für negative Zahlen wurde korrigiert.

rorlork
quelle
2
Wenn Sie einige Ruby-Shortcuts verwenden, können Sie dies auf 66 Bytes reduzieren: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Ich mag Ruby einfach.
blutorange
Wow, ich habe gerade viele Dinge gelernt, danke! Ich erinnerte mich nicht daran ?/, Zeichen zu bezeichnen, und wusste auch nicht , wie ich $><<drucken sollte oder welches loopSchlüsselwort ich verwenden sollte . Danke vielmals!!
rorlork
1
Gern geschehen, ich wusste auch nicht viel über diese Tricks, bis jemand darauf hingewiesen hat. $>ist eine Abkürzung für $stdoutund <<ist ein Operator. Sie können ein weiteres Byte in der zweiten Zeile speichern, indem Sie es in ändern c*d<0&&$><<?-. ein paar Bytes durch Kombinieren der 3./4. Zeile mit $><<a/b<<?.und eines durch Entfernen des Leerzeichens nach <<in der letzten Zeile. Und hier ist eine Idee, um es auf 91 Bytes zu reduzieren: ->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
Die Syntax für $><<a/bhat nicht richtig funktioniert, deshalb habe ich das Leerzeichen dort platziert. Der Rest scheint gut zu sein, vielen Dank!
Lorlork
1
Wenn Sie immer noch interessiert sind, gibt es seit Ruby 2.1 (das ich vor ungefähr 10 Minuten gelernt habe) auch ein rationales Literal ( Rational(2,3) == 2/3r), das verwendet werden kann, um die zweite Zeile zu verkürzen: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){}}

Der Algorithmus ist einfach; Der schwierige Teil war, den Druck zum Laufen zu bringen. Am Ende hatte ich den Computer für eine Sekunde zwischen jedem Schritt, damit er drucken konnte.

Erweiterte, lauffähige Version

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");
    }
}
Ypnypn
quelle
Während die Ausgabe ein Flush-Problem hat, war ich in der Lage, die Ausgabe anzuzeigen, indem ich für 9 ms geschlafen habe, was zwei Bytes rasieren würde.
@Snowman Das hängt wahrscheinlich von der Hardware oder dem Betriebssystem ab. Mein Computer funktioniert nicht mit weniger als 250 ms oder so.
Ypnypn
2

R 103 137 109 103

Etwas glücklicher jetzt damit. Durch die Verwendung von Scan mit einem Trennzeichen werden viele Bytes gespart. Möglicherweise gibt es noch Verbesserungspotenzial. Ersetzt <-durch =. Ich hatte nicht immer viel Glück damit, aber diesmal hat es funktioniert.

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

Testläufe

> 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...
MickyT
quelle
1

Python 3, 107 115 Bytes

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

Ziemlich einfach:

  • Geben Sie den Zähler und Nenner ein
  • Den Quotienten mit 1 Stelle nach dem Komma ausgeben, dann die letzte Stelle abziehen (zB -1/3-> -0.)
  • Absolute Werte nehmen *
  • Schleife:
    • Zähler ist Rest nach Nenneraufteilung
    • Zähler mit 10 multiplizieren
    • Ganzzahliger Quotient als nächste Ziffer ausgeben

* (Obwohl die Berechnung für ainnerhalb der Schleife verschoben wurde, um ein paar Bytes zu sparen.)

Bearbeiten: Fehler mit negativen Brüchen> -1 behoben.

DLosc
quelle
0

Python 2.7, 209 Bytes

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

bearbeiten:

Jetzt werden alle Zeichen in derselben Zeile ausgegeben, wie angefordert.

edit2:

Liest nun den Bruch aus dem Kommandozeilenargument, wie gewünscht :)

Dieter
quelle
1
Ein paar Tipps: 1) Verwenden mapanstelle des Listenverständnisses spart einiges; 2) nicht brauchen die Klammern um m*ain allen seinen Standorten, wie *, %und /sind alle gleich Vorrang und linksassoziativ; 3) Die 0-Punkt-Logik in Zeile 3 kann vereinfacht werden "0."[m==1], da Sie sie ohnehin nur drucken. 4) Spart wahrscheinlich Zeichen, um numerische Argumente mit Backticks nach Bedarf zu setzen o=stdout.writeund in Zeichenketten umzuwandeln .
DLosc
1
Außerdem scheint der Code nicht mit Negativen zu funktionieren: 1/-3gibt -1.666666666statt -0.333333333.
DLosc