Coverage Summary for Class: Universe (day11p2)
Class |
Method, %
|
Line, %
|
Universe |
100%
(5/5)
|
100%
(40/40)
|
Universe$toExpandedUniverse$1 |
100%
(1/1)
|
100%
(1/1)
|
Universe$toExpandedUniverse$3 |
100%
(1/1)
|
100%
(1/1)
|
Universe$toExpandedUniverse$galaxyColumns$1 |
100%
(1/1)
|
100%
(1/1)
|
Universe$toExpandedUniverse$galaxyRows$1 |
100%
(1/1)
|
100%
(1/1)
|
Universe$toImage$1 |
100%
(1/1)
|
100%
(2/2)
|
Universe$toImage$1$1 |
100%
(1/1)
|
100%
(1/1)
|
Universe$toImage$2 |
100%
(1/1)
|
100%
(1/1)
|
Total |
100%
(12/12)
|
100%
(48/48)
|
package day11p2
import java.util.*
import kotlin.math.absoluteValue
fun String.toUniverse(): Universe {
val lines = lines()
val numOfRows = lines.size
val numOfColumns = lines.first().length
val galaxies = lines.flatMapIndexed { row: Int, line: String ->
line.mapIndexedNotNull { column, ch -> if (ch == '#') row to column else null }
}
.map { Galaxy(Coordinate(it.first, it.second)) }
.toSet()
return Universe(numOfRows.toLong(), numOfColumns.toLong(), galaxies)
}
data class Universe(val numOfRows: Long, val numOfColumns: Long, val galaxies: Set<Galaxy>) {
fun toExpandedUniverse(expansionRate: Long = 2L): Universe {
var rowOffset = 0L
val rowOffsets = TreeMap<Long, Long>()
rowOffsets[0] = rowOffset
val galaxyRows = galaxies.asSequence().map { it.coordinate.row }.toSet()
(0..<numOfRows).asSequence().filter { !galaxyRows.contains(it) }.forEach { row ->
rowOffset += expansionRate - 1
rowOffsets[row] = rowOffset
}
var columnOffset = 0L
val columnOffsets = TreeMap<Long, Long>()
columnOffsets[0] = columnOffset
val galaxyColumns = galaxies.asSequence().map { it.coordinate.column }.toSet()
(0..<numOfColumns).asSequence().filter { !galaxyColumns.contains(it) }.forEach { column ->
columnOffset += expansionRate - 1
columnOffsets[column] = columnOffset
}
return Universe(
numOfRows + rowOffset,
numOfColumns + columnOffset,
galaxies.map { galaxy ->
val row = galaxy.coordinate.row
val column = galaxy.coordinate.column
val ro = rowOffsets.floorEntry(row).value!!
val co = columnOffsets.floorEntry(column).value!!
Galaxy(Coordinate(row + ro, column + co))
}
.toSet()
)
}
fun toImage(): String {
val galaxyColumnsByRow =
galaxies.groupBy({ it.coordinate.row }) { it.coordinate.column }.mapValues { it.value.toSet() }
return (0..<numOfRows).asSequence().map { row ->
val galaxiesInTheRow = galaxyColumnsByRow[row] ?: emptySet()
(0..<numOfColumns).asSequence().map { column -> if (galaxiesInTheRow.contains(column)) '#' else '.' }.toList()
}.joinToString("\n") { it.joinToString("") }
}
fun sumOfShortestPaths(): Long {
val galaxyList = galaxies.toList()
var result = 0L
for (i in galaxyList.indices) {
val galaxy1 = galaxyList[i]
for (j in (i + 1)..<galaxyList.size) {
val galaxy2 = galaxyList[j]
result += galaxy1.distanceTo(galaxy2)
}
}
return result
}
}
data class Galaxy(val coordinate: Coordinate) {
fun distanceTo(that: Galaxy): Long = coordinate.distanceTo(that.coordinate)
}
data class Coordinate(val row: Long, val column: Long) {
constructor(row: Int, column: Int) : this(row.toLong(), column.toLong())
fun distanceTo(that: Coordinate): Long = (row - that.row).absoluteValue + (column - that.column).absoluteValue
}