54 lines
1.4 KiB
Scala
54 lines
1.4 KiB
Scala
package aoc.y2017
|
|
|
|
import aoc._
|
|
|
|
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)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
}
|