Évaluation des expressions avec des raccourcis numériques

10

Vous travaillez pour une entreprise qui souhaite créer une calculatrice conviviale, et vous avez donc été chargé d'ajouter la possibilité pour les utilisateurs d'utiliser des "raccourcis numériques", c'est-à-dire des lettres qui représentent des valeurs numériques, comme kpour 1000. Parce que votre entreprise souhaite économiser de l'argent sur le stockage dans ces calculatrices, vous devez minimiser votre code autant que possible pour réduire le coût du stockage.


Ta tâche

Vous devez créer une fonction qui lit une expression en entrée de STDIN ou la prend comme paramètre et renvoie son évaluation ou l'imprime dans STDOUT.

Quelques clarifications

Permettez-moi de faire quelques définitions. Tout d'abord, nous avons l'entrée, que j'appelle une expression. Cela peut ressembler à ceci:

x + y / z

Au sein de cette expression , nous avons trois chiffres: x, yet z, séparés par les opérateurs ( +et /). Ces nombres ne sont pas nécessairement des entiers positifs (ni même des entiers). Ce qui complique les choses, c'est quand nous devons évaluer les raccourcis contenus dans les chiffres. Par exemple, avec

2k15

à des fins d'évaluation, nous avons divisé ce en trois chiffres: 2, 1000(qui est k), et 15. Ensuite, selon les règles, nous les combinons pour obtenir

2*1000 + 15 = 2015

Espérons que cela facilite un peu la compréhension des règles suivantes.

Règles

NB Sauf indication contraire, vous pouvez interpréter le mot "nombres" ou ses synonymes pour inclure des raccourcis.

  1. Ce qui suit constitue la sténographies numérique votre fonction doit être capable de traiter: k, m, b, t, and e. k, m, b, and tcorrespondent 1000, 1000000, 1000000000, and 1000000000000respectivement aux valeurs (mille, un million, un milliard et un billion). La esténographie sera toujours suivie d'un autre nombre n,, et représente 10^n. Vous devez permettre aux raccourcis numériques d'être présents net présents avant e. Par exemple, kekévalue à 1000*10^1000.

  2. Par souci de simplicité, si un nombre contient la sténographie e, il ne sera utilisé qu'une seule fois.

  3. Tout nombre ( raccourcis inclus ) avant qu'un raccourci soit multiplié par celui-ci. par exemple 120kkserait évalué comme 120 * 1000 * 1000. S'il n'y a pas de nombre avant, vous devez supposer que le nombre est 1 (comme la façon dont vous pourriez, en mathématiques, traiter ximplicitement une variable comme 1x). par exemple, e10évalue 10^10. Autre exemple: 2m2kévalue à 2*1000000*2*1000(rien n'y est ajouté).

  4. Tout numéro (les raccourcis ne s'appliquent pas) suivant le dernier raccourci d'un numéro contenant un raccourci y est ajouté. par exemple 2k12serait évalué comme 2*1000 + 12. L'exception à cette règle est si le raccourci eest utilisé, auquel cas le nombre ( raccourcis inclus ) suivant esera traité net évalué comme 10^n(voir la première règle).

  5. Votre fonction doit être capable de traiter les opérateurs +, -, *, and /qui sont respectivement l'addition, la soustraction, la multiplication et la division. Il peut en traiter davantage, si vous le souhaitez.

  6. Les opérations sont évaluées selon l' ordre des opérations.

  7. Les nombres en sténographie ne sont pas uniquement des entiers. 3.5b1.2est valide et doit être évalué comme3.5*1000000000 + 1.2 = 3500000001.2

  8. Les fonctions intégrées ne sont pas autorisées, si elles existent pour ce genre de chose. L'exception que j'ajouterai serait si votre langue convertit automatiquement les grands nombres en notation scientifique, auquel cas cela est admissible pour votre sortie.

  9. Le code le plus court en octets gagne, les failles standard s'appliquent.

Contribution

L'entrée sera une expression avec chaque nombre et opérateur séparés par des espaces. Les nombres peuvent contenir ou non un raccourci. Un exemple est présenté ci-dessous:

10 + 1b - 2k

Production

Votre fonction doit générer l'évaluation de l'expression sous forme de nombre. Il est admissible d'utiliser la notation scientifique si la sortie est trop grande pour être affichée. Vous devez avoir au moins trois décimales si le nombre n'est pas un entier. Il est admissible si vous conservez ces décimales si le nombre est un entier.

Cas de test

Contribution

t

Production

1000000000000

Contribution

1 + 4b / 10k11

Production

399561.483

Contribution

e2 + k2ke-1 - b12

Production

-999799912

ou

-999799912.000

Contribution

142ek12

Production

142e1012

ou

142.000e1012

Contribution:

1.2m5.25

Production:

1200005.25

Notes finales

C'est mon premier défi publié (avec l'aide des utilisateurs sur le bac à sable). Si quelque chose n'est pas clair, faites-le moi savoir et je ferai de mon mieux pour clarifier.

cole
la source
1
Bon premier défi
Digital Trauma
@DigitalTrauma Merci beaucoup! J'ai hâte de voir les réponses.
cole
Je ne comprends pas le deuxième exemple. Je pensais que le moyen terme était interprété comme 1000 + 2000 * 10 ^ -1, mais cela a donné une réponse finale de -999998712. (De plus, mon interprétation ne semble pas concorder avec le " dernier raccourci " de la règle 4 , mais je ne sais pas comment comprendre la séquence autrement k2k.) Pouvez-vous expliquer les étapes de son évaluation?
DLosc
@trichoplax oui, ce ne devrait être qu'un nombre; bonne prise.
cole
1
Après avoir regardé les commentaires sur le post du bac à sable, je pense qu'un exemple comme celui-ci 2m2kdevrait être ajouté à la discussion de la règle 3. En outre, il pourrait être préférable d'utiliser un terme différent - peut-être "entier" - pour les nombres littéraux comme 123celui-ci ne sont pas des raccourcis. Le mot «nombre» a environ 3 définitions différentes ici, tel qu'il se présente actuellement.
DLosc

Réponses:

4

Python 2, 553 octets

import sys
a=lambda i:lambda j:j*10**i
d={'k':a(3),'m':a(6),'b':a(9),'t':a(12)}
e='e'
o={'+':lambda i,j:i+j,'-':lambda i,j:i-j,'*':lambda i,j:i*j,'/':lambda i,j:i/j,e:lambda i,j:i*10**j}
r=[e,'*','/','+','-']
x=0
y=k=b=''
z=[]
q=lambda i,j:float(i or j)
for l in ''.join(sys.argv[1:]):
 if l in d:x,y=d[l](q(x,1)*q(y,1)),b
 elif l==e:z.extend([q(x+q(y,0),1),l]);x,y=0,b
 elif k==e:y+=l
 elif l in o:z.extend([x+q(y,0),l]);x,y=0,b
 else:y+=l
 k=l
z.append(x+q(y,0))
for m in r:
 while m in z:n=z.index(m);z[n-1:n+2]=[o[m](z[n-1],z[n+1])]
print repr(z[0])

Cette question semblait un peu mal aimée et semblait amusante, alors je lui ai donné un coup de feu. Je n'ai jamais fait de golf de code auparavant, donc il y a probablement beaucoup de choses qui peuvent être améliorées, mais je l'ai fait de mon mieux en fonction de ma connaissance de la langue. Une solution équivalente est possible en Python 3 au prix d'un octet supplémentaire:print repr(z[0]) -> print(repr(z[0])).

L'utilisation est quelque chose dans le sens de

python2 ShorthandMath.py <equation>

c'est à dire

python2 ShorthandMath.py e2 + k2ke-1 - b12

les sorties

-999799912.0

Des commentaires sur la façon d'améliorer cela seraient très appréciés. S'il y a suffisamment d'intérêt, je peux dé-golfer et commenter le programme, mais la plupart sont déjà assez lisibles (un fait inquiétant dans le code golf).

Il est à noter que le programme rompt avec l'exemple 142ek12 car cette valeur est ridiculement grande et le programme déborde.

Pour compenser, ce qui suit est légèrement plus long, mais peut théoriquement gérer tout ce qui est lancé en raison de l'utilisation de la bibliothèque de précision arbitraire intégrée. La syntaxe est identique.

Python 2, 589 588 octets (précision arbitraire)

import sys
from decimal import*
a=lambda i:lambda j:j*10**i
d={'k':a(3),'m':a(6),'b':a(9),'t':a(12)}
e='e'
o={'+':lambda i,j:i+j,'-':lambda i,j:i-j,'*':lambda i,j:i*j,'/':lambda i,j:i/j,e:lambda i,j:i*10**j}
r=[e,'*','/','+','-']
x=c=Decimal(0)
y=k=b=''
z=[]
q=lambda i,j:Decimal(float(i or j))
for l in ''.join(sys.argv[1:]):
 if l in d:x,y=d[l](q(x,1)*q(y,1)),b
 elif l==e:z.extend([q(x+q(y,0),1),l]);x,y=c,b
 elif k==e:y+=l
 elif l in o:z.extend([x+q(y,0),l]);x,y=c,b
 else:y+=l
 k=l
z.append(x+q(y,0))
for m in r:
 while m in z:n=z.index(m);z[n-1:n+2]=[o[m](z[n-1],z[n+1])]
print z[0]
BobChao87
la source
Je vais dire que la première version devrait être correcte et je vous répondrai s'il y a quelque chose qui ne va pas (je ne peux pas regarder / penser trop attentivement en ce moment).
cole
@Cole Awesome, merci. Je l'ai essayé sur tous les exemples donnés, et tout le monde a raison au moins.
BobChao87