# Isn't the point of math to just use numbers?

Write a program that converts a mathematical expression to words, evaluates the expression, and prints how the equation would be spoken aloud.

Input

• The input must only contain numbers and the symbols +, -, *, and /. There cannot be any whitespace in the input.
• The input does not say what the expression is equal to.

Output

• While order of operations must be followed in determining the numerical answer in the expression, it is not necessary to indicate this in the output (for this reason, the input cannot contain parentheses).
• Numbers must be printed in capital letters. Operations must be printed in lower case.
• Numbers must be printed in the order that they appear in the input. Then the word equals must be printed, then the answer.
• Numbers in the output can be negative. The word negative is written in capital letters.
• Operations and numbers must be separated by a space. There cannot be any space after the last letter is printed.
• + in the input gets converted to plus in the output. - in the input gets converted to minus in the output. * in the input gets converted to times in the output. / in the input gets converted to divided by in the output.
• Division by 0 is not allowed.
• When division results in a decimal, the number should be rounded to three decimal places and read X POINT X X X where the Xs are replaced by numbers.
• Negative numbers should have NEGATIVE in front of them.
• For simplicity, all numbers must have absolute value less than 1000.
• 0 is ZERO (not NOUGHT, OH, etc).

Samples

Inputs

1+2
2-3
6*2-4/1
1+1-1*1/1
2/3
413-621


Outputs

ONE plus TWO equals THREE
TWO minus THREE equals NEGATIVE ONE
SIX times TWO minus FOUR divided by ONE equals EIGHT
ONE plus ONE minus ONE times ONE divided by ONE equals ONE
TWO divided by THREE equals ZERO POINT SIX SIX SEVEN
FOUR HUNDRED THIRTEEN minus SIX HUNDRED TWENTY-ONE equals NEGATIVE TWO HUNDRED EIGHT


This is code golf, fellas. Standard CG rules apply. Shortest code in bytes wins.

• Is there a limit to the size of the numbers? Are decimals to be handled and if so to what precision? Commented Sep 21, 2015 at 2:55
• How do you get TWO for the last example? I get 1+1-1*1/1=1 Commented Sep 21, 2015 at 2:56
• @MickyT Updated. Commented Sep 21, 2015 at 2:58
• Also, do we have to handle numbers greater than 9? How do we output those? ONE NINE or NINETEEN? What is the maximum number we will have to handle? Commented Sep 21, 2015 at 3:36
• @Eridan I think it's to late to update. That's probably invalidated every answer Commented Sep 21, 2015 at 14:30

# JavaScript ES6, 255247237225 219 bytes

s=>(s+'='+ +eval(s).toFixed(3))[h=(a,b,l)=>' '+[a,...btoa(b).splitz][l],t='replace'](/\D/g,l=>h('divided by',¶)³:eºÌæ{¬Íê®j[3¦§·<,'*+-/=.'.indexOf(l)))[t](/\d/g,l=>h('ZERO',8Ñ3Mc³LtD1NQÅ!Q3HóHED71tó4D,l))


I'll resume golfing tomorrow. Gotta sleep :/

Base encoding may cause issues. If it does, I'll add a pastebin and possibly a hex dump.

If you find any issues (or the spec changes) don't hesitate to tell me, I'll fix it as soon as possible.

## Explanation

s=>     // Function with argument "s"
(s+'='                  // Add an equal sign to the input
+ +eval(s).toFixed(3)    // Add the value of the expression rounded to 3 places
)[h=(a,b,l)=>           // Function h with args a,b, and l
// Return...
' '+                    // A space added to...
[a,...btoa(b).splitz] // Base decode the compressed words
[l]                     // Grab the correct word
,t='replace'            // Alias replace command

](/\D/g,                // Replace non-digits with...
l=>h(                                   // Function h
'divided by',¶)³:eºÌæ{¬Íê®j[3¦§·<, // Base encoded words
'*+-/=.'.indexOf(l)                  // Replace operator with correct word
)

)[t](                             // Replace again
/\d/g,l=>                      // Replaces Digits with...
h('ZERO',8Ñ3Mc³LtD1NQÅ!Q3HóHED71tó4D // Base encoded words
,l                                   // The associated number
)
)


## Python 3, 268 224bytes

a=input()
o=eval(a)
print(*[{i:j for i,j in zip('*+-./=1234567890','times,plus,minus,POINT,divided by,equals,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,ZERO'.split(','))}[i] for i in a+'='+('%.'+str(3*(int(o)!=o))+'f')%o])


A dictionary lookup for each item assuming numbers are only evaluated between 0-9. Would appreciate some feedback on this.

Explanation:

The following formats the output string with the required decimals based on the fact that in python integers evaluate as equal to the equivalent float. e.g. 1.0 == 1 Which I use to identify integer numbers.

('%.'+str(3*(int(o)!=o))+'f')%o
('%.0f')%o if o is an integer
('%.3f')%o if o is a decimal


edit: Dictionary generators!

• 13+468-1966 returns ONE THREE plus FOUR SIX EIGHT minus ONE NINE SIX SIX equals minus ONE FOUR EIGHT FIVE instead of THIRTEEN plus FOUR HUNDRED SIXTY-EIGHT minus ONE THOUSAND NINE HUNDRED SIXTY-SIX equals NEGATIVE ONE THOUSAND FOUR HUNDRED EIGHTY-FIVE
– RK.
Commented Sep 21, 2015 at 20:23
• Yeah... The rules changed overnight... Probably adds quite a few bytes regardless.
– Todd
Commented Sep 22, 2015 at 6:43

# Pyth, 170143 141 bytes

jdm@c"ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,plus,minus,times,divided by,POINT,equals"\,x+jkmkUT"+-*/.="d++z\=?q>2J.Rvz3".0"<2JJ


Evaluates the input and if it ends with ".0", strips it. Then loops through a list with the numbers, then looks with their word representation.

# Python 2, 281223221 219 + 5 bytes

run with: "python -Qnew golf.py" to enable float divisions

a=raw_input()
print" ".join("ZERO%ONE%TWO%THREE%FOUR%FIVE%SIX%SEVEN%EIGHT%NINE%NEGATIVE%times%plus%equals%minus%POINT%divided by".split("%")[ord(i)-48]for i in a+','+("%.3f"%eval(a)).replace("-",")").replace(".000",""))


4 bytes off thanks to Zach Gates

• You can remove the spaces around your modulo operator. It saves 2 bytes. Commented Sep 21, 2015 at 14:11
• You can also remove the r (that makes it a raw string) from in front of your (\d+) regex string. And the first and last bracket inside the " ".join, because you can pass the iterable as an argument. Commented Sep 21, 2015 at 14:14
– Max
Commented Sep 21, 2015 at 14:23
– RK.
Commented Sep 21, 2015 at 20:24
• The OP changed the rules after the game has started... to spell the numbers in english words is another CG!
– Max
Commented Sep 22, 2015 at 6:31

# Python 2, 628 + 5 bytes

run with: "python -Qnew golf.py" to enable float divisions

this one should spell correctly the numbers

import re
a=raw_input()
d,x="ZERO%ONE%TWO%THREE%FOUR%FIVE%SIX%SEVEN%EIGHT%NINE%TEN%ELEVEN%TWELVE%THIR%FOUR%FIF%SIX%SEVEN%EIGH%NINE%TWENTY%THIRTY%FORTY%FIFTY%SIXTY%SEVENTY%EIGHTY%NINETY%NEGATIVE%times%plus%equals%minus%POINT%divided by".split("%"),[]
for i in re.split("([.),/*+-])",a+','+("%.3f"%eval(a)).replace("-",")").rstrip('0').rstrip('.')):
r=""
if len(i)>2:
x+=[d[int(i)//100],"HUNDRED"];i=i[1:].lstrip("0")
if len(i)>1:
z=int(i)
if z<20:r+=d[z]+["","TEEN"][z>12];i=""
else:r+=d[z//10+18]+["-",""][i[1]<"1"];i=i[1].strip("0")
if i:
c=d[ord(i)-48]
if i<"0":x+=[c]
else:r+=c
if r:x+=[r]
print" ".join(x)


# Test

1+2
ONE plus TWO equals THREE
2-3
TWO minus THREE equals NEGATIVE ONE
6*2-4/1
SIX times TWO minus FOUR divided by ONE equals EIGHT
1+1-1*1/1
ONE plus ONE minus ONE times ONE divided by ONE equals ONE
2/3
TWO divided by THREE equals ZERO POINT SIX HUNDRED SIXTY-SEVEN
413-621
FOUR HUNDRED THIRTEEN minus SIX HUNDRED TWENTY-ONE equals NEGATIVE TWO HUNDRED EIGHTEEN
`