Day 12
All checks were successful
Solve / example-action (push) Successful in 3m20s

This commit is contained in:
Logiar 2024-12-12 20:51:17 +01:00
parent 0f2b85f2ad
commit 7a1dba17f1
Signed by: Logiar
SSH Key Fingerprint: SHA256:tq77C31em1ZG4oELIHC3k62wq5UzPSXmhqH8g62whIY
2 changed files with 138 additions and 0 deletions

136
day12.kts Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env kotlin
import java.util.Scanner
val scanner = Scanner(System.`in`)
class Map(private val grid: List<List<String>>) {
private val fields = mutableSetOf<Field>()
private val map = mutableListOf<List<Plot>>()
init {
for ((y, line) in grid.withIndex()) {
map.add(line.mapIndexed { x, s -> Plot(Pair(x, y), s) })
}
for (y in 0 until this.getHeight()) {
for (x in 0 until this.getWidth()) {
val plot = getPlot(x, y)
if (!plot.hasField()) {
val field = Field(this)
plot.addField(field)
fields.add(field)
field.expand(plot)
}
}
}
}
fun getWidth(): Int = grid[0].size
fun getHeight(): Int = grid.size
fun getPlot(x: Int, y: Int): Plot = map[y][x]
fun getFields(): Set<Field> = fields
fun getPrice(): Long = fields.sumOf { it.getPrice() }
fun getBulkPrice(): Long = fields.sumOf { it.getBulkPrice() }
}
class Field(private val map: Map) {
private val fieldPlots = mutableSetOf<Plot>()
private val borderPlots = mutableSetOf<Pair<Plot, Plot>>()
fun addPlot(plot: Plot) {
fieldPlots.add(plot)
}
fun expand(plot: Plot) {
val (x, y) = plot.getPosition()
val checkPositions = listOf(Pair(x - 1, y), Pair(x + 1, y), Pair(x, y - 1), Pair(x, y + 1))
for ((checkX, checkY) in checkPositions) {
if (checkX < 0 || checkX >= map.getWidth() || checkY < 0 || checkY >= map.getHeight()) {
addBorder(plot, Plot(Pair(checkX, checkY), "."))
continue
}
val checkedPlot = map.getPlot(checkX, checkY)
if (plot.getType() == checkedPlot.getType()) {
if (!checkedPlot.hasField()) {
checkedPlot.addField(this)
expand(checkedPlot)
}
} else {
addBorder(plot, checkedPlot)
}
}
}
private fun addBorder(plot: Plot, checkedPlot: Plot) {
borderPlots.add(Pair(plot, checkedPlot))
}
fun getPrice(): Long {
return getArea() * getCircumference()
}
fun getArea(): Long = fieldPlots.size.toLong()
fun getCircumference(): Long = borderPlots.size.toLong()
fun getBulkPrice(): Long {
return getArea() * getNumberOfSides()
}
private fun getNumberOfSides(): Long {
val leftBorders = borderPlots.filter { it.first.getPosition().first > it.second.getPosition().first}.map { it.first.getPosition() }
val rightBorders = borderPlots.filter { it.first.getPosition().first < it.second.getPosition().first}.map { it.first.getPosition() }
val topBorders = borderPlots.filter { it.first.getPosition().second > it.second.getPosition().second}.map { it.first.getPosition() }
val bottomBorders = borderPlots.filter { it.first.getPosition().second < it.second.getPosition().second}.map { it.first.getPosition() }
return countSides(leftBorders) + countSides(rightBorders) + countSides(topBorders) + countSides(bottomBorders)
}
private fun countSides(coordinates: List<Pair<Int, Int>>): Long {
val visited = mutableSetOf<Pair<Int, Int>>()
val coordinateSet = coordinates.toSet()
var sideCount = 0
val directions = listOf(Pair(1, 0), Pair(0, 1), Pair(-1, 0), Pair(0, -1))
fun dfs(coord: Pair<Int, Int>) {
val stack = mutableListOf(coord)
while (stack.isNotEmpty()) {
val current = stack.removeLast()
if (current in visited) continue
visited.add(current)
directions.map { (dx, dy) -> Pair(current.first + dx, current.second + dy) }
.filter { it in coordinateSet && it !in visited }
.forEach { stack.add(it) }
}
}
for (coord in coordinates) {
if (coord !in visited) {
sideCount++
dfs(coord)
}
}
return sideCount.toLong()
}
}
class Plot(private val position: Pair<Int, Int>, private val type: String) {
private var field: Field? = null
fun addField(field: Field) {
this.field = field
field.addPlot(this)
}
fun hasField(): Boolean = field != null
fun getPosition(): Pair<Int, Int> = position
fun getType(): String = type
}
val grid = mutableListOf<List<String>>()
while (scanner.hasNextLine()) {
grid.add(scanner.nextLine().split("").filter { it.isNotEmpty() })
}
val map = Map(grid.reversed())
println("The price is: ${map.getPrice()}")
println("The bulk price is ${map.getBulkPrice()}")

2
day12.kts.testvalue Normal file
View File

@ -0,0 +1,2 @@
The price is: 1375476
The bulk price is 821372