Problem:
小学生のイクタ君は、ある日おじいさんから数式が書かれた紙をもらった。
どうやらおじいさんは数式の答えの金額だけお小遣いをくれるらしい。
イクタ君はまだ足し算、引き算、掛け算しか習ってなかったので、数式にも足し算と引き算と掛け算しか使われていない。
通常の計算では足し算と引き算より掛け算を先に計算しなければならないのだが、イクタ君は演算子の優先順位についての理解があやふやだったので、とりあえず数式の計算結果が最大になるような都合の良い優先順位を考えることにした。

+−×の3つの二項演算子と括弧を含む数式が与えられる。
3つの演算子の優先順位を任意に変更して、数式を最大化したときの計算結果を答えよ。

ただし、以下の点に注意せよ。

演算子は必ず左結合である。
(同じ優先順位の演算子は必ず数式の左側から計算する。)

異なる演算子が同じ優先順位であってもよい。

一つの数式を計算している途中で優先順位を変更してはならない。

Input

入力は以下の形式で与えられる。

0〜9の数字と演算子'+','-','*'、括弧'(',')'で構成された数式

正確に記述すると入力は以下のBNFで示される形式になっている

<expr> ::= ( <expr> ) | <number> | <expr> <op> <expr>
<op> ::= + | - | *

<number>は非負整数を表す。

Constraints

入力は以下の制約を満たす。

数式は200文字以下である。

どのような優先順位を設定しても、計算の結果やその途中で64bit整数型でoverflowするようなことはない。

Output

数式から得られる最大値を1行で出力せよ。

Sample Input 1

3-2*3

Output for the Sample Input 1

3

*の優先順位を-より低くすることでこのようになる。

Sample Input 2

(5-3*4)*(0-2+1)

Output for the Sample Input 2

21

優先順位は+>*>-

Sample Input 3

1-2+3-4+5-6*0

Output for the Sample Input 3

3

優先順位が一般的な場合

Sample Input 4

(1989967-3*1-211+4487)

Output for the Sample Input 4

8511076028

Solution in Scala (judge verdict: Accepted)

import scala.io.StdIn._
object Main extends App {
  readLine.trim match {
    case Expression(e) ⇒
      println(math.max(e.execute(Operator(Plus, Minus, Times), Operator(Plus), Operator(Plus)), Array(Operator(Plus), Operator(Minus), Operator(Times)).permutations.flatMap{case Array(p, n, s) ⇒ Array(e.execute(p, n, s), e.execute(p + n, n, s), e.execute(p, n + s, s))}.max))
    case _ ⇒ ???
  }
}
object Expression {
  def unapply(arg: String): Option[Expression] = {
    arg.toList match {
      case f Formula Nil ⇒ Some(Expression(f))
      case _ ⇒ ???
    }
  }
  object Num {
    def unapply(arg: List[Char]): Option[(Number, List[Char])] = {
      arg.span(_.isDigit) match {
        case (Nil, _) ⇒ None
        case (h, t) ⇒ Some(Number(h.foldLeft(0L){case (acc, r) ⇒ acc * 10 + r.asDigit}), t)
      }
    }
  }
  object Formula {
    def unapply(arg: List[Char]): Option[(Expr, List[Char])] = {
      arg match {
        case n Num r ⇒
          r match {
            case '+'::(m Formula rest) ⇒ Some(Expr(n, Succ(Plus, m)), rest)
            case '-'::(m Formula rest) ⇒ Some(Expr(n, Succ(Minus, m)), rest)
            case '*'::(m Formula rest) ⇒ Some(Expr(n, Succ(Times, m)), rest)
            case _ ⇒ Some((Expr(n, End), r))
          }
        case '('::(f Formula ')'::r) ⇒
          r match {
            case '+'::(m Formula rest) ⇒ Some(Expr(Bracket(Expression(f)), Succ(Plus, m)), rest)
            case '-'::(m Formula rest) ⇒ Some(Expr(Bracket(Expression(f)), Succ(Minus, m)), rest)
            case '*'::(m Formula rest) ⇒ Some(Expr(Bracket(Expression(f)), Succ(Times, m)), rest)
            case _ ⇒ Some((Expr(Bracket(Expression(f)), End), r))
          }
        case _ ⇒ None
      }
    }
  }
}

object Operator {
  def apply(operator: BiOp*): Operator = new Operator(operator)
}
class Operator(val operator: Seq[BiOp]) {
  def unapply(op: BiOp): Option[(Long ⇒ Long ⇒ Long)] = {
    Some(op).filter(operator.contains)
  }
  def +(that: Operator): Operator = new Operator(operator ++ that.operator)
}
case class Expression(expr: Expr) {
  def execute(priOp: Operator, norOp: Operator, subOp: Operator): Long = {
    expr.flatten(priOp, norOp, subOp).calculate(priOp, norOp, subOp)
  }
}
case class FExpr(head: Long, tail: FExprT) {
  def calculate(priOp: Operator, norOp: Operator, subOp: Operator): Long = consume(consume(consume(this, priOp), norOp), subOp) match {
    case head FExpr FEnd ⇒ head
    case _ ⇒ ???
  }
  private def consume(expr: FExpr, operator: Operator): FExpr = {
    expr match {
      case left FExpr (operator(op) FSucc (right FExpr rest)) ⇒ consume(FExpr(op(left)(right), rest), operator)
      case head FExpr (op FSucc rest) ⇒ FExpr(head, FSucc(op, consume(rest, operator)))
      case _ ⇒ expr
    }
  }
}
sealed trait FExprT
case class FSucc(op: BiOp, tail: FExpr) extends FExprT
case object FEnd extends FExprT

case class Expr(head: Factor, tail: ExprT) {
  def flatten(priOp: Operator, norOp: Operator, subOp: Operator): FExpr = {
    head match {
      case Bracket(expr) ⇒ FExpr(expr.execute(priOp, norOp, subOp), tail.flatten(priOp: Operator, norOp: Operator, subOp: Operator))
      case Number(value) ⇒ FExpr(value, tail.flatten(priOp: Operator, norOp: Operator, subOp: Operator))
    }
  }
}
sealed trait ExprT {
  def flatten(priOp: Operator, norOp: Operator, subOp: Operator): FExprT = {
    this match {
      case End ⇒ FEnd
      case op Succ tail ⇒ FSucc(op, tail.flatten(priOp, norOp, subOp))
    }
  }
}
case class Succ(op: BiOp, tail: Expr) extends ExprT
case object End extends ExprT

sealed trait Factor
case class Bracket(expr: Expression) extends Factor
case class Number(value: Long) extends Factor

sealed trait BiOp extends (Long ⇒ Long ⇒ Long)
case object Plus extends BiOp {
  override def apply(v1: Long): Long ⇒ Long = v1.+
}
case object Minus extends BiOp {
  override def apply(v1: Long): Long ⇒ Long = v1.-
}
case object Times extends BiOp  {
  override def apply(v1: Long): Long ⇒ Long = v1.*
}