Created
August 29, 2014 19:59
-
-
Save rokon12/f7a048d20d1db717e4d6 to your computer and use it in GitHub Desktop.
Command line scala postfix expression evaluator Input: "1 2 + 3 4 5 - - * 6 7 8 - * /" * Output: (((8 - 7) * 6) / (((5 - 4) - 3) * (2 + 1))) = -1 * */
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package calculator | |
import java.util.Stack | |
/** | |
* Created by Bazlur Rahman Rokon on 8/29/14. | |
*/ | |
object Calculator { | |
trait Operator { | |
def operate(lhs: Int, rhs: Int): Int | |
} | |
object Operator { | |
val operators: Map[String, Operator] = | |
Map("+" -> Add, "-" -> Substract, "*" -> Multiply, "/" -> Divide) | |
def unapply(token: String): Option[Operator] = | |
operators.get(token) | |
} | |
case object Add extends Operator { | |
override def operate(lhs: Int, rhs: Int): Int = lhs + rhs | |
override val toString = "+" | |
} | |
case object Substract extends Operator { | |
override def operate(lhs: Int, rhs: Int): Int = lhs - rhs | |
override val toString = "-" | |
} | |
case object Multiply extends Operator { | |
override def operate(lhs: Int, rhs: Int): Int = lhs * rhs | |
override val toString = "*" | |
} | |
case object Divide extends Operator { | |
override def operate(lhs: Int, rhs: Int): Int = lhs / rhs | |
override val toString = "/" | |
} | |
object Number { | |
def unapply(token: String): Option[Int] = try { | |
Some(token.toInt) | |
} catch { | |
case _: NumberFormatException => None | |
} | |
} | |
sealed trait Expression | |
case class NumberExpression(value: Int) extends Expression | |
case class OperationExpression(lhs: Expression, rhs: Expression, op: Operator) extends Expression | |
def parse(expression: String): Expression = { | |
val stack: Stack[Expression] = new Stack[Expression] | |
for (token <- expression.split(" ")) token match { | |
case Number(num) => stack.push(NumberExpression(num)) | |
case Operator(op) => | |
val lsh = stack.pop() | |
val rhs = stack.pop() | |
stack.push(OperationExpression(lsh, rhs, op)) | |
case _ => throw new IllegalArgumentException("Invalid token: " + token) | |
} | |
stack.pop() | |
} | |
def calculate(expression: Expression): Int = expression match { | |
case NumberExpression(value) => value | |
case OperationExpression(lhs, rhs, op) => op.operate(calculate(lhs), calculate(rhs)) | |
} | |
def toInfix(expression: Expression): String = expression match { | |
case NumberExpression(value) => value.toString | |
case OperationExpression(lhs, rhs, op) => s"(${toInfix(lhs)} $op ${toInfix(rhs)})" | |
} | |
/** | |
* Command line scala postfix expression evaluator | |
* | |
* Input: "1 2 + 3 4 5 - - * 6 7 8 - * /" | |
* Output: (((8 - 7) * 6) / (((5 - 4) - 3) * (2 + 1))) = -1 | |
* | |
* @param args | |
*/ | |
def main(args: Array[String]) { | |
if (args.length != 1) { | |
throw new IllegalArgumentException("Usage: Calculator <expression>") | |
} else { | |
val expression = parse(args(0)) | |
println(s"${toInfix(expression)} = ${calculate(expression)}") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment