Day 8: Resonant Collinearity
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Kotlin
A bit late to the party, but here’s my solution. I don’t know, if you even need to search for the smallest integer vector in the same direction in part 2, but I did it anyway.
Code:
import kotlin.math.abs import kotlin.math.pow fun main() { fun part1(input: List<String>): Int { val inputMap = Day08Map(input) return inputMap.isoFrequencyNodeVectorsByLocations .flatMap { (location, vectors) -> vectors.map { (2.0 scaleVec it) + location } } .toSet() .count { inputMap.isInGrid(it) } } fun part2(input: List<String>): Int { val inputMap = Day08Map(input) return buildSet { inputMap.isoFrequencyNodeVectorsByLocations.forEach { (location, vectors) -> vectors.forEach { vector -> var i = 0.0 val scaledDownVector = smallestIntegerVectorInSameDirection2D(vector) while (inputMap.isInGrid(location + (i scaleVec scaledDownVector))) { add(location + (i scaleVec scaledDownVector)) i++ } } } }.count() } val testInput = readInput("Day08_test") check(part1(testInput) == 14) check(part2(testInput) == 34) val input = readInput("Day08") part1(input).println() part2(input).println() } tailrec fun gcdEuclid(a: Int, b: Int): Int = if (b == 0) a else if (a == 0) b else if (a > b) gcdEuclid(a - b, b) else gcdEuclid(a, b - a) fun smallestIntegerVectorInSameDirection2D(vec: VecNReal): VecNReal { assert(vec.dimension == 2) // Only works in two dimensions. assert(vec == vec.roundComponents()) // Only works on integer vectors. return (gcdEuclid(abs(vec[0].toInt()), abs(vec[1].toInt())).toDouble().pow(-1) scaleVec vec).roundComponents() } class Day08Map(input: List<String>): Grid2D<Char>(input.reversed().map { it.toList() }) { init { transpose() } val isoFrequencyNodesLocations = asIterable().toSet().filter { it != '.' }.map { frequency -> asIterable().indicesWhere { frequency == it } } val isoFrequencyNodeVectorsByLocations = buildMap { isoFrequencyNodesLocations.forEach { isoFrequencyLocationList -> isoFrequencyLocationList.mapIndexed { index, nodeLocation -> this[VecNReal(nodeLocation)] = isoFrequencyLocationList .slice((0 until index) + ((index + 1)..isoFrequencyLocationList.lastIndex)) .map { VecNReal(it) - VecNReal(nodeLocation) } } } } }