Year 2016
This commit is contained in:
parent
b40328ee5d
commit
f5b37afa96
12 changed files with 172 additions and 46 deletions
|
@ -5,7 +5,8 @@ import scala.io.StdIn
|
|||
object Main {
|
||||
|
||||
val years = Map(
|
||||
"2017" -> y2017.get
|
||||
"2016" -> y2016.!,
|
||||
"2017" -> y2017.!,
|
||||
)
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
|
|
|
@ -2,6 +2,8 @@ package aoc
|
|||
|
||||
trait Year {
|
||||
|
||||
def !(): this.type = this
|
||||
|
||||
def days: Map[String, Day]
|
||||
|
||||
}
|
||||
|
|
25
aoc/src/main/scala/aoc/package.scala
Normal file
25
aoc/src/main/scala/aoc/package.scala
Normal file
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
111
aoc/src/main/scala/aoc/y2016/Day01.scala
Normal file
111
aoc/src/main/scala/aoc/y2016/Day01.scala
Normal file
|
@ -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
|
||||
}
|
||||
|
||||
}
|
9
aoc/src/main/scala/aoc/y2016/package.scala
Normal file
9
aoc/src/main/scala/aoc/y2016/package.scala
Normal file
|
@ -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
|
||||
|
||||
import aoc.Day
|
||||
import aoc._
|
||||
|
||||
object Day03 extends Day {
|
||||
|
||||
|
|
|
@ -29,24 +29,20 @@ object Day05 extends Day {
|
|||
}
|
||||
|
||||
override def part1(input: String): String = {
|
||||
implicit val stepper: Stepper = new Stepper {
|
||||
def step(p: Program): Program = {
|
||||
val instruction = p.instructions(p.index)
|
||||
val newList = p.instructions.updated(p.index, instruction + 1)
|
||||
Program(newList, p.index + instruction)
|
||||
}
|
||||
implicit val stepper: Stepper = (p: Program) => {
|
||||
val instruction = p.instructions(p.index)
|
||||
val newList = p.instructions.updated(p.index, instruction + 1)
|
||||
Program(newList, p.index + instruction)
|
||||
}
|
||||
println()
|
||||
countSteps(getStartingProgram(input)).toString
|
||||
}
|
||||
|
||||
override def part2(input: String): String = {
|
||||
implicit val stepper: Stepper = new Stepper {
|
||||
def step(p: Program): Program = {
|
||||
val instruction = p.instructions(p.index)
|
||||
val newList = p.instructions.updated(p.index, if (instruction >= 3) instruction - 1 else instruction + 1)
|
||||
Program(newList, p.index + instruction)
|
||||
}
|
||||
implicit val stepper: Stepper = (p: Program) => {
|
||||
val instruction = p.instructions(p.index)
|
||||
val newList = p.instructions.updated(p.index, if (instruction >= 3) instruction - 1 else instruction + 1)
|
||||
Program(newList, p.index + instruction)
|
||||
}
|
||||
println()
|
||||
countSteps(getStartingProgram(input)).toString
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package aoc.y2017
|
||||
|
||||
import aoc.Day
|
||||
import aoc._
|
||||
|
||||
object Day06 extends Day {
|
||||
|
||||
|
|
|
@ -42,15 +42,15 @@ object Day08 extends Day {
|
|||
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 registerParser[_: P]: P[String] = P(CharIn("a-z").rep(1).!)
|
||||
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 "dec" => Dec
|
||||
}
|
||||
|
||||
def testParser[_: P] = P(("<=" | ">=" | "<" | ">" | "==" | "!=").!).map {
|
||||
def testParser[_: P]: P[Test] = P(("<=" | ">=" | "<" | ">" | "==" | "!=").!).map {
|
||||
case "<" => Lt
|
||||
case ">" => Gt
|
||||
case "<=" => Leq
|
||||
|
@ -59,18 +59,19 @@ object Day08 extends Day {
|
|||
case "!=" => Neq
|
||||
}
|
||||
|
||||
def fullInstructionParser[_: P] = P(registerParser ~ " " ~ instructionParser ~ " " ~ numberParser).map {
|
||||
case (reg, op, v) => FullInstruction(reg, op, v)
|
||||
}
|
||||
def fullInstructionParser[_: P]: P[FullInstruction] =
|
||||
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)
|
||||
}
|
||||
|
||||
def lineParser[_: P] = P(fullInstructionParser ~ " if " ~ fullTestParser).map {
|
||||
def lineParser[_: P]: P[Line] = P(fullInstructionParser ~ " if " ~ fullTestParser).map {
|
||||
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] = {
|
||||
val Parsed.Success(list, _) = parse(input, listParser(_))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package aoc.y2017
|
||||
|
||||
import aoc.Day
|
||||
import aoc._
|
||||
|
||||
object Day10 extends Day {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package aoc.y2017
|
||||
|
||||
import aoc.Day
|
||||
import aoc._
|
||||
|
||||
object Day11 extends Day {
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ package aoc
|
|||
|
||||
package object y2017 extends Year {
|
||||
|
||||
def get = this
|
||||
|
||||
override def days: Map[String, Day] = Map(
|
||||
"1" -> Day01,
|
||||
"2" -> Day02,
|
||||
|
@ -20,21 +18,4 @@ package object y2017 extends Year {
|
|||
"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 a new issue