diff --git a/aoc/src/dev/ctsk/aoc/days/Day04.scala b/aoc/src/dev/ctsk/aoc/days/Day04.scala index b2d2b5e..d154efc 100644 --- a/aoc/src/dev/ctsk/aoc/days/Day04.scala +++ b/aoc/src/dev/ctsk/aoc/days/Day04.scala @@ -1,49 +1,46 @@ package dev.ctsk.aoc.days import dev.ctsk.aoc._ +import scala.compiletime.ops.double +import scala.reflect.ClassTag +import scala.collection.mutable.ArrayBuffer object Day04 extends Solver(4): + private val XMAS = "XMAS".r + private val REV_XMAS = "XMAS".reverse.r + + def diagonals[A: ClassTag](m: Array[Array[A]]): Array[Array[A]] = + val diagonals = Array.fill(m.length + m(0).length - 1)(ArrayBuffer[A]()) + + for + i <- m.indices + j <- m(i).indices + do diagonals(i + j) :+= m(i)(j) + + diagonals.map(_.toArray) def part1(lines: Array[Array[Char]]): Int = - def pad(front: Int, line: Array[Char], end: Int): Array[Char] = - Array.fill(front)('.') ++ line ++ Array.fill(end)('.') - def count(line: Array[Char]) = - (0 until line.length - 3) - .count(idx => { - (line.slice(idx, idx + 4) sameElements Array('X', 'M', 'A', 'S')) - || (line.slice(idx, idx + 4) sameElements Array('S', 'A', 'M', 'X')) - }) + val cs = ArrayCharSequence(line) + XMAS.findAllIn(cs).length + REV_XMAS.findAllIn(cs).length - lines.map(count(_)).sum - + lines.transpose.map(count(_)).sum - + lines.zipWithIndex - .map((line, index) => pad(index, line, lines.length - index)) - .transpose - .map(count(_)) - .sum - + lines.zipWithIndex - .map((line, index) => pad(lines.length - index, line, index)) - .transpose - .map(count(_)) - .sum + lines.map(count).sum + + lines.transpose.map(count).sum + + diagonals(lines).map(count).sum + + diagonals(lines.reverse).map(count).sum def part2(grid: Array[Array[Char]]): Int = - def countXMAS(g: Array[Array[Char]]): Int = - (for - i <- 0 until g.length - 2 - j <- 0 until g(i).length - 2 - if g(i)(j) == 'M' && g(i)(j + 2) == 'M' - && g(i + 1)(j + 1) == 'A' - && g(i + 2)(j) == 'S' && g(i + 2)(j + 2) == 'S' - yield 1).sum + var count = 0 - List( - grid, - grid.reverse, - grid.transpose, - grid.transpose.reverse - ).map(countXMAS).sum + for + i <- 1 until grid.length - 1 + j <- 1 until grid(i).length - 1 + if grid(i)(j) == 'A' + & (grid(i - 1)(j - 1) + grid(i + 1)(j + 1) == 'S' + 'M') + & (grid(i - 1)(j + 1) + grid(i + 1)(j - 1) == 'S' + 'M') + do count += 1 + + count def run(input: String): (Timings, Solution) = var in = io.Source