Ausdrücke mit numerischen Abkürzungen auswerten

10

Sie arbeiten für ein Unternehmen , das einen benutzerfreundliche Rechner machen will, und so haben Sie mit dem Hinzufügen der Möglichkeit für Benutzer verwenden „numerische Kürzel“ zu beauftragt worden , das heißt, Buchstaben , die numerischen Werte darstellen, wie kfür 1000. Da Ihr Unternehmen bei der Speicherung in diesen Taschenrechnern Geld sparen möchte, müssen Sie Ihren Code so weit wie möglich minimieren, um die Speicherkosten zu senken.


Deine Aufgabe

Sie müssen eine Funktion erstellen, die entweder einen Ausdruck als Eingabe von STDIN liest oder als Parameter verwendet und seine Auswertung zurückgibt oder an STDOUT druckt.

Einige Klarstellungen

Lassen Sie mich einige Definitionen machen. Zunächst einmal haben wir die Eingabe, die ich einen Ausdruck nenne. Dies kann ungefähr so ​​aussehen:

x + y / z

In diesem Ausdruck haben wir drei Zahlen: x, y, und z, getrennt durch Operatoren ( +und /). Diese Zahlen sind nicht unbedingt positive ganze Zahlen (oder sogar ganze Zahlen). Was die Dinge kompliziert, ist, wenn wir in Zahlen enthaltene Kurzschriften bewerten müssen. Zum Beispiel mit

2k15

Zu Bewertungszwecken teilen wir dies in drei Zahlen auf : 2, 1000(was ist k) und 15. Dann kombinieren wir sie gemäß den Regeln, um sie zu erhalten

2*1000 + 15 = 2015

Hoffentlich erleichtert dies das Verständnis der folgenden Regeln.

Regeln

NB Sofern nicht anders angegeben, können Sie das Wort "Zahlen" oder seine Synonyme so interpretieren, dass es Kurzzeichen enthält.

  1. Das Folgende stellt die numerischen Abkürzungen dar, die Ihre Funktion verarbeiten kann : k, m, b, t, and e. k, m, b, and tentsprechen jeweils den Werten 1000, 1000000, 1000000000, and 1000000000000(eintausend, eine Million, eine Milliarde und eine Billion). Der eKurzschrift folgt immer eine andere Zahl nund steht für 10^n. Sie müssen zulassen, dass numerische Kurzzeichen in nund vor vorhanden sind e. Zum Beispiel kekwertet auf aus 1000*10^1000.

  2. Der Einfachheit halber wird eine Zahl, die die Abkürzung enthält e, nur einmal verwendet.

  3. Jede Zahl ( einschließlich Kurzschrift ) vor einer Kurzschrift wird damit multipliziert. zB 120kkwürde bewertet als 120 * 1000 * 1000. Wenn keine Zahl davor steht, müssen Sie davon ausgehen, dass die Zahl 1 ist (wie Sie in der Mathematik eine Variable ximplizit als behandeln könnten 1x). zB e10bewertet zu 10^10. Ein weiteres Beispiel: wird 2m2kausgewertet 2*1000000*2*1000(es wird nichts hinzugefügt).

  4. Eine beliebige Zahl (Abkürzungen gelten nicht) nach der letzten Kurzschrift in einer Zahl, die eine Kurzschrift enthält, wird hinzugefügt. zB 2k12würde bewertet als 2*1000 + 12. Die Ausnahme ist, wenn die Kurzschrift everwendet wird. In diesem Fall wird die folgende Nummer ( einschließlich Kurzschrift ) eals behandelt nund ausgewertet 10^n(siehe erste Regel).

  5. Ihre Funktion muss in der Lage sein, die Operatoren zu verarbeiten, +, -, *, and /die Addition, Subtraktion, Multiplikation bzw. Division sind. Es kann mehr verarbeiten, wenn Sie dies wünschen.

  6. Operationen werden gemäß der Reihenfolge der Operationen bewertet .

  7. Zahlen in Kurzschrift sind nicht nur ganze Zahlen. 3.5b1.2ist gültig und ist zu bewerten als3.5*1000000000 + 1.2 = 3500000001.2

  8. Eingebaute sind nicht erlaubt, wenn sie für solche Dinge existieren. Die Ausnahme, die ich hinzufügen werde, wäre, wenn Ihre Sprache große Zahlen automatisch in wissenschaftliche Notation konvertiert. In diesem Fall ist dies für Ihre Ausgabe zulässig.

  9. Der kürzeste Code in Bytes gewinnt, es gelten Standardlücken.

Eingang

Die Eingabe ist ein Ausdruck, bei dem jede Zahl und jeder Operator durch Leerzeichen getrennt sind. Zahlen können eine Kurzschrift enthalten oder nicht. Ein Beispiel ist unten gezeigt:

10 + 1b - 2k

Ausgabe

Ihre Funktion muss die Auswertung des Ausdrucks als Zahl ausgeben. Es ist zulässig, wissenschaftliche Notation zu verwenden, wenn die Ausgabe zu groß wäre, um angezeigt zu werden. Sie müssen mindestens drei Dezimalstellen haben, wenn die Zahl keine Ganzzahl ist. Es ist zulässig, wenn Sie diese Dezimalstellen beibehalten, wenn die Zahl eine Ganzzahl ist.

Testfälle

Eingang

t

Ausgabe

1000000000000

Eingang

1 + 4b / 10k11

Ausgabe

399561.483

Eingang

e2 + k2ke-1 - b12

Ausgabe

-999799912

oder

-999799912.000

Eingang

142ek12

Ausgabe

142e1012

oder

142.000e1012

Eingang:

1.2m5.25

Ausgabe:

1200005.25

Schlussbemerkungen

Dies ist meine erste Herausforderung (mit Hilfe von Benutzern in der Sandbox). Wenn etwas unklar ist, machen Sie es mir bekannt und ich werde mein Bestes tun, um es zu klären.

cole
quelle
1
Gute erste Herausforderung
Digital Trauma
@ DigitalTrauma Vielen Dank! Ich freue mich auf die Antworten.
Cole
Ich verstehe das zweite Beispiel nicht. Ich dachte, die Mittelfrist würde so interpretiert 1000 + 2000 * 10 ^ -1, aber das gab eine endgültige Antwort von -999998712. (Außerdem scheint meine Interpretation nicht mit der " letzten Abkürzung " von Regel 4 übereinzustimmen , aber ich bin mir nicht sicher, wie ich die Reihenfolge sonst verstehen soll k2k.) Können Sie bitte die Schritte zur Bewertung erläutern?
DLosc
@trichoplax ja, es sollte nur eine Zahl sein; guter Fang.
Cole
1
In den Kommentaren auf der Sandbox - Post Nach einem Blick, denke ich ein Beispiel wie 2m2ksoll 3. Auch zur Diskussion der Regel hinzugefügt wird, ist es am besten sein könnte , einen anderen Begriff zu verwenden - vielleicht „integer“ - für die wörtlichen Zahlen wie 123die sind keine Abkürzungen. Das Wort "Zahl" hat hier ungefähr 3 verschiedene Definitionen, wie es jetzt steht.
DLosc

Antworten:

4

Python 2, 553 Bytes

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])

Diese Frage sah ein wenig ungeliebt aus und schien lustig zu sein, also habe ich es versucht. Ich habe noch nie Code Golf gespielt, daher gibt es wahrscheinlich eine Menge, die verbessert werden kann, aber ich habe mein Bestes gegeben, basierend auf meinen Sprachkenntnissen. Eine äquivalente Lösung ist in Python 3 zum Preis von einem zusätzlichen Byte möglich: print repr(z[0])-> print(repr(z[0])).

Nutzung ist etwas in der Art von

python2 ShorthandMath.py <equation>

dh

python2 ShorthandMath.py e2 + k2ke-1 - b12

Ausgänge

-999799912.0

Beiträge zur Verbesserung sind sehr willkommen. Wenn genügend Interesse besteht, kann ich das Programm auflösen und kommentieren, aber das meiste davon ist bereits ziemlich gut lesbar (eine besorgniserregende Tatsache im Code-Golf).

Es ist zu beachten, dass das Programm mit dem Beispiel bricht, 142ek12da dieser Wert lächerlich groß ist und das Programm überläuft.

Um dies zu kompensieren, ist das Folgende etwas länger, kann aber theoretisch alles verarbeiten, was aufgrund der Verwendung der eingebauten Bibliothek mit beliebiger Genauigkeit darauf geworfen wird. Die Syntax ist identisch.

Python 2, 589 588 Bytes (willkürliche Genauigkeit)

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
quelle
Ich werde sagen, dass die erste Version in Ordnung sein sollte und ich werde mich bei Ihnen melden, wenn Sie versuchen, dass etwas nicht stimmt (ich kann momentan nicht genau hinschauen / überlegen).
Cole
@ Cole Super, danke. Ich habe es an jedem Beispiel ausprobiert, und es macht zumindest alle richtig.
BobChao87