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