#!/usr/bin/env kotlin import java.util.Scanner val scanner = Scanner(System.`in`) val antennaMap = mutableMapOf>>() val antinodeSet = mutableSetOf>() val harmonicAntinodeSet = mutableSetOf>() var xMax = 0 var yMax = 0 while (scanner.hasNext()) { val symbols = scanner.nextLine().trim().split("").filter { it.isNotEmpty() } xMax = xMax.coerceAtLeast(symbols.lastIndex) for ((i, symbol) in symbols.withIndex()) { if (symbol == ".") continue antennaMap.getOrPut(symbol) { mutableListOf() }.add(Pair(i, yMax)) } yMax++ } yMax-- fun getAntinodes(pair: Pair, pair1: Pair, xMax: Int, yMax: Int): Collection> { val antinodes = mutableSetOf>() val diffOne = Pair(pair.first - pair1.first, pair.second - pair1.second) antinodes.add(Pair(pair.first + diffOne.first, pair.second + diffOne.second)) antinodes.add(Pair(pair1.first - diffOne.first, pair1.second - diffOne.second)) antinodes.removeIf { it.first < 0 || it.second < 0 || it.first > xMax || it.second > yMax } return antinodes } fun getHarmonicAntiNodes( pair: Pair, pair1: Pair, xMax: Int, yMax: Int ): Collection> { val antinodes = mutableSetOf>() val diffOne = Pair(pair.first - pair1.first, pair.second - pair1.second) var mult = 0 while ((pair.first + mult * diffOne.first) <= xMax && (pair.second + mult * diffOne.second) <= yMax && 0 <= (pair.first + mult * diffOne.first) && 0 <= (pair.second + mult * diffOne.second) ) { antinodes.add(Pair(pair.first + mult * diffOne.first, pair.second + mult * diffOne.second)) mult++ } mult = 0 while ((pair1.first - mult * diffOne.first) <= xMax && (pair1.second - mult * diffOne.second) <= yMax && 0 <= (pair1.first - mult * diffOne.first) && 0 <= (pair1.second - mult * diffOne.second)) { antinodes.add(Pair(pair1.first - mult * diffOne.first, pair1.second - mult * diffOne.second)) mult++ } antinodes.removeIf { it.first < 0 || it.second < 0 || it.first > xMax || it.second > yMax } return antinodes } for (antennaType in antennaMap.keys) { for (i in antennaMap[antennaType]!!.indices) { for (y in (i + 1)..(antennaMap[antennaType]!!.lastIndex)) { val antinodes = getAntinodes(antennaMap[antennaType]!![i], antennaMap[antennaType]!![y], xMax, yMax) val harmonicAntinodes = getHarmonicAntiNodes(antennaMap[antennaType]!![i], antennaMap[antennaType]!![y], xMax, yMax) antinodeSet.addAll(antinodes) harmonicAntinodeSet.addAll(harmonicAntinodes) } } } fun printMap(antinodeSet: Set>) { for (y in 0..yMax) { for (x in 0..xMax) { if (Pair(x, y) in antennaMap.values.flatten()) { for (antennatype in antennaMap.keys) { if (Pair(x, y) in antennaMap[antennatype]!!) { print(antennatype) break } } } else if(Pair(x, y) in antinodeSet) print("#") else print(".") } println() } } println("Antinodes: ${antinodeSet.size}") println("Harmonic Antinodes: ${harmonicAntinodeSet.size}")