Guest User

Untitled

a guest
Jan 23rd, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.63 KB | None | 0 0
  1. import java.text.DecimalFormat
  2. import scala.io.StdIn._
  3. import scala.util.matching.Regex
  4.  
  5. object Main {
  6. import Parsers._
  7. import Model._
  8.  
  9. def main(args: Array[String]): Unit = {
  10. def number: Parser[Expr] = regex("\\d+".r).map(a => Num(a.toInt))
  11. def rand: Parser[Expr] = regex("d\\d+".r).map(a => Rand(a.tail.toInt))
  12. def literal: Parser[Expr] = number | rand
  13. def surround[A](p: Parser[A]): Parser[A] = string("(") ~> p ~< string(")")
  14.  
  15. def expr: Parser[Expr] = (gtExpr ~ many(string(">") ~ gtExpr)).map(a => listToBinary(a._1, a._2))
  16. def gtExpr: Parser[Expr] = (termExpr ~ many(string("+") ~ termExpr | string("-") ~ termExpr)).map(a => listToBinary(a._1, a._2))
  17. def termExpr: Parser[Expr] = (factorExpr ~ many(string("*") ~ factorExpr)).map(a => listToBinary(a._1, a._2))
  18. def factorExpr: Parser[Expr] = literal | surround(expr)
  19.  
  20. val s = readLine()
  21. printDistribution(eval(run(s, expr).get))
  22. }
  23.  
  24. def listToBinary(expr: Expr, operatorsWithExprs: List[(String, Expr)]): Expr = {
  25. operatorsWithExprs.foldLeft[Expr](expr) { case (acc, (op, e)) =>
  26. op match {
  27. case "*" => Mult(acc, e)
  28. case "+" => Plus(acc, e)
  29. case "-" => Minus(acc, e)
  30. case ">" => GT(acc, e)
  31. }
  32. }
  33. }
  34.  
  35. def printDistribution(distribution: Map[Int, Double]): Unit = {
  36. distribution.toList.sortBy(_._1).foreach { case (k, v) =>
  37. println(s"$k ${new DecimalFormat("0.00").format(v*100)}")
  38. }
  39. }
  40. }
  41.  
  42. object Parsers {
  43. def run[A](s: String, p: Parser[A]): Option[A] = p.repr(s) match {
  44. case (Some(a), "") => Some(a)
  45. case _ => None
  46. }
  47.  
  48. def runDebug[A](s: String, p: Parser[A]): (Option[A], String) = p.repr(s) match {
  49. case (result, s1) => (result, s1)
  50. }
  51.  
  52. case class Parser[A](repr: String => (Option[A], String)) {
  53. def map[B](f: A => B): Parser[B] = Parser(
  54. s => this.repr(s) match {
  55. case (None, _) => (None, s)
  56. case (Some(a), s1) => (Some(f(a)), s1)
  57. }
  58. )
  59. }
  60.  
  61. def sequence[A, B](p1: Parser[A], p2: =>Parser[B]): Parser[(A, B)] = {
  62. Parser(
  63. s => p1.repr(s) match {
  64. case (None, _) => (None, s)
  65. case (Some(a), s1) => p2.repr(s1) match {
  66. case (None, _) => (None, s)
  67. case (Some(b), s2) => (Some((a, b)), s2)
  68. }
  69. }
  70. )
  71. }
  72.  
  73. def many[A](p: Parser[A]): Parser[List[A]] = {
  74. sequence(p, many(p)).map(a => a._1 :: a._2) | succeed(List.empty)
  75. }
  76.  
  77. def many1[A](p: Parser[A]): Parser[List[A]] = {
  78. sequence(p, many(p)).map(a => a._1 :: a._2)
  79. }
  80.  
  81. def disjunction[A](p1: Parser[A], p2: =>Parser[A]): Parser[A] =
  82. Parser(
  83. s => p1.repr(s) match {
  84. case (None, _) => p2.repr(s) match {
  85. case (None, _) => (None, s)
  86. case (Some(a), s1) => (Some(a), s1)
  87. }
  88. case (Some(a), s1) => (Some(a), s1)
  89. }
  90. )
  91.  
  92. def succeed[A](a: A): Parser[A] = Parser(s => (Some(a), s))
  93.  
  94. def regex(r: Regex): Parser[String] =
  95. Parser(
  96. s => r.findPrefixOf(s) match {
  97. case None => (None, s)
  98. case Some(a) => (Some(a), s.drop(a.length))
  99. }
  100. )
  101.  
  102. def string(r: String): Parser[String] =
  103. Parser(
  104. s => if (s.startsWith(r)) (Some(r), s.drop(r.length)) else (None, s)
  105. )
  106.  
  107.  
  108. implicit class Ops[A](parser: Parser[A]) {
  109. def ~[B](other: =>Parser[B]): Parser[(A, B)] = sequence(parser, other)
  110. def ~>[B](other: =>Parser[B]): Parser[B] = sequence(parser, other).map(a => a._2)
  111. def ~<[B](other: =>Parser[B]): Parser[A] = sequence(parser, other).map(a => a._1)
  112. def |(other: =>Parser[A]): Parser[A] = disjunction(parser, other)
  113. }
  114. }
  115.  
  116. object Model {
  117. sealed abstract class Expr
  118. case class Num(a: Int) extends Expr
  119. case class Rand(a: Int) extends Expr
  120. case class Mult(a: Expr, b: Expr) extends Expr
  121. case class Plus(a: Expr, b: Expr) extends Expr
  122. case class Minus(a: Expr, b: Expr) extends Expr
  123. case class GT(a: Expr, b: Expr) extends Expr
  124.  
  125. def eval(e: Expr): Map[Int, Double] = {
  126. e match {
  127. case Num(a) => Map(a -> 1.0)
  128. case Rand(a) => Vector.tabulate(a)(i => (i + 1) -> 1.0 / a).toMap
  129. case Mult(a, b) => combineDistributions(eval(a), eval(b), _ * _)
  130. case Plus(a, b) => combineDistributions(eval(a), eval(b), _ + _)
  131. case Minus(a, b) => combineDistributions(eval(a), eval(b), _ - _)
  132. case GT(a, b) => combineDistributions(eval(a), eval(b), (x, y) => if (x > y) 1 else 0)
  133. }
  134. }
  135.  
  136. def combineDistributions(a: Map[Int, Double], b: Map[Int, Double], op: (Int, Int) => Int): Map[Int, Double] = {
  137. var res = Map.empty[Int, Double]
  138. val denormCoef = 0.0
  139. for ((k1, v1) <- a) {
  140. for ((k2, v2) <- b) {
  141. val k = op(k1, k2)
  142. val v = v1 * v2
  143. res += k -> (v + res.getOrElse(k, 0.0))
  144. }
  145. }
  146. res
  147. }
  148. }
Add Comment
Please, Sign In to add comment