This commit is contained in:
Paul-Henri Froidmont 2022-12-13 13:19:55 +01:00
parent b8bc763374
commit 7735a22aa1
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 523 additions and 0 deletions

74
aoc/src/Day13.scala Normal file
View file

@ -0,0 +1,74 @@
import scala.io.Source
object Day13 extends App:
val input = Source
.fromURL(getClass.getResource("day13Input.txt"))
.mkString
.split('\n')
.toList
enum Packet:
case Digit(v: Int)
case DList(v: List[Packet])
object Packet:
private def parseArray(input: String): DList =
DList(
input
.split("((?<=[,\\[\\]])|(?=[,\\[\\]]))")
.foldLeft((List[Packet](), "")) {
case ((packets, acc), next) if acc == "" && next == "," => (packets, acc)
case ((packets, acc), next) =>
parse(acc + next)
.map(p => (packets.appended(p), ""))
.getOrElse((packets, acc + next))
}._1
)
def parse(input: String): Option[Packet] =
input.toList match
case _ :: _ if input.forall(_.isDigit) => Some(Digit(input.toInt))
case List('[', _*) :+ ']' if input.count(_ == '[') == input.count(_ == ']') =>
Some(parseArray(input.tail.dropRight(1)))
case _ => None
val compare: (Packet, Packet) => Int =
case (Digit(left), Digit(right)) => left - right
case (DList(left), Digit(right)) => compare(DList(left), DList(List(Digit(right))))
case (Digit(left), DList(right)) => compare(DList(List(Digit(left))), DList(right))
case (DList(Nil), DList(Nil)) => 0
case (DList(Nil), DList(_ :: _)) => -1
case (DList(_ :: _), DList(Nil)) => 1
case (DList(l :: ls), DList(r :: rs)) =>
val headCmp = compare(l, r)
if headCmp != 0 then headCmp else compare(DList(ls), DList(rs))
end Packet
val part1 = input
.filter(_.nonEmpty)
.flatMap(Packet.parse)
.grouped(2)
.map(it => Packet.compare(it.head, it(1)))
.zipWithIndex
.filter(_._1 < 0)
.map(_._2 + 1)
.sum
println("Part 1:")
println(part1)
val divider1 = Packet.parse("[[2]]").get
val divider2 = Packet.parse("[[6]]").get
val sortedPackets = input
.filter(_.nonEmpty)
.flatMap(Packet.parse)
.prependedAll(List(divider1, divider2))
.sortWith(Packet.compare(_, _) < 1)
val part2 = (sortedPackets.indexOf(divider1) + 1) * (sortedPackets.indexOf(divider2) + 1)
println("Part 2:")
println(part2)
end Day13