mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +01:00
Adding day 13 p1 and day 14 p1
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
||||
input
|
||||
*input*
|
||||
197
day13/part1.scala
Normal file
197
day13/part1.scala
Normal file
@@ -0,0 +1,197 @@
|
||||
import scala.io.StdIn.readLine
|
||||
import scala.annotation.tailrec
|
||||
|
||||
val ESC = "\u001B"
|
||||
val RED = s"$ESC[1;31m"
|
||||
val BLU = s"$ESC[1;34m"
|
||||
val CLR = s"$ESC[0;37m"
|
||||
|
||||
val CLEAR_SCREEN = s"$ESC[2J"
|
||||
|
||||
case class Pos(x: Int, y: Int) {
|
||||
def +(that: Pos): Pos = Pos(x + that.x, y + that.y)
|
||||
}
|
||||
|
||||
object Up extends Pos(0, -1)
|
||||
object Down extends Pos(0, 1)
|
||||
object Left extends Pos(-1, 0)
|
||||
object Right extends Pos(1, 0)
|
||||
|
||||
val directions: Array[Pos] = Array(
|
||||
Left,
|
||||
Up,
|
||||
Right,
|
||||
Down)
|
||||
|
||||
sealed trait TrackOrientation {
|
||||
val c: Char
|
||||
def move(cart: Cart): Cart
|
||||
}
|
||||
|
||||
trait Straight extends TrackOrientation {
|
||||
override def move(cart: Cart): Cart =
|
||||
cart.copy(p = cart.p + cart.o)
|
||||
}
|
||||
|
||||
case object StraightImpl extends Straight {
|
||||
override val c: Char = '?'
|
||||
}
|
||||
|
||||
case object Horizontal extends Straight {
|
||||
override val c: Char = '-'
|
||||
}
|
||||
case object Vertical extends Straight {
|
||||
override val c: Char = '|'
|
||||
}
|
||||
|
||||
case object Diag1 extends TrackOrientation {
|
||||
override val c: Char = '/'
|
||||
override def move(cart: Cart): Cart = cart.o match {
|
||||
case Up => TurnRight.move(cart)
|
||||
case Down => TurnRight.move(cart)
|
||||
case Left => TurnLeft.move(cart)
|
||||
case Right => TurnLeft.move(cart)
|
||||
}
|
||||
}
|
||||
|
||||
case object Diag2 extends TrackOrientation {
|
||||
override val c: Char = '\\'
|
||||
override def move(cart: Cart): Cart = cart.o match {
|
||||
case Up => TurnLeft.move(cart)
|
||||
case Down => TurnLeft.move(cart)
|
||||
case Left => TurnRight.move(cart)
|
||||
case Right => TurnRight.move(cart)
|
||||
}
|
||||
}
|
||||
|
||||
case object TurnLeft extends TrackOrientation {
|
||||
override val c: Char = '?'
|
||||
|
||||
val changes: Map[Pos, Pos] = Map(
|
||||
Up -> Left,
|
||||
Down -> Right,
|
||||
Left -> Down,
|
||||
Right -> Up
|
||||
)
|
||||
|
||||
override def move(cart: Cart): Cart = {
|
||||
val newDir = changes(cart.o)
|
||||
cart.copy(o = newDir, p = cart.p + newDir)
|
||||
}
|
||||
}
|
||||
|
||||
case object TurnRight extends TrackOrientation {
|
||||
override val c: Char = '?'
|
||||
|
||||
val changes: Map[Pos, Pos] = Map(
|
||||
Up -> Right,
|
||||
Down -> Left,
|
||||
Left -> Up,
|
||||
Right -> Down
|
||||
)
|
||||
|
||||
override def move(cart: Cart): Cart = {
|
||||
val newDir = changes(cart.o)
|
||||
cart.copy(o = newDir, p = cart.p + newDir)
|
||||
}
|
||||
}
|
||||
|
||||
val crossDirections = Array(
|
||||
TurnLeft,
|
||||
StraightImpl,
|
||||
TurnRight)
|
||||
|
||||
case object CX extends TrackOrientation {
|
||||
override val c: Char = '+'
|
||||
|
||||
override def move(cart: Cart): Cart =
|
||||
crossDirections(cart.nextCross)
|
||||
.move(cart.copy(nextCross=(cart.nextCross + 1) % 3))
|
||||
}
|
||||
|
||||
sealed trait Entry
|
||||
|
||||
case class Track(p: Pos, o: TrackOrientation) extends Entry
|
||||
|
||||
case class Cart(p: Pos, o: Pos, nextCross: Int = 0) extends Entry with Ordered[Cart] {
|
||||
def compare(that: Cart): Int = {
|
||||
val cmpL = p.y - that.p.y
|
||||
if (cmpL == 0) {
|
||||
p.x - that.p.x
|
||||
} else {
|
||||
cmpL
|
||||
}
|
||||
}
|
||||
|
||||
def next(tracks: Map[Pos, TrackOrientation]): Cart =
|
||||
tracks(p).move(this)
|
||||
|
||||
override def toString: String = "#"
|
||||
}
|
||||
|
||||
val input = Iterator
|
||||
.continually(readLine)
|
||||
.takeWhile(_ != null)
|
||||
.toList
|
||||
.zipWithIndex
|
||||
.flatMap { case (l, y) => l.zipWithIndex.map { case (c, x) => Pos(x, y) -> c } }
|
||||
.flatMap {
|
||||
// tracks
|
||||
case (p, c) if c == '|' => List(Track(p, Vertical))
|
||||
case (p, c) if c == '-' => List(Track(p, Horizontal))
|
||||
case (p, c) if c == '+' => List(Track(p, CX))
|
||||
case (p, c) if c == '\\' => List(Track(p, Diag2))
|
||||
case (p, c) if c == '/' => List(Track(p, Diag1))
|
||||
case (p, c) if c == 'v' => List(Track(p, Vertical), Cart(p, Down))
|
||||
case (p, c) if c == '^' => List(Track(p, Vertical), Cart(p, Up))
|
||||
case (p, c) if c == '>' => List(Track(p, Horizontal), Cart(p, Right))
|
||||
case (p, c) if c == '<' => List(Track(p, Horizontal), Cart(p, Left))
|
||||
case _ => List()
|
||||
}
|
||||
|
||||
val tracks: Map[Pos, TrackOrientation] = input.flatMap {
|
||||
case t: Track => Some(t.p -> t.o)
|
||||
case _ => None
|
||||
}.toMap
|
||||
|
||||
val initialCarts: List[Cart] = input.filter(_.isInstanceOf[Cart]).map(_.asInstanceOf[Cart])
|
||||
|
||||
def printGame(tracks: Map[Pos, TrackOrientation], carts: List[Cart], turn: Int): Unit = {
|
||||
val maxX = tracks.keys.map(_.x).max
|
||||
val maxY = tracks.keys.map(_.y).max
|
||||
|
||||
// print(CLEAR_SCREEN)
|
||||
|
||||
val lines = (0 to maxY).map { y =>
|
||||
val line = (0 to maxX).map { x =>
|
||||
Pos(x, y) match {
|
||||
case p if carts.exists(_.p == p) =>
|
||||
carts.filter(_.p == p) match {
|
||||
case cs if cs.size > 1 => s"${RED}X${CLR}"
|
||||
case c :: Nil => s"${BLU}$c${CLR}"
|
||||
}
|
||||
case p if tracks.isDefinedAt(p) => tracks(p).c.toString
|
||||
case _ => " "
|
||||
}
|
||||
}.mkString("")
|
||||
"%03d %s".format(turn, line)
|
||||
}
|
||||
lines.foreach(println)
|
||||
// Thread.sleep(200)
|
||||
}
|
||||
|
||||
@tailrec
|
||||
def playGame(tracks: Map[Pos, TrackOrientation])(carts: List[Cart], turn: Int): (Int, Pos) = {
|
||||
val nextCarts = carts.sorted.map(_.next(tracks))
|
||||
// printGame(tracks, nextCarts, turn)
|
||||
|
||||
(nextCarts ++ carts).groupBy(_.p).find(_._2.size > 1) match {
|
||||
case Some((p, _)) => turn -> p
|
||||
case _ => playGame(tracks)(nextCarts, turn + 1)
|
||||
}
|
||||
}
|
||||
|
||||
// printGame(tracks, initialCarts, 1)
|
||||
|
||||
val (crashTurn, crashPos) = playGame(tracks)(initialCarts, 2)
|
||||
println(crashTurn, crashPos)
|
||||
42
day14/part1.scala
Normal file
42
day14/part1.scala
Normal file
@@ -0,0 +1,42 @@
|
||||
import scala.io.StdIn.readInt
|
||||
|
||||
case class Turn(recipes: Vector[Int], idx1: Int, idx2: Int, turnNb: Int) {
|
||||
def newScores(a: Int, b: Int): Vector[Int] =
|
||||
(a + b).toString.map(_.toInt - '0').toVector
|
||||
|
||||
def next: Turn = {
|
||||
val newRecipes = recipes ++ newScores(recipes(idx1), recipes(idx2))
|
||||
val newIdx1 = (idx1 + (newRecipes(idx1) + 1)) % newRecipes.size
|
||||
val newIdx2 = (idx2 + (newRecipes(idx2) + 1)) % newRecipes.size
|
||||
Turn(newRecipes, newIdx1, newIdx2, turnNb + 1)
|
||||
}
|
||||
|
||||
override def toString: String =
|
||||
recipes.zipWithIndex.map {
|
||||
case (v, k) => k match {
|
||||
case _ if k == idx1 => s"($v)"
|
||||
case _ if k == idx2 => s"[$v]"
|
||||
case _ => s" $v "
|
||||
}
|
||||
}.mkString(" ")
|
||||
|
||||
def computeScoreAt(n: Int): Option[String] =
|
||||
recipes match {
|
||||
case _ if recipes.size < n + 10 => None
|
||||
case _ => Some(recipes.slice(n, n + 10).mkString(""))
|
||||
}
|
||||
}
|
||||
|
||||
val input = readInt
|
||||
|
||||
val turn0 = Turn(Vector(3, 7), 0, 1, 0)
|
||||
|
||||
val endTurn = Iterator.iterate(turn0)(_.next)
|
||||
.filter(_.recipes.length >= input + 11)
|
||||
.next
|
||||
|
||||
// println(s"Score: ${endTurn.computeScoreAt(5)} - Expected: 0124515891")
|
||||
// println(s"Score: ${endTurn.computeScoreAt(18)} - Expected: 9251071085")
|
||||
// println(s"Score: ${endTurn.computeScoreAt(2018)} - Expected: 5941429882")
|
||||
|
||||
println(s"Score: ${endTurn.computeScoreAt(input).get}")
|
||||
Reference in New Issue
Block a user