Day 13
This commit is contained in:
parent
b8bc763374
commit
7735a22aa1
2 changed files with 523 additions and 0 deletions
74
aoc/src/Day13.scala
Normal file
74
aoc/src/Day13.scala
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue