Sort by

recency

|

11 Discussions

|

  • + 0 comments

    scala:

    object Solution {
      private val mod = (1e9 + 7).toLong
      private type ArithmeticOp = (BigInt, BigInt) => BigInt
    
      private abstract class Token(repr: String) {
        override def toString() = repr
      }
      private final case class Number(s: String) extends Token(s) {
        def toBigInt: BigInt = BigInt(s)
      }
      private final case object LeftParen extends Token("(")
      private final case object RightParen extends Token(")")
      private abstract class Operator(repr: String, val eval: ArithmeticOp) extends Token(repr)
      private abstract class MultiplicativeOperator(repr: String, eval: ArithmeticOp) extends Operator(repr, eval)
      private final case object Multiply extends MultiplicativeOperator("*", _ * _)
      private final case object Divide extends MultiplicativeOperator("/", _ * _.modInverse(mod))
      private abstract class UnaryOperator(repr: String, eval: ArithmeticOp) extends Operator(repr, eval) {
        def eval(num: BigInt): BigInt = eval(0, num)
      }
      private final case object Plus extends UnaryOperator("+", _ + _)
      private final case object Minus extends UnaryOperator("-", _ - _)
    
      private class UnknownToken(t: Char) extends RuntimeException(s"unknown token `$t`")
      private class UnexpectedToken(ts: List[Token]) extends RuntimeException(s"unexpected token `${ts.mkString}`")
      private class UnexpectedEndOfExpression extends RuntimeException("unexpected end of expression")
    
      private def tokenize(expression: String): List[Token] = {
        expression
          .replace(" ", "")
          .foldLeft(List.empty[Token]) {
            case (acc, '+') => Plus :: acc
            case (acc, '-') => Minus :: acc
            case (acc, '*') => Multiply :: acc
            case (acc, '/') => Divide :: acc
            case (acc, '(') => LeftParen :: acc
            case (acc, ')') => RightParen :: acc
            case (acc, c) if c.isDigit || '.' == c =>
              acc match {
                case (Number(s) :: tail) =>
                  Number(s + c) :: tail
                case _ =>
                  Number(c.toString) :: acc
              }
            case (acc, token) => throw new UnknownToken(token)
          }
          .reverse
      }
    
      private def dropRightParen(tokens: List[Token]): List[Token] = {
        tokens match {
          case RightParen :: tail => tail
          case _                  => throw new UnexpectedEndOfExpression
        }
      }
      // Expression ::= Term [+-] Expression
      //              | Term
      private def evaluateExpression(tokens: List[Token]): (BigInt, List[Token]) = {
        evaluateTerm(tokens) match {
          case (term, (op: UnaryOperator) :: tail) =>
            val (expression, remaining) = evaluateExpression(tail)
            op.eval(term, expression) -> remaining
          case (term, remaining) =>
            term -> remaining
        }
      }
    
      // Term ::= Factor [*/] Term
      //        | Factor
      private def evaluateTerm(tokens: List[Token]): (BigInt, List[Token]) = {
        evaluateFactor(tokens) match {
          case (factor, (op: MultiplicativeOperator) :: tail) =>
            val (term, remaining) = evaluateTerm(tail)
            op.eval(factor, term) -> remaining
          case (factor, remaining) =>
            factor -> remaining
        }
      }
    
      // Factor ::= Number
      //          | [+-] Factor
      //          | '(' Expression ')'
      private def evaluateFactor(tokens: List[Token]): (BigInt, List[Token]) = {
        tokens match {
          case (number: Number) :: remaining =>
            number.toBigInt -> remaining
          case (op: UnaryOperator) :: tail =>
            val (factor, remaining) = evaluateFactor(tail)
            op.eval(factor) -> remaining
          case LeftParen :: tail =>
            val (expression, remaining) = evaluateExpression(tail)
            expression -> dropRightParen(remaining)
          case _ =>
            throw new UnexpectedToken(tokens)
        }
      }
    
      def main(args: Array[String]): Unit = {
        val in = Iterator
          .continually(io.StdIn.readLine())
          .takeWhile(null != _)
          .map(_.trim)
        val expression = in.next()
        val tokens = tokenize(expression)
        val (outcome, remaining) = evaluateExpression(tokens)
        if (remaining.nonEmpty)
          throw new UnexpectedToken(remaining)
        println(outcome.mod(mod))
      }
    }
    
  • [deleted]
    + 0 comments

    I think this problem might not be tagged as Expert

  • + 1 comment

    Sorry for my perhaps naive question.

    When I compute 10^(p-2) using fast modular exponentiation as suggested by the challenge author I do not get the expected result of 700000005. My code for fast modular exponentiation is below (no spoiler here since it is a word for word rendering of the challenge author's own suggestion as he himself posted):

    let rec modexp x y =
      if y=0. then 1.
      else
        let z=modexp x (floor (y/.2.)) in
            if (mod_float y 2. =0.) then  mod_p  (z ** 2.)
            else mod_p (x *. (z** 2.))
            
    let mod_p a =
      mod_float ((mod_float a p) +. p) p
      
    let p = 10. ** 9. +. 7.
    

    Indeed, the reported result for modexp 10. (p-.2.) is 485926138.

    Can someone point me in the right direction? Thank you!

  • [deleted]
    + 0 comments

    AC using SLR(1) and LL(1) Parsing

  • + 0 comments

    I hate to boast, but this should not be classified as 'Expert' : solved in 2 hours flat :D