Convertir une fraction en une décimale répétée


17

Presque l'opposé polaire si ce défi, et je pense que ce sera un peu plus facile.

Votre tâche consiste à prendre deux entiers au format a/b(Formation d'un nombre rationnel) puis à sortir le nombre en décimal exactement.

Par exemple, si vous deviez entrer 1/3, cela produirait:

0.33333333333333333

Et continuerait à imprimer des 3 jusqu'à la fin des temps, avec un 0 en tête facultatif. (Vous pouvez également imprimer un caractère par ligne si et seulement si votre langue ne permet pas d'imprimer sur la même ligne.)

Le comportement de x/0sera indéfini. Pour un nombre qui semble ne pas se répéter (comme, disons 5/4), il se répète. L'un ou l'autre des deux formulaires suivants serait acceptable pour 5/4:

1.25000000000000000
1.24999999999999999

(La même chose avec des nombres entiers, 1.9999999ou 2.000000)

La fraction peut ne pas être dans sa forme la plus simple, et aou bpeut être négatif (Note -a/b = -(a/b), -a/-b = a/b, a/-b = -a/bet -.6249999est invalide, mais -0.6249999est acceptable, mais vous pouvez toujours utiliser.


Pouvons-nous utiliser Unix bc, ou est-ce de la triche?
David R Tribble

Avant de continuer à jouer au golf, ma réponse: peut aet / ou bêtre négative?
Dennis

@Dennis Oui, mais l'un aou l' autre b(ou les deux) peuvent être négatifs)

@DavidRTribble Je pense que c'est une faille standard, donc non.

Votre dernier montage indique-t-il que les zéros non significatifs acceptent les nombres positifs, mais pas les négatifs? Si oui, quelle en est la raison?
Geobits

Réponses:


2

CJam, 38 37 octets

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

Comment ça fonctionne

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)

Puisque vous utilisez la double division, n'est-ce pas totalement cassé pour les grands nombres?
orlp

@orlp: Totalement. C'est réparé maintenant.
Dennis

6

C, 108 79

Modifier modifié pour fonctionner avec des nombres négatifs.

Entrée de stdin. Ancien style 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

Ruby, 83 69 102 91 89 octets

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

Implémentation simple de la division entière manuelle basée sur la division entière de l'ordinateur.

Merci à @blutorange pour son aide au golf.

Modifier: correction de la solution pour inclure des nombres négatifs.


2
En utilisant certains raccourcis dans ruby, vous pouvez ramener cela à 66 octets: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}j'adore ça à propos de ruby.
blutorange

Wow, je viens d'apprendre beaucoup de choses, merci! Je ne me souvenais pas ?/de désigner des caractères, je ne savais pas non plus comment $><<imprimer ou le loopmot - clé. Merci beaucoup!!
rorlork

1
Vous êtes les bienvenus, je ne connaissais pas beaucoup de ces trucs non plus jusqu'à ce que quelqu'un le fasse remarquer. $>est l'abréviation de $stdout, et <<est un opérateur. Vous pouvez enregistrer un octet de plus dans la deuxième ligne en le remplaçant par c*d<0&&$><<?-; quelques octets en combinant la 3ème / 4ème ligne à $><<a/b<<?., et un de plus en supprimant l'espace après <<dans la dernière ligne. Et voici une idée pour le ramener à 91 octets: ->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 syntaxe de $><<a/b ne fonctionnait pas correctement, c'est pourquoi j'y ai mis de l'espace. Le reste semble bon, merci beaucoup!
rorlork

1
Si vous êtes toujours intéressé, il y a aussi un littéral rationnel ( Rational(2,3) == 2/3r) depuis ruby ​​2.1 (que j'ai appris il y a environ 10 minutes) qui peut être utilisé pour raccourcir la deuxième ligne: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'algorithme est simple; la partie délicate était de faire fonctionner l'impression. Au final, j'ai laissé l'ordinateur en veille une seconde entre chaque étape pour qu'il puisse imprimer.

Version étendue et exécutable

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

Bien que la sortie ait un problème de vidage, j'ai pu l'obtenir pour afficher la sortie en dormant pendant 9 ms, ce qui raserait deux octets.

@Snowman Cela dépend probablement du matériel ou du système d'exploitation; mon ordinateur ne fonctionnera pas avec moins de 250 ms environ.
Ypnypn

2

R, 103 137 109 109 103

Un peu plus heureux avec ça maintenant. L'utilisation de l'analyse avec un séparateur permet d'économiser beaucoup d'octets. Peut encore avoir des améliorations. Remplacé <-par =. Je n'ai pas toujours eu la meilleure des chances avec ça, mais ça a fonctionné cette fois.

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

Essais

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

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

Assez simple:

  • Entrez le numérateur et le dénominateur
  • Sortez le quotient avec 1 chiffre après la virgule décimale, puis retirez le dernier chiffre (par exemple -1/3->-0. )
  • Prendre des valeurs absolues *
  • Boucle:
    • Le numérateur reste après avoir divisé le dénominateur
    • Multiplier le numérateur par 10
    • Sortie du quotient entier comme chiffre suivant

* (Bien que le calcul pour a été déplacé à l'intérieur de la boucle pour économiser quelques octets.)

Edit: correction d'un bug avec des fractions négatives> -1.


0

Python 2.7, 209 octets

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

Éditer:

Sort maintenant tous les caractères sur la même ligne, comme demandé.

edit2:

Lit maintenant la fraction de l'argument de ligne de commande, comme demandé :)


1
Quelques conseils: 1) L'utilisation mapau lieu de la compréhension de la liste permet d'économiser un peu; 2) ne pas besoin des parenthèses autour m*ade l' un de ses sites, comme *, %et /sont tous la même priorité et gauche associative; 3) la logique 0 ou point sur la ligne 3 peut être simplifiée "0."[m==1], puisque vous l'imprimez de toute façon; 4) enregistrera probablement les caractères pour simplement définir o=stdout.writeet convertir les arguments numériques en chaîne avec des raccourcis si nécessaire.
DLosc

1
De plus, le code ne semble pas fonctionner avec les négatifs: 1/-3donne -1.666666666au lieu de -0.333333333.
DLosc
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.