patternMinor
Solution to part 1 of Day 7 Advent of Code in Scala
Viewed 0 times
adventpartscalacodesolutionday
Problem
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):
calculate the value of a. Here is an example of a full input file.
My solution:
```
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")
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 -> 0calculate the value of a. Here is an example of a full input file.
My solution:
```
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")
Solution
It seems to me that your general approach is solid. One small change I noticed you could make would be to move the
Regex declarations outside of the functions parse and innerParse. The reason for doing this is that it is expensive to compile the Regexs with every call to these functions. By moving them out we only construct them once. This is supported by the Scala Regex documentation which can be read here.case object Command {
val assignmentRegex = """(.+) -> (.+)""".r
val rShiftRegex = """(\w+) RSHIFT (\d+)""".r
val lShiftRegex = """(\w+) LSHIFT (\d+)""".r
val constRegex = """(\d+)""".r
val varRegex = """(\w+)""".r
val notRegex = """NOT (\w+)""".r
val andRegex = """(\w+) AND (\w+)""".r
val orRegex = """(\w+) OR (\w+)""".r
def parse(s: String): Assignment = {
def innerParse(s: String): Expr = {
// ...
}
// ...
}
// ...
}Code Snippets
case object Command {
val assignmentRegex = """(.+) -> (.+)""".r
val rShiftRegex = """(\w+) RSHIFT (\d+)""".r
val lShiftRegex = """(\w+) LSHIFT (\d+)""".r
val constRegex = """(\d+)""".r
val varRegex = """(\w+)""".r
val notRegex = """NOT (\w+)""".r
val andRegex = """(\w+) AND (\w+)""".r
val orRegex = """(\w+) OR (\w+)""".r
def parse(s: String): Assignment = {
def innerParse(s: String): Expr = {
// ...
}
// ...
}
// ...
}Context
StackExchange Code Review Q#113719, answer score: 2
Revisions (0)
No revisions yet.