Year 2016

This commit is contained in:
Aly 2018-11-28 06:44:24 -08:00
parent b40328ee5d
commit f5b37afa96
No known key found for this signature in database
GPG Key ID: 555B7346639DDAC3
12 changed files with 172 additions and 46 deletions

View File

@ -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 = {

View File

@ -2,6 +2,8 @@ package aoc
trait Year {
def !(): this.type = this
def days: Map[String, Day]
}

View 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)
}
}
}

View 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
}
}

View File

@ -0,0 +1,9 @@
package aoc
package object y2016 extends Year {
override def days: Map[String, Day] = Map(
"1" -> Day01
)
}

View File

@ -1,6 +1,6 @@
package aoc.y2017
import aoc.Day
import aoc._
object Day03 extends Day {

View File

@ -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

View File

@ -1,6 +1,6 @@
package aoc.y2017
import aoc.Day
import aoc._
object Day06 extends Day {

View File

@ -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(_))

View File

@ -1,6 +1,6 @@
package aoc.y2017
import aoc.Day
import aoc._
object Day10 extends Day {

View File

@ -1,6 +1,6 @@
package aoc.y2017
import aoc.Day
import aoc._
object Day11 extends Day {

View File

@ -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)
}
}
}