Cette question n'a pas besoin de s'appliquer uniquement aux décimales terminales - les décimales répétitives peuvent également être converties en fractions via un algorithme.
Votre tâche consiste à créer un programme qui prend une décimale répétée en entrée et à sortir le numérateur et le dénominateur correspondants (en termes les plus bas) qui produisent cette expansion décimale. Les fractions supérieures à 1 doivent être représentées comme des fractions impropres comme 9/5
. Vous pouvez supposer que l'entrée sera positive.
La décimale répétée sera donnée dans ce format:
5.3.87
avec tout après le deuxième point répété, comme ceci:
5.3878787878787...
Votre programme affichera deux entiers représentant le numérateur et le dénominateur, séparés par une barre oblique (ou la forme équivalente dans votre langue si vous ne produisez pas de texte brut):
889/165
Notez que les décimales terminales n'auront rien après le deuxième point, et les décimales sans partie décimale non répétitive n'auront rien entre les deux points.
Cas de test
Ces cas de test couvrent tous les cas de coin requis:
0..3 = 1/3
0.0.3 = 1/30
0.00.3 = 1/300
0.6875. = 11/16
1.8. = 9/5
2.. = 2/1
5..09 = 56/11
0.1.6 = 1/6
2..142857 = 15/7
0.01041.6 = 1/96
0.2.283950617 = 37/162
0.000000.1 = 1/9000000
0..9 = 1/1
0.0.9 = 1/10
0.24.9 = 1/4
Si vous le souhaitez, vous pouvez également supposer que les fractions sans parties entières n'ont rien à gauche du premier point. Vous pouvez tester cela avec ces cas de test facultatifs:
.25. = 1/4
.1.6 = 1/6
..09 = 1/11
.. = 0/1
la source
9/99
?(in lowest terms)
c'est-à-dire que la fraction doit être simplifiée.13
au lieu de13/1
?1.9999...
et sorties2/1
1.9999.
est19999/10000
, pour obtenir2/1
ce dont vous avez besoin1..9
, n'est-ce pas?Réponses:
Dyalog APL (
75736968 caractères)Voici une autre et cinquième tentative (probablement ma dernière); J'ai passé la journée à essayer d'écrire un morceau de code de moins de 80 caractères et à être pleinement conforme aux règles. Ce défi a fait ma journée!
J'ai finalement obtenu une ligne d'APL composée de 75 caractères, fonctionnant avec Dyalog APL (mais pas sur la page d'interpréteur en ligne car utilisant la fonction d'
⍎
exécution ), qui est la suivante:Bien sûr, je pourrais le raccourcir un peu, mais les cas particuliers où un, deux ou trois champs manquent. Mon code peut même gérer le
..
cas d'entrée.Je sais qu'APL est difficile à lire, et comme les gens aiment comprendre comment fonctionne réellement un morceau de code, voici quelques explications. Fondamentalement, je calcule le dénominateur final dans la variable D et le numérateur final dans la variable N.
APL est analysé de droite à gauche.
I←
).P←'.'=
). Par exemple, «1.2.3» sera mappé sur 0 1 0 1 0.10⊥
); maintenant '1.2.3' est 1010.1-⍨
ou avec¯1+
, ici j'ai choisi le second). Maintenant, «1.2.3» est 1009.⍕
), deux chiffres initiaux sont supprimés (2↓
), ce qui fait 09 de notre exemple initial '1.2.3'; la chaîne est inversée (⌽
).'0',
mais je l'ai fait pour éviter une erreur lorsque les deuxième et troisième champs sont tous les deux vides. La chaîne est reconvertie en un nombre (⍎
) et elle est stockée dans D, qui est le dénominateur, sauf lorsque les deux derniers champs sont vides, car dans ce cas, D est égal à 0.D←D+0=
morceau de code définit D à 1 s'il est actuellement nul, et maintenant D contient le dénominateur (avant la division GCD cependant).×
) par le contenu de la chaîne initiale I jusqu'au deuxième point avec(⍎'0',I/⍨2>+\P)
lequel recommence depuis P (0 1 0 1 0 dans mon exemple), ajoute les nombres successifs en les cumulant (ce qui fait 0 1 1 2 2 dans mon exemple), vérifiez quelles valeurs sont inférieures à 2 (en faisant le vecteur booléen 1 1 1 0 0), et en prenant les caractères correspondants dans I; un autre 0 est ajouté devant la chaîne pour empêcher un autre piège (si les deux champs initiaux sont vides) et le tout est converti en un nombre.(⍎'0',1↓I/⍨2=+\P)
, qui reprend P, ajoute en cumulant à nouveau, vérifie quelles valeurs sont égales à 2 (voir explication précédente), prend les caractères, supprime la première qui est un point , ajoute un caractère 0 initial empêchant et convertit en un nombre.edit: Voici un correctif pour 73 caractères:
L'idée de ce hack est de calculer d'abord le cas où l'addition cumulative a des valeurs égales à 2, de les stocker pour plus tard et d'inverser ce masque au niveau du bit pour obtenir le premier cas; le calcul du cas suivant nécessite donc moins de caractères.
edit: Voici un autre correctif pour 69 caractères:
L'idée de ce hack est d'incorporer le cas spécial le plus compliqué en tant que code APL dans la chaîne à évaluer (au stade de la conversion chaîne en nombre).
edit: Voici un autre correctif pour 68 caractères:
L'idée de ce hack est de remplacer l' ajout de -1 à la valeur de soustraction de 1 à cette valeur par l'opération de soustraction de cette valeur à 1 puis de supprimer plus tard un caractère de plus au début (qui sera le signe moins).
modifier: changement cosmétique:
Aucune amélioration de taille, mais plus satisfaits d'obtenir la fonction maximale du code à évaluer.
la source
INVALID TOKEN
. Est-ce que tu sais pourquoi?I
): voir ce permalienPerl 6 (
93101100806866 octets)La taille a été augmentée pour ne rien gérer, au lieu de simplement échouer. Mouq a proposé d'utiliser
$/
, donc il est maintenant utilisé, et le code est 20 octets plus court. Ayiko a proposé de le remplacer/
par, le code est donc encore plus court (de 12 octets). Puis Mouq a proposé de les remplacer
chars
parcomb
(dans un contexte numérique, ils sont identiques, car la liste des caractères après la conversion en nombre est le nombre de caractères).Exemple de sortie:
la source
0..09
retourne1/11
, mais0.0.09
revient1/110
.0.1 + 0.2 == 0.3
en Perl 6.$/=split ".",get;say join "/",($0+($1+$2/(9 x chars $2 or 1))/10**$1.chars).nude
:)J (
859089 caractères)Ma fonction d'origine, qui était 5 caractères plus courte que la seconde, avait quelques bugs: elle ne produisait pas d'entiers comme "n / 1" et elle donnait la mauvaise réponse sur les nombres avec plus d'une douzaine de chiffres. Voici une fonction corrigée dans J qui intègre également la suggestion d'Eelvex pour enregistrer un personnage:
Il reçoit une chaîne et renvoie une chaîne. Voici un exemple de session:
la source
0/1
et3/1
inf deux premiers cas de test, Voir ce commentaire('0','x',~])
et enregistrez un octet.C, 171
Assez longtemps. Pourrait être encore réduit. Non
scanf
, ce qui ne peut vraiment pas le gérer s'il n'y a pas de nombres entre les points. Nonstrtol
. Juste le calcul des nombres:Tester:
la source
DC (pas entièrement général, raccourci à 76 caractères)
Pas entièrement général, mais s'il vous plaît, considérez que je l'ai fait avec l'une des choses les plus anciennes du monde:
Modifier: je modifie ma solution; ce n'est pas plus général, mais un peu plus court:
Utilisez-le comme:
Le premier champ n'est pas obligatoire:
est OK.
Le deuxième et le premier champ nécessitent au moins un chiffre
la source
Javascript, 203
Beaucoup trop long, mais toujours amusant. Retour à la ligne car les points-virgules sont illisibles.
la source
889/NaN
quand je cours5.3.87
... Est-ce que je fais quelque chose de mal?"889/165"
dans la console. Comment le gérez-vous? @rafaelcastrocoutob=1
pièce à l'intérieurprompt()
.f=(P(10,s[2].length)-1)*P(10,l),f=f?f:1
=>f=(P(10,s[2].length)-1)*P(10,l)||1
J (méthode différente)
Une autre solution basée sur une méthode très différente; cette fois, c'est tout à fait général; ne manque que le 1-dénominateur lorsqu'un entier est soumis:
la source
GolfScript (67 caractères)
NB Cela prend en charge les parties entières vides.
Si la chaîne est de la forme,
'n.p.q'
la valeur estn + p/E + q/(DE) = ((nD + p)E + q)/DE
oùD = 10^(len p)
etE = 10^(len q) - 1
, sauf quandlen q = 0
, dans ce casE = 1
(pour éviter la division par 0).Dissection:
Démo en ligne qui simule l'exécution du programme avec chacune des entrées de test, une à la fois.
la source
0.1.
Python
Aucune bibliothèque - 156 caractères
Utilisation
fractions
- 127 caractèresla source
fractions
version imprime des choses comme "Fraction (7, 5)" au lieu de "7/5", n'est-ce pas?_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),
ValueError: need more than 1 value to unpack
print
utilisestr
lorsqu'il est disponible, nonrepr
. Voici la sortie de ma part: puu.sh/7w64w.png_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),(10**len(c)-bool(c))*10**len(b);f=_(d,e);print'%i/%i'%(d/f,e/f)
devrait aller tout en une seule ligne.Mathematica, 143
Comme d'habitude, Mathematica offre de nombreuses fonctions de haut niveau pour faire le travail, mais leur donne des noms verbeux.
Exemple de sortie à ajouter plus tard quand j'aurai le temps.
la source
n/1
de réduire àn
? J'ajouterai les ~ 50 octets supplémentaires pour convertir les entiers plus tard.FromDigits
donc j'ai décidé de le poster aussi.Rubis - 112
C'est ma première expérience avec le rubis, alors n'hésitez pas à suggérer des améliorations.
la source
If you wish
. Je ne souhaite pas, donc je ne supporte pas les fractions sans le 1er ou le 3e groupe de chiffres. Je soutiens cependant les fractions manquant du 2ème groupe de chiffres, ce qui correspond à la spécification.C, 164
Ceci est similaire à la solution C d'Orion, même si je l'ai fait à partir de zéro. J'avoue cependant avoir volé un certain nombre de ses optimisations. Il n'est pas beaucoup plus court, mais il gère 0,25. = 1/4 et 0,00000000,1 = 1/9000000.
la source
Deux réponses python sans bibliothèque. Gère d'abord l'entrée facultative sans chiffre avant le premier. et 162 caractères
Le second ne gère rien avant le premier chiffre mais gère correctement toutes les entrées requises et est de 150 caractères
la source
Haskell
la source
span
pour implémenter s, ajoutez des alias courts pour les fonctions, supprimez l'espace si possible.import Data.Ratio v=span(/='.');w=tail;l=length;f n=(r x)%1+(r y)%p+(r z)%((10^t-1)*p)where{(x,b)=v n;(y,d)=v(w b);z=w d;p=10^(l y);r""=0;r n=read n;t=if null z then 9 else l z}
- 178 caractères, en baisse de 321. NBTrue
est synonyme deotherwise
,null z
estlength z==0
JavaScript (ECMAScript 6)
180175Bien que ce ne soit pas un gagnant clair pour la prime de 300 ... c'est le plus court que je puisse trouver:
P
fonction Power en la modifiant au+("1e"+a)
lieu d'Math.pow(10,a)
enregistrer ainsi quelques caractères supplémentaires ...la source
Mathematica 175
La plupart de la routine consiste à masser l'entrée. Environ 50 caractères sont allés à la gestion des entiers.
Exemples
Plus d'exemples:
Comment cela serait normalement accompli dans Mathematica
FromDigits
peut obtenir une fraction directement à partir d'une décimale récurrente récurrente, à condition que l'entrée soit sous une forme particulière. Les entiers sont affichés sous forme d'entiers.la source
J (96 caractères)
Je n'utilise pas le symbole de barre oblique comme séparateur (mais la solution dans Mathematica non plus car elle utilise une représentation graphique qui est de toute façon meilleure); en langage J, la fraction est affichée avec à la
r
place/
:la source
APL (pas entièrement général)
Pas complètement général (comme ma solution pour DC); fonctionne avec Dyalog APL (mais pas sur la version en ligne de Dyalog APL, je ne sais pas pourquoi):
Le premier champ est facultatif, mais au moins un chiffre est requis pour les deux autres champs.
la source
JavaScript (189)
Exemple:
Contribution:
Sortie:
la source
C (420 caractères tels qu'écrits; moins après la suppression des espaces inutiles)
Notez que cela suppose 64 bits
long
(par exemple Linux 64 bits); il échouera pour le scénario de test0.2.283950617
sur les systèmes utilisant 32 bitslong
. Cela peut être résolu au prix de certains caractères en changeant le type enlong long
et en changeant laprintf
chaîne de format en conséquence.la source
'0'
en48
.switch
déclaration sous la formeif(c==46) n[++i]=1; else d[i]=10*d[i]+c-48,n[i]*=10;
.GTB , 81
Exemple
la source
GTB
lien ci-dessus si vous ne me croyez pas. Vous obtiendrez des éléments compressés pour un programme propriétaire, puis vous rechercherez ce programme et constaterez que le site qui prétend fournir un téléchargement dit qu'il n'est pas disponible. Alors, comment pouvons-nous le compiler?