# Evaluating expressions with numerical shorthands

You work for a company that wants to make a user-friendly calculator, and thus you have been tasked with adding the ability for users to use "numerical shorthands," that is, letters that represent numerical values, such as k for 1000. Because your company wants to save money on storage in said calculators, you must minimize your code as much as possible to reduce the cost of storage.

You are to create a function that either reads an expression as input from STDIN or takes it as a parameter and returns its evaluation or prints it to STDOUT.

## Some Clarification

Let me do some definitions. First off, we have the input, which I call an expression. This can be something like the following:

x + y / z


Within this expression we have three numbers: x, y, and z, separated by operators (+ and /). These numbers are not necessarily positive integers (or even integers). What complicates things is when we have to evaluate shorthands contained within numbers. For example, with

2k15


for purposes of evaluation, we split this up into three numbers: 2, 1000 (which is k), and 15. Then, according to the rules, we combine them to obtain

2*1000 + 15 = 2015


Hopefully this makes it a bit easier to understand the following rules.

## Rules

N.B. Unless specified otherwise, you can interpret the word "numbers" or its synonyms to include shorthands.

1. The following constitutes the numerical shorthands your function must be able to process: k, m, b, t, and e. k, m, b, and t correspond to the values 1000, 1000000, 1000000000, and 1000000000000 respectively (one thousand, one million, one billion, and one trillion). The e shorthand will always be followed by another number, n, and represents 10^n. You must allow for numerical shorthands to be present in n and present before e. For example, kek evaluates to 1000*10^1000.

2. For simplicity's sake, if a number has the shorthand e in it, it will only be used once.

3. Any number (shorthands included) before a shorthand is multiplied by it. e.g. 120kk would be evaluated as 120 * 1000 * 1000. If there is no number before it, you must assume that the number is 1 (like how you might, in mathematics, treat a variable x implicitly as 1x). e.g. e10 evaluates to 10^10. Another example: 2m2k evaluates to 2*1000000*2*1000 (nothing is added to it).

4. Any number (shorthands do not apply) following the last shorthand in a number containing a shorthand is added to it. e.g. 2k12 would be evaluated as 2*1000 + 12. The exception to this is if the shorthand e is used, in which case the number (shorthands included) following e will be treated as n and evaluated as 10^n (see the first rule).

5. Your function must be able to process the operators +, -, *, and / which are addition, subtraction, multiplication, and division respectively. It may process more, if you so desire.

6. Operations are evaluated according to the order of operations.

7. Numbers in shorthands are not only integers. 3.5b1.2 is valid and is to be evaluated as 3.5*1000000000 + 1.2 = 3500000001.2

8. Built-ins are not allowed, if they exist for this sort of thing. The exception that I'll add would be if your language automatically converts large numbers to scientific notation, in which case that is admissible for your output.

9. Shortest code in bytes wins, standard loopholes applying.

## Input

The input will be an expression with each number and operator separated by spaces. Numbers may or may not contain a shorthand. A sample is shown below:

10 + 1b - 2k


## Output

Your function must output the evaluation of the expression as a number. It is admissible to use scientific notation if the output would be too large to display. You must have at least three decimal places if the number is not an integer. It is admissible if you retain these decimal places if the number is an integer.

## Test Cases

Input

t


Output

1000000000000


Input

1 + 4b / 10k11


Output

399561.483


Input

e2 + k2ke-1 - b12


Output

-999799912


or

-999799912.000


Input

142ek12


Output

142e1012


or

142.000e1012


Input:

1.2m5.25


Output:

1200005.25


## Final Notes

This is my first challenge posted (with some help from users on the sandbox). If anything is unclear, make it known to me and I will do my best to clarify.

• Good first challenge Sep 10, 2015 at 23:20
• @DigitalTrauma Thanks a lot! I look forward to seeing the answers.
– cole
Sep 10, 2015 at 23:22
• I don't understand the second example. I thought the middle term was interpreted as 1000 + 2000 * 10 ^ -1, but that gave a final answer of -999998712. (Also, my interpretation doesn't seem to jive with rule 4's "last shorthand," but I'm not sure how else to understand the sequence k2k.) Can you please explain the steps in evaluating it? Sep 10, 2015 at 23:22
• @trichoplax yes, it should only be a number; good catch.
– cole
Sep 10, 2015 at 23:24
• After looking at the comments on the sandbox post, I think an example like 2m2k should be added to the discussion of rule 3. Also, it might be best to use a different term--maybe "integer"--for the literal numbers like 123 that are not shorthands. The word "number" has about 3 different definitions here, as it stands now. Sep 11, 2015 at 0:15

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


This question looked a little unloved and seemed fun, so I gave it a shot. I've never done code golf before, so there's probably a lot that can be improved, but I gave it my best based on my knowledge of the language. An equivalent solution is possible in Python 3 at the cost of one extra byte: print repr(z[0]) -> print(repr(z[0])).

Usage is something along the lines of

python2 ShorthandMath.py <equation>


i.e.

python2 ShorthandMath.py e2 + k2ke-1 - b12


outputs

-999799912.0


Input for how to improve this would be much appreciated. If there is sufficient interest, I can ungolf and comment the program, but most of it pretty legible already (a concerning fact in code golf).

It should be noted that the program breaks with the example 142ek12 because that value is ludicrously large and the program overflows.

To compensate, the following is slightly longer, but can theoretically handle anything thrown at it due to use of the built in arbitrary precision library. Syntax is identical.

# Python 2, 589 588 bytes (arbitrary precision)

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]

• I'm going to say the first version should be fine and I'll get back to you if try there's anything wrong (I can't look/think too carefully right now).
– cole
Oct 13, 2015 at 1:15
• @Cole Awesome, thanks. I tried it out on every example given, and it gets all of those right at least. Oct 13, 2015 at 5:44