## RPN Calculator (using Scala, python and Java)

1. Description

One of the earliest Programming Praxis challenges is called RPN Calculator . Our task is to write a RPN module capable of evaluating simple RPN expressions and return the right result . The exact requirment:

Implement an RPN calculator that takes an expression likeĀ `19 2.14 + 4.5 2 4.3 / - *` which is usually expressed asĀ `(19 + 2.14) * (4.5 - 2 / 4.3)` and responds with 85.2974. The program should read expressions from standard input and print the top of the stack to standard output when a newline is encountered. The program should retain the state of the operand stack between expressions.

Programming Praxis

The natural algorithm to resolve this exercise is stack-based :

 The first step is to tokenize the expression .If the expression is “19 2.14 + 4.5 2 4.3 / – *” after the tokenization the resulting structure will be an array of operands and operators, for example an array of Strings {“19”, “2.14”, “+”, “4.5”, “2”, “4.3”, “/”, “-“, “*”} . At the second step we iterate over the array of tokens .If the token: Is an operand (number, variable) – we push in onto the stack . Is an operator (we apriopri know the operator takes N arguments), we pop N values from the stack, we evaluate the operator with those values as input parameters, we push the result back onto the stack . If the RPN expression is valid, after we apply the previous steps, the stack would contain only one value, which is the result of the calculation .

2. Implementation

I will implement the solutions for this challenge using three different languages: Scala, python and Java .

2.1 Scala Solution

```import scala.collection.mutable.Stack
import scala.io.Source
import java.lang.Double.parseDouble

/**
* RPN Calculator .
*
* @author Andrei Ciobanu
* @date JAN 2, 2011
**/

object RPNCalc {
// Maps an operator to a function .
val ops = Map("+" -> ((_:Double) + (_:Double)),
"-" -> (-(_:Double) + (_:Double)),
"*" -> ((_:Double) * (_:Double)),
"/" -> (1/(_:Double) * (_:Double)))

// Evaluate RPN expr (given as string of tokens)
def evalTokens(tokens: Array[String]) : Double = {
val stack = new Stack[Double]
tokens.foreach(tok => {
if (ops.contains(tok)) stack.push(ops(tok)(stack.pop, stack.pop))
else stack.push(parseDouble(tok))
})
stack.pop
}

// Main  function
def main(args: Array[String]) = {
// Read line by line from stdin + tokenize line + evaluates line
Source.fromInputStream(System.in).getLines.foreach(l =>
printf("exp=%2.2fn", evalTokens(l.split(" "))))
}
}
```

And if we compile and run the above code: