fun part1(grid: Grid) = (horizontal + vertical + diagonals) .flatMap { m -> grid.findAll('X').map { it to m } } .mapNotNull { (p, m) -> if (grid[p + m] == 'M') p + m to m else null } .mapNotNull { (p, m) -> if (grid[p + m] == 'A') p + m to m else null } .count { (p, m) -> grid[p + m] == 'S' } fun part2(grid: Grid): Int = grid.findAll('A').count { p -> diagonals.count { m -> grid[p - m] == 'M' && grid[p + m] == 'S' } == 2 } typealias Move = Pair val diagonals: Set = setOf(-1 to -1, -1 to 1, 1 to -1, 1 to 1) val vertical: Set = setOf(-1 to 0, 1 to 0) val horizontal: Set = setOf(0 to -1, 0 to 1) typealias Pos = Pair operator fun Pos.plus(d: Move) = Pos(first + d.first, second + d.second) operator fun Pos.minus(d: Move) = Pos(first - d.first, second - d.second) typealias Grid = List operator fun Grid.get(p: Pos) = getOrNull(p.first)?.getOrNull(p.second) fun Grid.findAll(ch: Char): List = flatMapIndexed { r, line -> line.indices.filter { line[it] == ch }.map { c -> Pos(r, c) } }