Year 2016
This commit is contained in:
parent
b40328ee5d
commit
f5b37afa96
|
@ -5,7 +5,8 @@ import scala.io.StdIn
|
||||||
object Main {
|
object Main {
|
||||||
|
|
||||||
val years = Map(
|
val years = Map(
|
||||||
"2017" -> y2017.get
|
"2016" -> y2016.!,
|
||||||
|
"2017" -> y2017.!,
|
||||||
)
|
)
|
||||||
|
|
||||||
def main(args: Array[String]): Unit = {
|
def main(args: Array[String]): Unit = {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package aoc
|
||||||
|
|
||||||
trait Year {
|
trait Year {
|
||||||
|
|
||||||
|
def !(): this.type = this
|
||||||
|
|
||||||
def days: Map[String, Day]
|
def days: Map[String, Day]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package object aoc {
|
||||||
|
|
||||||
|
def rotateLeft[A](list: List[A], i: Int): List[A] = {
|
||||||
|
val size = list.size
|
||||||
|
list.drop(i % size) ++ list.take(i % size)
|
||||||
|
}
|
||||||
|
|
||||||
|
def rotateRight[A](list: List[A], i: Int): List[A] = {
|
||||||
|
val size = list.size
|
||||||
|
list.drop(size - (i % size)) ++ list.take(size - (i % size))
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit class TupleInt2Ops(t: (Int, Int)) {
|
||||||
|
|
||||||
|
def +(o: (Int, Int)): (Int, Int) = (t, o) match {
|
||||||
|
case ((x1, y1), (x2, y2)) => (x1 + x2, y1 + y2)
|
||||||
|
}
|
||||||
|
|
||||||
|
def *(m: Int): (Int, Int) = t match {
|
||||||
|
case (a, b) => (a * m, b * m)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package aoc.y2016
|
||||||
|
|
||||||
|
import aoc._
|
||||||
|
|
||||||
|
object Day01 extends Day {
|
||||||
|
|
||||||
|
import fastparse._, SingleLineWhitespace._
|
||||||
|
|
||||||
|
sealed trait Direction {
|
||||||
|
def score: (Int, Int)
|
||||||
|
}
|
||||||
|
case object MoveUp extends Direction {
|
||||||
|
override def score: (Int, Int) = (0, 1)
|
||||||
|
}
|
||||||
|
case object MoveDown extends Direction {
|
||||||
|
override def score: (Int, Int) = (0, -1)
|
||||||
|
}
|
||||||
|
case object MoveLeft extends Direction {
|
||||||
|
override def score: (Int, Int) = (-1, 0)
|
||||||
|
}
|
||||||
|
case object MoveRight extends Direction {
|
||||||
|
override def score: (Int, Int) = (1, 0)
|
||||||
|
}
|
||||||
|
case class State(currentDirection: Direction = MoveUp, distance: (Int, Int) = (0, 0))
|
||||||
|
sealed trait Turn {
|
||||||
|
def apply(d: Direction): Direction
|
||||||
|
}
|
||||||
|
case object TurnLeft extends Turn {
|
||||||
|
override def apply(d: Direction): Direction = d match {
|
||||||
|
case MoveUp => MoveLeft
|
||||||
|
case MoveLeft => MoveDown
|
||||||
|
case MoveDown => MoveRight
|
||||||
|
case MoveRight => MoveUp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case object TurnRight extends Turn {
|
||||||
|
override def apply(d: Direction): Direction = d match {
|
||||||
|
case MoveUp => MoveRight
|
||||||
|
case MoveRight => MoveDown
|
||||||
|
case MoveDown => MoveLeft
|
||||||
|
case MoveLeft => MoveUp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case class Move(t: Turn, l: Int)
|
||||||
|
|
||||||
|
val tMap = Map(
|
||||||
|
"L" -> TurnLeft,
|
||||||
|
"R" -> TurnRight
|
||||||
|
)
|
||||||
|
|
||||||
|
def timesParser[_: P]: P[Int] = P(CharIn("0-9").rep(1).!).map(_.toInt)
|
||||||
|
def directionParser[_: P]: P[Turn] = P(("L" | "R").!).map(tMap)
|
||||||
|
def moveParser[_: P]: P[Move] = P(directionParser ~ timesParser).map { case (t, l) => Move(t, l) }
|
||||||
|
def movesParser[_: P]: P[List[Move]] = P(moveParser.rep(1, ","./)).map(_.toList)
|
||||||
|
|
||||||
|
def getMoves(input: String): List[Move] = {
|
||||||
|
val Parsed.Success(moves, _) = parse(input, movesParser(_))
|
||||||
|
moves
|
||||||
|
}
|
||||||
|
|
||||||
|
def distance(s: State): Int = {
|
||||||
|
val (x, y) = s.distance
|
||||||
|
val (dx, dy) = (Math.abs(x), Math.abs(y))
|
||||||
|
dx + dy
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part1(input: String): String = {
|
||||||
|
val moves = getMoves(input)
|
||||||
|
val endingState = moves.foldLeft(State())((s, m) => {
|
||||||
|
val nd = m.t(s.currentDirection)
|
||||||
|
val ns = nd.score * m.l
|
||||||
|
State(nd, s.distance + ns)
|
||||||
|
})
|
||||||
|
distance(endingState).toString
|
||||||
|
}
|
||||||
|
|
||||||
|
override def part2(input: String): String = {
|
||||||
|
val moves = getMoves(input)
|
||||||
|
def firstRepeat(
|
||||||
|
m: List[Move],
|
||||||
|
startingState: State = State(),
|
||||||
|
carryOutRotate: Boolean = true,
|
||||||
|
seen: List[(Int, Int)] = List()
|
||||||
|
): State = {
|
||||||
|
val thisMove = m.head
|
||||||
|
val nd = if (carryOutRotate) {
|
||||||
|
thisMove.t(startingState.currentDirection)
|
||||||
|
} else {
|
||||||
|
startingState.currentDirection
|
||||||
|
}
|
||||||
|
val ns = startingState.distance + nd.score
|
||||||
|
print(s"\r(${ns._1}, ${ns._2}) ")
|
||||||
|
val ss = State(nd, ns)
|
||||||
|
if (seen.contains(ns)) {
|
||||||
|
ss
|
||||||
|
} else {
|
||||||
|
val xw = thisMove.l == 1
|
||||||
|
val nm = if (xw) {
|
||||||
|
m.drop(1)
|
||||||
|
} else {
|
||||||
|
Move(thisMove.t, thisMove.l - 1) +: m.drop(1)
|
||||||
|
}
|
||||||
|
firstRepeat(nm, ss, xw, seen :+ ns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val rs = firstRepeat(moves)
|
||||||
|
println()
|
||||||
|
distance(rs).toString
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package aoc
|
||||||
|
|
||||||
|
package object y2016 extends Year {
|
||||||
|
|
||||||
|
override def days: Map[String, Day] = Map(
|
||||||
|
"1" -> Day01
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
import aoc.Day
|
import aoc._
|
||||||
|
|
||||||
object Day03 extends Day {
|
object Day03 extends Day {
|
||||||
|
|
||||||
|
|
|
@ -29,24 +29,20 @@ object Day05 extends Day {
|
||||||
}
|
}
|
||||||
|
|
||||||
override def part1(input: String): String = {
|
override def part1(input: String): String = {
|
||||||
implicit val stepper: Stepper = new Stepper {
|
implicit val stepper: Stepper = (p: Program) => {
|
||||||
def step(p: Program): Program = {
|
val instruction = p.instructions(p.index)
|
||||||
val instruction = p.instructions(p.index)
|
val newList = p.instructions.updated(p.index, instruction + 1)
|
||||||
val newList = p.instructions.updated(p.index, instruction + 1)
|
Program(newList, p.index + instruction)
|
||||||
Program(newList, p.index + instruction)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
countSteps(getStartingProgram(input)).toString
|
countSteps(getStartingProgram(input)).toString
|
||||||
}
|
}
|
||||||
|
|
||||||
override def part2(input: String): String = {
|
override def part2(input: String): String = {
|
||||||
implicit val stepper: Stepper = new Stepper {
|
implicit val stepper: Stepper = (p: Program) => {
|
||||||
def step(p: Program): Program = {
|
val instruction = p.instructions(p.index)
|
||||||
val instruction = p.instructions(p.index)
|
val newList = p.instructions.updated(p.index, if (instruction >= 3) instruction - 1 else instruction + 1)
|
||||||
val newList = p.instructions.updated(p.index, if (instruction >= 3) instruction - 1 else instruction + 1)
|
Program(newList, p.index + instruction)
|
||||||
Program(newList, p.index + instruction)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
println()
|
println()
|
||||||
countSteps(getStartingProgram(input)).toString
|
countSteps(getStartingProgram(input)).toString
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
import aoc.Day
|
import aoc._
|
||||||
|
|
||||||
object Day06 extends Day {
|
object Day06 extends Day {
|
||||||
|
|
||||||
|
|
|
@ -42,15 +42,15 @@ object Day08 extends Day {
|
||||||
case class FullTest(reg: String, op: Test, v: Int)
|
case class FullTest(reg: String, op: Test, v: Int)
|
||||||
case class Line(i: FullInstruction, t: FullTest)
|
case class Line(i: FullInstruction, t: FullTest)
|
||||||
|
|
||||||
def registerParser[_: P] = P(CharIn("a-z").rep(1).!)
|
def registerParser[_: P]: P[String] = P(CharIn("a-z").rep(1).!)
|
||||||
def numberParser[_: P] = P(("-".? ~ CharIn("0-9").rep(1)).!).map(_.toInt)
|
def numberParser[_: P]: P[Int] = P(("-".? ~ CharIn("0-9").rep(1)).!).map(_.toInt)
|
||||||
|
|
||||||
def instructionParser[_: P] = P(("inc" | "dec").!).map {
|
def instructionParser[_: P]: P[Instruction] = P(("inc" | "dec").!).map {
|
||||||
case "inc" => Inc
|
case "inc" => Inc
|
||||||
case "dec" => Dec
|
case "dec" => Dec
|
||||||
}
|
}
|
||||||
|
|
||||||
def testParser[_: P] = P(("<=" | ">=" | "<" | ">" | "==" | "!=").!).map {
|
def testParser[_: P]: P[Test] = P(("<=" | ">=" | "<" | ">" | "==" | "!=").!).map {
|
||||||
case "<" => Lt
|
case "<" => Lt
|
||||||
case ">" => Gt
|
case ">" => Gt
|
||||||
case "<=" => Leq
|
case "<=" => Leq
|
||||||
|
@ -59,18 +59,19 @@ object Day08 extends Day {
|
||||||
case "!=" => Neq
|
case "!=" => Neq
|
||||||
}
|
}
|
||||||
|
|
||||||
def fullInstructionParser[_: P] = P(registerParser ~ " " ~ instructionParser ~ " " ~ numberParser).map {
|
def fullInstructionParser[_: P]: P[FullInstruction] =
|
||||||
case (reg, op, v) => FullInstruction(reg, op, v)
|
P(registerParser ~ " " ~ instructionParser ~ " " ~ numberParser).map {
|
||||||
}
|
case (reg, op, v) => FullInstruction(reg, op, v)
|
||||||
|
}
|
||||||
|
|
||||||
def fullTestParser[_: P] = P(registerParser ~ " " ~ testParser ~ " " ~ numberParser).map {
|
def fullTestParser[_: P]: P[FullTest] = P(registerParser ~ " " ~ testParser ~ " " ~ numberParser).map {
|
||||||
case (reg, op, v) => FullTest(reg, op, v)
|
case (reg, op, v) => FullTest(reg, op, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
def lineParser[_: P] = P(fullInstructionParser ~ " if " ~ fullTestParser).map {
|
def lineParser[_: P]: P[Line] = P(fullInstructionParser ~ " if " ~ fullTestParser).map {
|
||||||
case (i, t) => Line(i, t)
|
case (i, t) => Line(i, t)
|
||||||
}
|
}
|
||||||
def listParser[_: P] = P(lineParser.rep(1, "\n")).map(_.toList)
|
def listParser[_: P]: P[List[Line]] = P(lineParser.rep(1, "\n")).map(_.toList)
|
||||||
|
|
||||||
def getProgram(input: String): List[Line] = {
|
def getProgram(input: String): List[Line] = {
|
||||||
val Parsed.Success(list, _) = parse(input, listParser(_))
|
val Parsed.Success(list, _) = parse(input, listParser(_))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
import aoc.Day
|
import aoc._
|
||||||
|
|
||||||
object Day10 extends Day {
|
object Day10 extends Day {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package aoc.y2017
|
package aoc.y2017
|
||||||
|
|
||||||
import aoc.Day
|
import aoc._
|
||||||
|
|
||||||
object Day11 extends Day {
|
object Day11 extends Day {
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@ package aoc
|
||||||
|
|
||||||
package object y2017 extends Year {
|
package object y2017 extends Year {
|
||||||
|
|
||||||
def get = this
|
|
||||||
|
|
||||||
override def days: Map[String, Day] = Map(
|
override def days: Map[String, Day] = Map(
|
||||||
"1" -> Day01,
|
"1" -> Day01,
|
||||||
"2" -> Day02,
|
"2" -> Day02,
|
||||||
|
@ -20,21 +18,4 @@ package object y2017 extends Year {
|
||||||
"25" -> Day25
|
"25" -> Day25
|
||||||
)
|
)
|
||||||
|
|
||||||
def rotateLeft[A](list: List[A], i: Int): List[A] = {
|
|
||||||
val size = list.size
|
|
||||||
list.drop(i % size) ++ list.take(i % size)
|
|
||||||
}
|
|
||||||
|
|
||||||
def rotateRight[A](list: List[A], i: Int): List[A] = {
|
|
||||||
val size = list.size
|
|
||||||
list.drop(size - (i % size)) ++ list.take(size - (i % size))
|
|
||||||
}
|
|
||||||
|
|
||||||
implicit class TupleInt2Ops(t: (Int, Int)) {
|
|
||||||
|
|
||||||
def +(o: (Int, Int)): (Int, Int) = (t, o) match {
|
|
||||||
case ((x1, y1), (x2, y2)) => (x1 + x2, y1 + y2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue