### Kotlin Solution

#### Part 1

This one wasn't too bad. I had a false start trying to flood-fill with multiple generators, and that got silly really quickly.

Then I realized I could just build a big array, chunk through item by item, remove any symbol on an edge, and then just count the places they reached.

fun String.parsePoint() = this.split(""", """).let { found ->
Point(found[0].toInt(), found[1].toInt())
}

fun Point.manhattanDistance(b: Point): Int =
(x - b.x).absoluteValue + (y - b.y).absoluteValue

val alpha = ('a'..'z') + ('A'..'Z')

val minX = input.minBy { (x, y) -> x }!!.x
val minY = input.minBy { (x, y) -> y }!!.y
val maxX = input.maxBy { (x, y) -> x }!!.x
val maxY = input.maxBy { (x, y) -> y }!!.y

val map = input.mapIndexed { i, point ->
point to alpha[i].toString()
}.toMap().toMutableMap()

val output =
(minY..maxY).map { y ->
(minX..maxX).map { x ->
map.toList().groupBy { (k, _) ->
(x to y).manhattanDistance(k)
}.minByKey()!!.value.let { closest ->
when {
closest.count() > 1 -> "."
else -> closest.first().second
}
}
}
}

return map.values.filter { v ->
v !in output.first()
&& v !in output.map { it.first() }
&& v !in output.last()
&& v !in output.map { it.last() }
}.map { v ->
output.flatten().count { it == v }
}.max()
}

#### Part 2

This is where I got stuck a bit trying to optimize instead of just letting it finish this code's 30 second cycle.

I'm not happy I couldn't figure out the math, but I'll post some pictures I've generated from my output in penance.

val dist = 10000

val minX = input.minBy { (x, y) -> x }!!.x
val minY = input.minBy { (x, y) -> y }!!.y
val maxX = input.maxBy { (x, y) -> x }!!.x
val maxY = input.maxBy { (x, y) -> y }!!.y

val ptc =
(maxX - dist..minX + dist).map { x ->
println("row \$x")
(maxY - dist..minY + dist).map { y ->
x to y
}
.filter { point -> input.sumBy(point::manhattanDistance) < dist }
}.fold(emptySet<Point>()) { a, b ->
a + b
}

return ptc.count()
}

You don't have to construct an array; you can just iterate over min(x)..max(x) and min(y)..max(y) and add + to the nearest input point.

The promised images!