class Y24D08(val input: String) : Day { private val cityLimits = input.toGrid() private val antennae: Map> = buildMap> { cityLimits.withIndex() .filter { (_, roof) -> roof != '.' } .forEach { (index, antenna) -> val pos = Coord.fromIndex(index, cityLimits.width) getOrPut(antenna) { mutableListOf() }.add(pos) } } private inline fun solve(antinode: (Pair) -> List) = antennae.values .flatMap { positions -> positions.getPairs().flatMap(antinode) } .toSet() .size override fun part1() = solve { (a, b) -> val diff = a - b listOf(a + diff, b - diff).filter { antinode -> antinode isWithin cityLimits } } override fun part2() = solve { (a, b) -> val diff = a - b ray(a, diff) + ray(b, -diff) } private fun ray(start: Coord, diff: Coord) = generateSequence(start) { it + diff } .takeWhile { antinode -> antinode isWithin cityLimits } .toList() }