Converti una frazione in un decimale ripetuto


17

Quasi l'opposto polare se questa sfida, e sospetto che sarà leggermente più facile.

Il tuo compito è quello di prendere due numeri interi nel formato a/b(Formare un numero razionale), quindi produrre esattamente il numero in decimale.

Ad esempio, se dovessi inserire 1/3, produrrebbe:

0.33333333333333333

E continuerebbe a stampare 3 secondi fino alla fine dei tempi, con uno 0 iniziale facoltativo (puoi anche stampare un carattere per riga se e solo se la tua lingua non consente la stampa sulla stessa riga.)

Il comportamento per x/0sarà indefinito. Per un numero che sembra che non si ripeta (come, diciamo 5/4) in realtà si ripete. Una delle due seguenti forme sarebbe accettabile per 5/4:

1.25000000000000000
1.24999999999999999

(Lo stesso con numeri interi 1.9999999o 2.000000)

La frazione non può essere nella sua forma più semplice, e ao bpuò essere negativo (Nota -a/b = -(a/b), -a/-b = a/b, a/-b = -a/b, e -.6249999non è valido, ma -0.6249999è accettabile, ma è ancora in grado di utilizzare.


Possiamo usare Unix bco è barare?
David R Tribble

Prima di continuare a giocare a golf la mia risposta: può ae / o bessere negativo?
Dennis,

@Dennis Sì, ma uno ao entrambi b(o entrambi) possono essere negativi)

@DavidRTribble Penso che sia una scappatoia standard, quindi no.

La tua ultima modifica dice che gli zero iniziali vanno bene con numeri positivi, ma non negativi? In tal caso, qual è il motivo?
Geobits

Risposte:


2

CJam, 38 37 byte

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

Come funziona

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)

Dal momento che usi la doppia divisione non è completamente rotto per i grandi numeri?
orlp,

@orlp: totalmente. Ora è riparato.
Dennis,

6

C, 108 79

Modifica modificata per funzionare con numeri negativi.

Input da stdin. Vecchio stile 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

Rubino, 83 69 102 91 89 byte

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

Semplice implementazione della divisione intera manuale basata sulla divisione intera del computer.

Grazie a @blutorange per l'aiuto nel golf.

Modifica: corretta la soluzione per includere numeri negativi.


2
Facendo uso di alcune scorciatoie nel rubino, puoi ridurlo a 66 byte: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}adoro questo rubino.
Blutorange,

Wow, ho appena imparato molte cose, grazie! Non ricordavo ?/di indicare i caratteri, né sapevo $><<di stampare o la loopparola chiave. Molte grazie!!
rorlork,

1
Prego, non sapevo di molti di questi trucchi neanche fino a quando qualcuno non lo ha sottolineato. $>è l'abbreviazione di $stdouted <<è un operatore. È possibile salvare un altro byte nella seconda riga modificandolo in c*d<0&&$><<?-; pochi byte combinando la 3a / 4a riga in $><<a/b<<?.e un'altra rimuovendo lo spazio dopo <<nell'ultima riga. Ed ecco un'idea per portarlo a 91 byte: ->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

La sintassi per $><<a/bnon ha funzionato correttamente, ecco perché ho messo lo spazio lì. Il resto sembra buono, grazie mille!
rorlork,

1
Se sei ancora interessato, c'è anche un letterale razionale ( Rational(2,3) == 2/3r) dal ruby ​​2.1 (che ho imparato circa 10 minuti fa) che può essere usato per abbreviare la seconda riga: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){}}

L'algoritmo è semplice; la parte difficile era far funzionare la stampa. Alla fine, ho fatto dormire il computer per un secondo tra ogni passaggio in modo che potesse stampare.

Versione espandibile e eseguibile

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

Mentre l'output ha un problema di flushing, sono stato in grado di farlo mostrare dormendo per 9ms che avrebbe raduto due byte.

@Snowman Probabilmente dipende dall'hardware o dal sistema operativo; il mio computer non funzionerà con meno di 250 ms o giù di lì.
Ypnypn,

2

R, 103 137 109 103

Un po 'più felice con questo ora. L'uso della scansione con un separatore consente di risparmiare molti byte. Potrebbe avere ancora margini di miglioramento. Sostituito <-con =. Non ho sempre avuto la fortuna di farlo, ma questa volta ha funzionato.

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

Esecuzioni di test

> 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 byte

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

Abbastanza diretto:

  • Immettere il numeratore e il denominatore
  • Emette il quoziente con 1 cifra dopo il punto decimale, quindi togli l'ultima cifra (es. -1/3-> -0.)
  • Prendi valori assoluti *
  • Ciclo continuo:
    • Il numeratore è il resto dopo aver diviso il denominatore
    • Moltiplicare il numeratore per 10
    • Quoziente intero di output come cifra successiva

* (Anche se il calcolo per è astato spostato all'interno del ciclo per salvare alcuni byte.)

Modifica: corretto bug con frazioni negative> -1.


0

Python 2.7, 209 byte

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

modificare:

Ora genera tutti i caratteri sulla stessa riga, come richiesto.

EDIT2:

Ora legge la frazione dall'argomento della riga di comando, come richiesto :)


1
Alcuni consigli: 1) L'uso al mapposto della comprensione dell'elenco consente di risparmiare parecchio; 2) non hanno bisogno le parentesi intorno m*ain una qualsiasi delle sue sedi, come *, %e /sono tutti la stessa priorità e di sinistra-associativa; 3) la logica a 0 o punto sulla riga 3 può essere semplificata "0."[m==1], dal momento che la stai stampando comunque; 4) probabilmente salverà i caratteri per impostare o=stdout.writee convertire semplicemente argomenti numerici in stringa con backtick secondo necessità.
DLosc,

1
Inoltre, il codice non sembra funzionare con i negativi: 1/-3-1.666666666invece di -0.333333333.
DLosc,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.