Day 12 finally. I hate you.
This commit is contained in:
parent
9a8b316122
commit
90cf5a8335
10
src/Utils.kt
10
src/Utils.kt
@ -75,6 +75,13 @@ class CharGrid {
|
|||||||
val data: Array<CharArray>
|
val data: Array<CharArray>
|
||||||
val bChar: Char
|
val bChar: Char
|
||||||
|
|
||||||
|
constructor(width: Int, height: Int, borderChar: Char = ' ') {
|
||||||
|
bChar = borderChar
|
||||||
|
this.width = width
|
||||||
|
this.height = height
|
||||||
|
data = Array(height) { CharArray(width) { bChar } }
|
||||||
|
}
|
||||||
|
|
||||||
constructor(input: List<String>, borderChar: Char = ' ') {
|
constructor(input: List<String>, borderChar: Char = ' ') {
|
||||||
bChar = borderChar
|
bChar = borderChar
|
||||||
width = input[0].length
|
width = input[0].length
|
||||||
@ -196,6 +203,9 @@ class CharGrid {
|
|||||||
fun matchRelative(c: Int, r: Int, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
fun matchRelative(c: Int, r: Int, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
||||||
relposes.filter { predicate(get(c + it.dc, r + it.dr)) }
|
relposes.filter { predicate(get(c + it.dc, r + it.dr)) }
|
||||||
|
|
||||||
|
fun matchRelativeRelPos(pos: RelPos, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
||||||
|
relposes.filter { predicate(get(pos.translate(it))) }
|
||||||
|
|
||||||
fun matchAbsoluteRelPos(pos: RelPos, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
fun matchAbsoluteRelPos(pos: RelPos, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
||||||
relposes.map { pos.translate(it) }.filter { predicate(get(it)) }
|
relposes.map { pos.translate(it) }.filter { predicate(get(it)) }
|
||||||
|
|
||||||
|
@ -54,53 +54,29 @@ MMMISSJEEE
|
|||||||
fun part2(input: List<String>): Int {
|
fun part2(input: List<String>): Int {
|
||||||
val grid = CharGrid(input)
|
val grid = CharGrid(input)
|
||||||
var sum = 0
|
var sum = 0
|
||||||
|
val magic = listOf(3, 5, 10, 12)
|
||||||
for (p in grid.generateGridPos()) {
|
for (p in grid.generateGridPos()) {
|
||||||
val c = grid[p]
|
val c = grid[p]
|
||||||
if (c != '.') {
|
if (c != '.') {
|
||||||
println("$p: $c")
|
|
||||||
val areaPos = HashSet<RelPos>()
|
val areaPos = HashSet<RelPos>()
|
||||||
val fence = HashSet<RelPos>()
|
|
||||||
var newPos = setOf(p)
|
var newPos = setOf(p)
|
||||||
while (newPos.isNotEmpty()) {
|
while (newPos.isNotEmpty()) {
|
||||||
val newSeeds = HashSet<RelPos>()
|
val newSeeds = HashSet<RelPos>()
|
||||||
for (np in newPos) {
|
for (np in newPos) {
|
||||||
areaPos.add(np)
|
areaPos.add(np)
|
||||||
grid[np] = c.lowercaseChar()
|
grid[np] = '.'
|
||||||
newSeeds.addAll(grid.matchAbsoluteRelPos(np, CharGrid.PLUS_POS) { it == c })
|
newSeeds.addAll(grid.matchAbsoluteRelPos(np, CharGrid.PLUS_POS) { it == c })
|
||||||
fence.addAll(grid.matchRelative(np.dc, np.dr, CharGrid.BOX_POS) { it.uppercaseChar() != c }
|
|
||||||
.map { RelPos(np.dc * 2 + it.dc, np.dr * 2 + it.dr) })
|
|
||||||
}
|
}
|
||||||
newPos = newSeeds
|
newPos = newSeeds
|
||||||
}
|
}
|
||||||
var turns = 0
|
val corners = areaPos.sumOf {
|
||||||
while (fence.isNotEmpty()) {
|
val plusCode = CharGrid.PLUS_POS.mapIndexed { index, relPos -> if (areaPos.contains(it.translate(relPos))) 1 shl index else 0 }.sum()
|
||||||
val f1 = fence.first()
|
val crossCode = CharGrid.CROSS_POS.mapIndexed { index, relPos -> if (areaPos.contains(it.translate(relPos))) 1 shl index else 0 }.sum()
|
||||||
var dir = CharGrid.PLUS_POS.find { fence.contains(f1.translate(it)) }
|
val outer = magic.count { plusCode and it == 0 }
|
||||||
if (dir == null) {
|
val inner = magic.filterIndexed { i, m -> (plusCode and m == m) && (crossCode and (1 shl i) == 0) }.count()
|
||||||
fence.remove(f1)
|
outer + inner
|
||||||
turns += 2
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
sum += areaPos.size * corners
|
||||||
// 851006 too low
|
|
||||||
// 852491 too high
|
|
||||||
val initDir = dir
|
|
||||||
var rp = f1
|
|
||||||
while (fence.isNotEmpty()) {
|
|
||||||
fence.remove(rp)
|
|
||||||
if (fence.contains(rp.translate(dir!!))) {
|
|
||||||
rp = rp.translate(dir)
|
|
||||||
} else {
|
|
||||||
dir = CharGrid.PLUS_POS.find { fence.contains(rp.translate(it)) } ?: break
|
|
||||||
rp = rp.translate(dir)
|
|
||||||
turns++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (initDir != dir) turns++
|
|
||||||
}
|
|
||||||
println("$c Area: ${areaPos.size} Fence: ${fence.size} Discount: $turns = ${areaPos.size * turns}")
|
|
||||||
areaPos.forEach { grid[it] = '.' }
|
|
||||||
sum += areaPos.size * turns
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sum
|
return sum
|
||||||
|
Loading…
Reference in New Issue
Block a user