Skip to main content
edited tags
Link
200_success
  • 145.6k
  • 22
  • 191
  • 480
added 337 characters in body
Source Link

Does someone want to review my solution to part 1 of Day 7 Advent of Code in Scala? The assignment is here: http://adventofcode.com/day/7 Without repeating the whole text, in short:

The codeGiven a text file of the following form (simplified):

x AND y -> a
x -> 1
y -> 0

calculate the value of a. Here is herean example of a full input file.

My solution:

Does someone want to review my solution to part 1 of Day 7 Advent of Code in Scala?

The code is here:

Does someone want to review my solution to part 1 of Day 7 Advent of Code in Scala? The assignment is here: http://adventofcode.com/day/7 Without repeating the whole text, in short:

Given a text file of the following form (simplified):

x AND y -> a
x -> 1
y -> 0

calculate the value of a. Here is an example of a full input file.

My solution:

Source Link

Solution to part 1 of Day 7 Advent of Code in Scala

Does someone want to review my solution to part 1 of Day 7 Advent of Code in Scala?

The code is here:

import scala.io.Source

object Day7 {

  sealed trait Expr

  case class Variable(name: String) extends Expr

  case class Const(value: Int) extends Expr

  case class Not(expr: Expr) extends Expr

  case class And(left: Expr, right: Expr) extends Expr

  case class Or(left: Expr, right: Expr) extends Expr

  case class LShift(expr: Expr, by: Int) extends Expr

  case class RShift(expr: Expr, by: Int) extends Expr

  case class Assignment(v: Variable, expr: Expr) extends Expr

  case object Command {
    def parse(s: String): Assignment = {
      val assignmentRegex = """(.+) -> (.+)""".r
      def innerParse(s: String): Expr = {
        val rShiftRegex = """(\w+) RSHIFT (\d+)""".r
        val lShiftRegex = """(\w+) LSHIFT (\d+)""".r
        val orRegex = """(\w+) OR (\w+)""".r
        val andRegex = """(\w+) AND (\w+)""".r
        val notRegex = """NOT (\w+)""".r
        val constRegex = """(\d+)""".r
        val varRegex = """(\w+)""".r

        s match {
          case rShiftRegex(l, n) =>
            RShift(innerParse(l), n.toInt)
          case lShiftRegex(l, n) =>
            LShift(innerParse(l), n.toInt)
          case orRegex(l, r) =>
            Or(innerParse(l), innerParse(r))
          case andRegex(l, r) =>
            And(innerParse(l), innerParse(r))
          case notRegex(e) =>
            Not(innerParse(e))
          case constRegex(n) =>
            Const(n.toInt)
          case varRegex(n) =>
            Variable(n)
        }
      }
      s match {
        case assignmentRegex(l, r) => Assignment(Variable(r), innerParse(l))
        case _ => throw new Exception(s"Unrecognized command: $s")
      }
    }
  }

  class Environment(mappings: Map[String, Expr]) {

    val cache = new scala.collection.mutable.HashMap[Expr, Int]()

    private def eval(e: Expr): Int = {
      cache.get(e) match {
        case Some(i) => i
        case None => {
          val result = e match {
            case Variable(name) => {
              println(s"evaluating $name")
              eval(mappings(name))
            }
            case Const(value) => value
            case Not(expr) => ~eval(expr)
            case And(l, r) => eval(l) & eval(r)
            case Or(l, r) => eval(l) | eval(r)
            case LShift(expr, n) => eval(expr) << n
            case RShift(expr, n) => eval(expr) >> n
          }
          cache += (e -> result)
          result
        }
      }
    }

    def call(name: String): Int = {
      eval(mappings(name))
    }
  }

  def main(args: Array[String]) = {
    val lines = Source.fromFile("input-day7.txt").getLines()
    val x = lines.map(Command.parse).map((a) => a match {
      case Assignment(Variable(v), e) => (v -> e)
    })
    val m = x.toMap
    println(new Environment(m).call("a"))

  }

}