3 gold star
This commit is contained in:
parent
6ba1c0a451
commit
0bf14430ea
7 changed files with 196 additions and 11 deletions
|
@ -5,7 +5,6 @@ import aoc.Day
|
|||
object Day03 extends Day {
|
||||
|
||||
override def part1(input: String): String = {
|
||||
case class Cell(num: Int, stepSize: Int, stepFrac: Int, stepped: Int, dist: (Int, Int))
|
||||
val inum = input.toInt
|
||||
(inum match {
|
||||
case 1 => 0
|
||||
|
@ -19,7 +18,53 @@ object Day03 extends Day {
|
|||
}
|
||||
|
||||
override def part2(input: String): String = {
|
||||
"Not Currently Implemented" // TODO Implement this
|
||||
implicit class TupleInt2Ops(t: (Int, Int)) {
|
||||
def +(o: (Int, Int)): (Int, Int) = (t, o) match {
|
||||
case ((x1, y1), (x2, y2)) => (x1 + x2, y1 + y2)
|
||||
}
|
||||
}
|
||||
sealed trait Direction {
|
||||
def change: (Int, Int)
|
||||
}
|
||||
case object MoveUp extends Direction {
|
||||
override def change: (Int, Int) = (0, 1)
|
||||
}
|
||||
case object MoveRight extends Direction {
|
||||
override def change: (Int, Int) = (1, 0)
|
||||
}
|
||||
case object MoveDown extends Direction {
|
||||
override def change: (Int, Int) = (0, -1)
|
||||
}
|
||||
case object MoveLeft extends Direction {
|
||||
override def change: (Int, Int) = (-1, 0)
|
||||
}
|
||||
def sumOfSurrounding(p: (Int, Int), m: Map[(Int, Int), Int]): Int = {
|
||||
val surrounding = List(
|
||||
(-1, 1), ( 0, 1), ( 1, 1),
|
||||
(-1, 0), /* */ ( 1, 0),
|
||||
(-1, -1), ( 0, -1), ( 1, -1)
|
||||
)
|
||||
surrounding.map(o => m.getOrElse(p + o, 0)).sum
|
||||
}
|
||||
lazy val movementStream: Stream[Int] = Stream.from(1).flatMap(i => Stream(i, i))
|
||||
lazy val directionStream: Stream[Direction] = MoveRight #:: MoveUp #:: MoveLeft #:: MoveDown #:: directionStream
|
||||
lazy val pathStream = movementStream.zip(directionStream).flatMap {
|
||||
case (times, dir) => Stream.fill(times)(dir)
|
||||
}
|
||||
lazy val pathIterator = pathStream.toIterator
|
||||
val targetNum = input.toInt
|
||||
def findNext(m: Map[(Int, Int), Int] = Map((0, 0) -> 1), p: (Int, Int) = (0, 0), i: Iterator[Direction]): Int = {
|
||||
val nd = i.next()
|
||||
val np = p + nd.change
|
||||
val sum = sumOfSurrounding(np, m)
|
||||
val nm = m + (np -> sum)
|
||||
if(sum > targetNum) {
|
||||
sum
|
||||
} else {
|
||||
findNext(nm, np, i)
|
||||
}
|
||||
}
|
||||
findNext(i = pathIterator).toString
|
||||
}
|
||||
|
||||
}
|
||||
|
|
63
aoc/src/main/scala/aoc/y2017/Day06.scala
Normal file
63
aoc/src/main/scala/aoc/y2017/Day06.scala
Normal file
|
@ -0,0 +1,63 @@
|
|||
package aoc.y2017
|
||||
|
||||
import aoc.Day
|
||||
|
||||
object Day06 extends Day {
|
||||
|
||||
def uniquePrefix[A](as: Stream[A]): Stream[A] = {
|
||||
def go(as: Stream[A], seen: Set[A]): Stream[A] = as match {
|
||||
case h #:: t if !seen(h) => h #:: go(t, seen + h)
|
||||
case _ => Stream.empty[A]
|
||||
}
|
||||
go(as, Set.empty)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
case class State(blocks: List[Int]) {
|
||||
|
||||
def step: State = {
|
||||
val mi = blocks.indexWhere(_ == blocks.max)
|
||||
val shifted = rotateLeft(blocks, mi)
|
||||
val max = shifted.head
|
||||
val loops = max / shifted.size
|
||||
val extra = max % shifted.size
|
||||
val looped = shifted.map(_ + loops)
|
||||
val extraSlice = looped.tail.take(extra).map(_ + 1)
|
||||
val back = looped.tail.drop(extra)
|
||||
val constructed = loops +: (extraSlice ++ back)
|
||||
State(rotateRight(constructed, mi))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def showAndGetStream(input: String): Stream[State] = {
|
||||
val os = State(input.split('\t').toList.map(_.toInt))
|
||||
val stream = Stream.iterate(os)(s => s.step)
|
||||
val uStream = uniquePrefix(stream)
|
||||
uStream.foreach(s => print(s"\r${s.blocks.mkString("\t")} "))
|
||||
println()
|
||||
uStream
|
||||
}
|
||||
|
||||
override def part1(input: String): String = {
|
||||
val uStream = showAndGetStream(input)
|
||||
uStream.toList.size.toString
|
||||
}
|
||||
|
||||
override def part2(input: String): String = {
|
||||
val uStream = showAndGetStream(input)
|
||||
val l = uStream.toList
|
||||
val n = l.last.step
|
||||
(l.size - l.indexOf(n)).toString
|
||||
}
|
||||
|
||||
}
|
75
aoc/src/main/scala/aoc/y2017/Day07.scala
Normal file
75
aoc/src/main/scala/aoc/y2017/Day07.scala
Normal file
|
@ -0,0 +1,75 @@
|
|||
package aoc.y2017
|
||||
|
||||
import aoc.Day
|
||||
|
||||
object Day07 extends Day {
|
||||
|
||||
import fastparse._, SingleLineWhitespace._
|
||||
|
||||
case class TowerRef(name: String, weight: Int, children: List[String]) {
|
||||
|
||||
def resolve(trs: List[TowerRef]): Tower =
|
||||
Tower(name, weight, children.map(c => trs.find(_.name == c).get.resolve(trs)))
|
||||
|
||||
}
|
||||
|
||||
case class Tower(name: String, weight: Int, children: List[Tower]) {
|
||||
|
||||
def childWeights: List[Int] = children.map(_.totalWeight)
|
||||
|
||||
def totalWeight: Int = weight + childWeights.sum
|
||||
|
||||
}
|
||||
|
||||
def childrenParser[_: P]: P[List[String]] =
|
||||
P(("->" ~ CharIn("a-z").rep(1).!.rep(1, ",")).?).map(_.fold(List[String]())(_.toList))
|
||||
|
||||
def towerParser[_: P]: P[TowerRef] = P(CharIn("a-z").rep(1).! ~ "(" ~ CharIn("0-9").rep(1).! ~ ")" ~ childrenParser).map {
|
||||
case (name, weight, children) => TowerRef(name, weight.toInt, children)
|
||||
}
|
||||
|
||||
def towerListParser[_: P]: P[List[TowerRef]] = towerParser.rep(1, "\n").map(_.toList)
|
||||
|
||||
def lowest(trs: List[TowerRef]): TowerRef = {
|
||||
val allChildren = trs.flatMap(_.children)
|
||||
val name = trs.map(_.name).filterNot(allChildren.contains).head
|
||||
trs.find(_.name == name).get
|
||||
}
|
||||
|
||||
override def part1(input: String): String = {
|
||||
val Parsed.Success(trs: List[TowerRef], _) = parse(input, towerListParser(_))
|
||||
lowest(trs).name
|
||||
}
|
||||
|
||||
override def part2(input: String): String = {
|
||||
val Parsed.Success(trs: List[TowerRef], _) = parse(input, towerListParser(_))
|
||||
val lowestT = lowest(trs)
|
||||
val resolved = lowestT.resolve(trs)
|
||||
def searchForUnevenness(tower: Tower): List[Int] = {
|
||||
if(tower.childWeights.distinct.size == 1) {
|
||||
tower.children.flatMap(searchForUnevenness)
|
||||
} else {
|
||||
if(tower.childWeights.isEmpty) {
|
||||
List()
|
||||
} else {
|
||||
val ds = tower.childWeights.distinct
|
||||
val (w1, w2) = (ds.head, ds.last)
|
||||
val (c1, c2) = (tower.childWeights.count(_ == w1), tower.childWeights.count(_ == w2))
|
||||
val (offWeight, onWeight) = if (Math.max(c1, c2) == c1) {
|
||||
(w2, w1)
|
||||
} else {
|
||||
(w1, w2)
|
||||
}
|
||||
val offChild = tower.children.find(_.totalWeight == offWeight).get
|
||||
if (offChild.childWeights.distinct.size == 1) {
|
||||
List((onWeight - offWeight) + offChild.weight)
|
||||
} else {
|
||||
offChild.children.flatMap(searchForUnevenness)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
searchForUnevenness(resolved).head.toString
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,8 @@ package object y2017 extends Year {
|
|||
"3" -> Day03,
|
||||
"4" -> Day04,
|
||||
"5" -> Day05,
|
||||
"6" -> Day06,
|
||||
"7" -> Day07,
|
||||
"25" -> Day25
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ val sharedSettings = Seq(
|
|||
name := "aoc",
|
||||
organization := "tf.bug",
|
||||
version := "0.1.0",
|
||||
scalaVersion := "2.11.12",
|
||||
scalaVersion := "2.12.7",
|
||||
libraryDependencies ++= List(
|
||||
"com.lihaoyi" %%% "fastparse" % "2.0.4",
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue