aoc2023/Day13.scala

55 lines
1.3 KiB
Scala
Raw Normal View History

2023-12-13 14:25:46 +00:00
package aoc.day13
import aoc._
type Board = List[Seq[Char]]
val boards: Seq[Board] =
lines.toSeq
.splitBy(_ == "")
.map(_.map(_.toSeq).toList)
extension [T](ss: List[T])
def splits =
def loop(prefix: List[T], cur: List[T]): Seq[(List[T], List[T])] = cur match
case head :: next =>
(prefix, cur) +: loop(head +: prefix, next)
case Nil => Seq((prefix, cur))
loop(List.empty, ss)
def reflections(ok: (Board, Board, Int) => Boolean)(board: Board): Seq[Int] =
board.toList.splits.zipWithIndex
.filter {
case ((Nil, _) | (_, Nil), _) => false
case ((top, bottom), _) =>
val smudges = top.lazyZip(bottom).map(_.lazyZip(_).count(_ != _)).sum
ok(top, bottom, smudges)
}
.map(_._2)
inline def boardReflections(ok: (Board, Board, Int) => Boolean)(board: Board) =
val rowReflections = reflections(ok)(board)
val colReflections = reflections(ok)(board.transpose)
// println(s"$rowReflections $colReflections")
(rowReflections.sum * 100L + colReflections.sum)
// part 1
def part1 =
val res = boards
.map(boardReflections((_, _, s) => s == 0)(_))
.sum
println(res)
// part 2
def part2 =
val res = boards
.map(boardReflections((_, _, s) => s == 1)(_))
.sum
println(res)
@main def Day13(part: Int) = part match
case 1 => part1
case 2 => part2