Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created February 11, 2022 11:52
Show Gist options
  • Save sungkmi/4e563385245448a9df31c3468709a37a to your computer and use it in GitHub Desktop.
Save sungkmi/4e563385245448a9df31c3468709a37a to your computer and use it in GitHub Desktop.
package lascala.aoc2021.day1_10.day10
opaque type Chunk = List[Char]
val Parens: Set[(Char, Char)] =
Set(('(', ')'), ('[', ']'), ('{', '}'), ('<', '>'))
val OpenParens: Set[Char] = Parens.unzip._1
extension (c: Chunk)
def check: Either[Char, Chunk] =
@annotation.tailrec
def loop(chunk: Chunk, acc: List[Char]): Either[Char, Chunk] =
chunk match
case Nil =>
Right(acc)
case h :: t if OpenParens contains h =>
loop(t, h :: acc)
case h :: t =>
acc match
case h2 :: t2 if Parens contains (h2, h) =>
loop(t, t2)
case _ => Left(h)
loop(c, Nil)
def isEmpty: Boolean = c.isEmpty
end extension
object Chunk:
def apply(s: String): Chunk = s.toList
def empty: Chunk = Nil
def solve1(s: String): BigInt =
val illigals: Seq[Char] = for
line <- s.split("\n")
chunk = Chunk(line)
checked = chunk.check if checked.isLeft
yield checked.left.get
val scoreMap: Map[Char, Int] =
Map(')' -> 3, ']' -> 57, '}' -> 1197, '>' -> 25137)
illigals.map(scoreMap).sum
end solve1
def solve2(s: String): BigInt =
val parenMap: Map[Char, Char] = Parens.toMap
val completes: Seq[Seq[Char]] = for
line <- s.split("\n")
chunk = Chunk(line)
checked = chunk.check if checked.isRight
opens <- checked.toOption
yield opens.map(parenMap)
val scoreMap: Map[Char, Int] = Map(')' -> 1, ']' -> 2, '}' -> 3, '>' -> 4)
val scores = completes.map { complete =>
complete.foldLeft(BigInt(0)) { (acc, c) =>
acc * 5 + scoreMap(c)
}
}.sorted
scores(scores.length / 2)
end solve2
@main def part1: Unit =
val ans = solve1(input)
println(ans)
@main def part2: Unit =
val ans = solve2(input)
println(ans)
val input =
package lascala.aoc2021.day1_10.day10
import minitest.SimpleTestSuite
import hedgehog.minitest.HedgehogSupport
import hedgehog.*
object Day10Test extends SimpleTestSuite with HedgehogSupport:
val testInput = """[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]"""
example("day10 - check") {
Result.all(List(
Chunk("()").check ==== Right(Chunk.empty),
Chunk("{([(<{}[<>[]}>{[]{[(<()>").check ==== Left('}'),
Chunk("[[<[([]))<([[{}[[()]]]").check ==== Left(')'),
Chunk("[{[{({}]{}}([{[{{{}}([]").check ==== Left(']'),
Chunk("[<(<(<(<{}))><([]([]()").check ==== Left(')'),
Chunk("<{([([[(<>()){}]>(<<{{").check ==== Left('>'),
))
}
example("day10 - solve 1") {
solve1(testInput) ==== 26397
}
example("day10 - solve 2") {
solve2(testInput) ==== 288957
}
end Day10Test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment