Add days 8 and 9
This commit is contained in:
parent
a6a7daf29e
commit
cf0b23d5a5
3 changed files with 160 additions and 2 deletions
|
@ -1,5 +1,121 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
object Day08 {
|
import aoc.Day
|
||||||
|
|
||||||
|
object Day08 extends Day {
|
||||||
|
|
||||||
|
import fastparse._, NoWhitespace._
|
||||||
|
|
||||||
|
sealed trait Instruction {
|
||||||
|
def result(regValue: Int, input: Int): Int
|
||||||
|
}
|
||||||
|
case object Dec extends Instruction {
|
||||||
|
override def result(regValue: Int, input: Int): Int = regValue - input
|
||||||
|
}
|
||||||
|
case object Inc extends Instruction {
|
||||||
|
override def result(regValue: Int, input: Int): Int = regValue + input
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed trait Test {
|
||||||
|
def result(regValue: Int, input: Int): Boolean
|
||||||
|
}
|
||||||
|
case object Lt extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue < input
|
||||||
|
}
|
||||||
|
case object Gt extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue > input
|
||||||
|
}
|
||||||
|
case object Leq extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue <= input
|
||||||
|
}
|
||||||
|
case object Geq extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue >= input
|
||||||
|
}
|
||||||
|
case object Eq extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue == input
|
||||||
|
}
|
||||||
|
case object Neq extends Test {
|
||||||
|
override def result(regValue: Int, input: Int): Boolean = regValue != input
|
||||||
|
}
|
||||||
|
|
||||||
|
case class FullInstruction(reg: String, op: Instruction, v: Int)
|
||||||
|
case class FullTest(reg: String, op: Test, v: Int)
|
||||||
|
case class Line(i: FullInstruction, t: FullTest)
|
||||||
|
|
||||||
|
def registerParser[_: P] = P(CharIn("a-z").rep(1).!)
|
||||||
|
def numberParser[_: P] = P(("-".? ~ CharIn("0-9").rep(1)).!).map(_.toInt)
|
||||||
|
def instructionParser[_: P] = P(("inc" | "dec").!).map {
|
||||||
|
case "inc" => Inc
|
||||||
|
case "dec" => Dec
|
||||||
|
}
|
||||||
|
def testParser[_: P] = P(("<=" | ">=" | "<" | ">" | "==" | "!=").!).map {
|
||||||
|
case "<" => Lt
|
||||||
|
case ">" => Gt
|
||||||
|
case "<=" => Leq
|
||||||
|
case ">=" => Geq
|
||||||
|
case "==" => Eq
|
||||||
|
case "!=" => Neq
|
||||||
|
}
|
||||||
|
def fullInstructionParser[_: P] = P(registerParser ~ " " ~ instructionParser ~ " " ~ numberParser).map {
|
||||||
|
case (reg, op, v) => FullInstruction(reg, op, v)
|
||||||
|
}
|
||||||
|
def fullTestParser[_: P] = P(registerParser ~ " " ~ testParser ~ " " ~ numberParser).map {
|
||||||
|
case (reg, op, v) => FullTest(reg, op, v)
|
||||||
|
}
|
||||||
|
def lineParser[_: P] = P(fullInstructionParser ~ " if " ~ fullTestParser).map {
|
||||||
|
case (i, t) => Line(i, t)
|
||||||
|
}
|
||||||
|
def listParser[_: P] = P(lineParser.rep(1, "\n")).map(_.toList)
|
||||||
|
|
||||||
|
def getProgram(input: String): List[Line] = {
|
||||||
|
val Parsed.Success(list, _) = parse(input, listParser(_))
|
||||||
|
list
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part1(input: String): String = {
|
||||||
|
val list = getProgram(input)
|
||||||
|
val allRegs = (list.map(_.i.reg) ++ list.map(_.t.reg)).distinct
|
||||||
|
val regMap: Map[String, Int] = allRegs.map(r => (r, 0)).toMap
|
||||||
|
val o = list.foldLeft(regMap)((map, cl) => {
|
||||||
|
print(s"\r$cl")
|
||||||
|
val testReg = map(cl.t.reg)
|
||||||
|
val test = cl.t.op
|
||||||
|
val v = cl.t.v
|
||||||
|
if(test.result(testReg, v)) {
|
||||||
|
val inReg = map(cl.i.reg)
|
||||||
|
val in = cl.i.op
|
||||||
|
val iv = cl.i.v
|
||||||
|
map + (cl.i.reg -> in.result(inReg, iv))
|
||||||
|
} else {
|
||||||
|
map
|
||||||
|
}
|
||||||
|
})
|
||||||
|
println()
|
||||||
|
o.values.max.toString
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part2(input: String): String = {
|
||||||
|
val list = getProgram(input)
|
||||||
|
val allRegs = (list.map(_.i.reg) ++ list.map(_.t.reg)).distinct
|
||||||
|
val regMap: Map[String, Int] = allRegs.map(r => (r, 0)).toMap
|
||||||
|
val (_, max) = list.foldLeft((regMap, 0)) {
|
||||||
|
case ((map, hm), cl) =>
|
||||||
|
print(s"\r$cl")
|
||||||
|
val testReg = map(cl.t.reg)
|
||||||
|
val test = cl.t.op
|
||||||
|
val v = cl.t.v
|
||||||
|
val inReg = map(cl.i.reg)
|
||||||
|
if (test.result(testReg, v)) {
|
||||||
|
val in = cl.i.op
|
||||||
|
val iv = cl.i.v
|
||||||
|
val nv = in.result(inReg, iv)
|
||||||
|
(map + (cl.i.reg -> nv), Math.max(hm, nv))
|
||||||
|
} else {
|
||||||
|
(map, Math.max(hm, inReg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
max.toString
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,45 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
object Day09 {
|
import aoc.Day
|
||||||
|
|
||||||
|
object Day09 extends Day {
|
||||||
|
|
||||||
|
import fastparse._, MultiLineWhitespace._
|
||||||
|
|
||||||
|
sealed trait Elem {
|
||||||
|
def score(level: Int = 1): Int
|
||||||
|
def garbageCount: Int
|
||||||
|
}
|
||||||
|
case class Group(contents: List[Elem]) extends Elem {
|
||||||
|
override def score(level: Int = 1): Int = level + contents.map(_.score(level + 1)).sum
|
||||||
|
override def garbageCount: Int = contents.map(_.garbageCount).sum
|
||||||
|
}
|
||||||
|
case class Garbage(contents: String) extends Elem {
|
||||||
|
override def score(level: Int = 1): Int = 0
|
||||||
|
override def garbageCount: Int = {
|
||||||
|
val r = """!.""".r
|
||||||
|
contents.length - (r.findAllIn(contents).length * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def elemParser[_: P]: P[Elem] = P(groupParser | garbageParser)
|
||||||
|
def groupParser[_: P]: P[Group] = P("{" ~/ elemParser.rep(0, ","./) ~ "}").map(c => Group(c.toList))
|
||||||
|
def garbageCharacterParser[_: P]: P[Unit] = P(("!".? ~ CharIn("""aeiou"'<{,}""")) | "!>" | "!!")./
|
||||||
|
def garbageParser[_: P]: P[Garbage] = P("<" ~/ garbageCharacterParser.rep.! ~ ">").map(s => Garbage(s))
|
||||||
|
|
||||||
|
def getElem(input: String): Elem = {
|
||||||
|
val Parsed.Success(e, _) = parse(input, elemParser(_))
|
||||||
|
e
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part1(input: String): String = {
|
||||||
|
val e = getElem(input)
|
||||||
|
e.score().toString
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part2(input: String): String = {
|
||||||
|
val e = getElem(input)
|
||||||
|
e.garbageCount.toString
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ package object y2017 extends Year {
|
||||||
"5" -> Day05,
|
"5" -> Day05,
|
||||||
"6" -> Day06,
|
"6" -> Day06,
|
||||||
"7" -> Day07,
|
"7" -> Day07,
|
||||||
|
"8" -> Day08,
|
||||||
|
"9" -> Day09,
|
||||||
"25" -> Day25
|
"25" -> Day25
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue