diff --git a/src/Utils.kt b/src/Utils.kt index dd81e6e..dc9767b 100644 --- a/src/Utils.kt +++ b/src/Utils.kt @@ -31,8 +31,14 @@ fun readGraph(day: Int, name: String) = readInput(day, name).fold(mapOf product(xs: Sequence, ys: Sequence): Sequence> = + xs.flatMap { x -> ys.map { y -> x to y } } + fun product(xs: Sequence, ys: Sequence, zs: Sequence): Sequence> = xs.flatMap { x -> ys.flatMap { y -> zs.map { z -> Triple(x, y, z) } } } +fun product(xs: Iterable, ys: Iterable): Sequence> = + product(xs.asSequence(), ys.asSequence()) + fun product(xs: Iterable, ys: Iterable, zs: Iterable): Sequence> = product(xs.asSequence(), ys.asSequence(), zs.asSequence()) diff --git a/src/year2021/day04/Day04.kt b/src/year2021/day04/Day04.kt index cc73f64..189b24c 100644 --- a/src/year2021/day04/Day04.kt +++ b/src/year2021/day04/Day04.kt @@ -1,5 +1,6 @@ package year2021.day04 +import product import readInput class Bingo(description: List) { @@ -21,8 +22,7 @@ class Bingo(description: List) { } private fun mark(board: MutableList>, number: Int) { - board.indices - .flatMap { i -> board.indices.map { j -> Pair(i, j) } } + product(board.indices, board.indices) .filter { (i, j) -> board[i][j] == number } .forEach { (i, j) -> val before = isWinningBoard(board) diff --git a/src/year2021/day08/Day08.kt b/src/year2021/day08/Day08.kt index 8b29f66..b3ec7f4 100644 --- a/src/year2021/day08/Day08.kt +++ b/src/year2021/day08/Day08.kt @@ -1,5 +1,6 @@ package year2021.day08 +import product import readInput class Patterns(private val patterns: MutableList) { @@ -31,9 +32,7 @@ class Patterns(private val patterns: MutableList) { } private fun check(): Boolean = - segments - .indices - .flatMap { i -> segments.indices.map { j -> Pair(i, j) } } + product(segments.indices, segments.indices) .all { (i, j) -> segments[i].intersect(segments[j]).size == (decoded[i] ?: emptySet()).intersect( (decoded[j] ?: emptySet()).toSet() diff --git a/src/year2021/day11/Day11.kt b/src/year2021/day11/Day11.kt index d56a1c9..1ae3387 100644 --- a/src/year2021/day11/Day11.kt +++ b/src/year2021/day11/Day11.kt @@ -1,18 +1,18 @@ package year2021.day11 +import product import readInput -fun validAdjacentIndices(input: List>, y0: Int, x0: Int): Iterable> = - (y0 - 1..y0 + 1) - .flatMap { y -> (x0 - 1..x0 + 1).map { x -> Pair(y, x) } } +fun validAdjacentIndices(input: List>, y0: Int, x0: Int): Sequence> = + product(y0 - 1..y0 + 1, x0 - 1..x0 + 1) .filter { (y, x) -> (y != y0 || x != x0) && (y >= 0 && y < input.size) && (x >= 0 && x < input[y].size) } -fun allIndices(octopuses: List>): Iterable> = - octopuses.indices.flatMap { y -> octopuses[y].indices.map { x -> y to x } } +fun allIndices(octopuses: List>): Sequence> = + product(octopuses.indices, octopuses.first().indices) -fun getFlashes(octopuses: List>): Iterable> = +fun getFlashes(octopuses: List>): Sequence> = allIndices(octopuses).filter { (y, x) -> octopuses[y][x] > 9 } fun step(octopuses: List>): Int { diff --git a/src/year2021/day17/Day17.kt b/src/year2021/day17/Day17.kt index 36fa910..76a57e7 100644 --- a/src/year2021/day17/Day17.kt +++ b/src/year2021/day17/Day17.kt @@ -1,5 +1,6 @@ package year2021.day17 +import product import readInput import kotlin.math.absoluteValue import kotlin.math.min @@ -26,8 +27,8 @@ data class Area(val min: Vector, val max: Vector) { val ySpeeds: IntRange get() = speeds { it.y } - val possibleVectors: Iterable - get() = xSpeeds.flatMap { vx -> ySpeeds.map { vy -> Vector(vx, vy) } } + val possibleVectors: Sequence + get() = product(xSpeeds, ySpeeds).map { (vx, vy) -> Vector(vx, vy) } } // region parsing diff --git a/src/year2021/day18/Day18.kt b/src/year2021/day18/Day18.kt index 5d852c5..8d584bd 100644 --- a/src/year2021/day18/Day18.kt +++ b/src/year2021/day18/Day18.kt @@ -1,5 +1,6 @@ package year2021.day18 +import product import readInput enum class SnailfishNumberType { @@ -193,8 +194,7 @@ fun part1(input: List): Long = fun part2(input: List): Long = input.map(String::toSnailfishNumber).let { numbers -> - numbers.indices - .flatMap { i -> numbers.indices.map { j -> i to j } } + product(numbers.indices, numbers.indices) .filter { (i, j) -> i != j }.maxOf { (i, j) -> (numbers[i] + numbers[j]).magnitude } diff --git a/src/year2021/day19/Day19.kt b/src/year2021/day19/Day19.kt index e1d6391..7c77200 100644 --- a/src/year2021/day19/Day19.kt +++ b/src/year2021/day19/Day19.kt @@ -1,5 +1,6 @@ package year2021.day19 +import product import readInputAsString import java.time.Instant import java.util.* @@ -44,8 +45,7 @@ val TRIGONOMETRY: Set> = .toSet() val ROTATIONS: Set> = - TRIGONOMETRY - .flatMap { alpha -> TRIGONOMETRY.flatMap { beta -> TRIGONOMETRY.map { gamma -> Triple(alpha, beta, gamma) } } } + product(TRIGONOMETRY, TRIGONOMETRY, TRIGONOMETRY) .map { (a, b, g) -> val (sinA, cosA) = a val (sinB, cosB) = b diff --git a/src/year2021/day20/Day20.kt b/src/year2021/day20/Day20.kt index 46d3e90..1dad814 100644 --- a/src/year2021/day20/Day20.kt +++ b/src/year2021/day20/Day20.kt @@ -1,10 +1,11 @@ package year2021.day20 +import product import readInput data class Point(val x: Int, val y: Int) { - val square: Iterable - get() = (y - 1..y + 1).flatMap { y -> (x - 1..x + 1).map { x -> Point(x, y) } } + val square: Sequence + get() = product(y - 1..y + 1, x - 1..x + 1).map { (y, x) -> Point(x, y) } } data class TrenchMap( @@ -24,15 +25,15 @@ data class TrenchMap( private val ys: IntRange get() = coordinateRange { it.y } - private val indices: Iterable - get() = ys.flatMap { y -> xs.map { x -> Point(x, y) } } + private val indices: Sequence + get() = product(ys, xs).map { (y, x) -> Point(x, y) } override fun toString(): String = ys.joinToString("\n") { y -> xs.joinToString("") { x -> get(x, y).toString() } } - private fun toIndex(square: Iterable): Int = + private fun toIndex(square: Sequence): Int = square.map { if (get(it) == '#') 1 else 0 }.reduce { acc, bit -> acc * 2 + bit } private fun enhancePixel(pixel: Point): Char = algorithm[toIndex(pixel.square)]