Skip to content

Instantly share code, notes, and snippets.

@tong92
Created March 31, 2023 13:29
Show Gist options
  • Save tong92/c63c9e46a1ed0803d5643d029a3dbc7e to your computer and use it in GitHub Desktop.
Save tong92/c63c9e46a1ed0803d5643d029a3dbc7e to your computer and use it in GitHub Desktop.
2022-day13
import scala.io.Source
sealed trait Sig:
override def toString: String =
this match
case Open => "O "
case Close => "C "
case SigN(x) => s"$x "
object Open extends Sig
object Close extends Sig
case class SigN(n: Int) extends Sig
def toSig(s: String): List[Sig] =
if s.isEmpty then Nil
else if s.head == '[' then Open :: toSig(s.tail)
else if s.last == ']' then toSig(s.dropRight(1)) ++ List(Close)
else SigN(s.toInt) :: Nil
def matchSig(l: List[Sig], r: List[Sig], n: Int): Int =
if l.isEmpty then return n
else if r.isEmpty then return 0
val lh = l.head
val rh = r.head
(lh, rh) match
case (Close, Close) => matchSig(l.tail, r.tail, n)
case (Close, _) => n
case (Open, Open) => matchSig(l.tail, r.tail, n)
case (Open, Close) => 0
case (Open, SigN(x)) => matchSig(l.tail, r, n)
case (SigN(x), Close) => 0
case (SigN(x), Open) => matchSig(l, r.tail, n)
case (SigN(x), SigN(y)) =>
if x > y then 0
else if x < y then n
else matchSig(l.tail, r.tail, n)
def compare(l: String, r: String, n: Int): Int =
matchSig(convert(l), convert(r))
def ans1(xs: List[String], n: Int = 1): Int =
xs match
case Nil => 0
case "" :: t => ans1(t, n)
case a :: next =>
next match
case b :: t => compare(a, b, n) + ans1(t, n + 1)
case Nil => 0
def convert(s: String): List[Sig] =
s.split(',').map(toSig).flatten.toList
def sigOrder(l: List[Sig], r: List[Sig]): Boolean =
matchSig(l, r, 1) == 0
def check(l: List[Sig], i: Int): Int = l match
case List(Open, Open, SigN(2), Close, Close) => i + 1
case List(Open, Open, SigN(6), Close, Close) => i + 1
case _ => 1
def ans2(xs: List[String]): Int =
(xs ++ List("[[2]]", "[[6]]"))
.filter(!_.isEmpty)
.map(convert)
.sortWith(sigOrder)
.zipWithIndex.map(check)
.product
def solve =
val input = Source.fromFile("day13.txt").getLines.toList
// println(ans1(input))
println(ans2(input))
def test =
val input = Source.fromFile("ex13.txt").getLines.toList
// println(ans1(input))
println(ans2(input))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment