Day 12 Part 2 not correct.
This commit is contained in:
parent
778b38b3a4
commit
9a8b316122
@ -196,6 +196,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 matchAbsoluteRelPos(pos: RelPos, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
||||||
|
relposes.map { pos.translate(it) }.filter { predicate(get(it)) }
|
||||||
|
|
||||||
fun marchMatching(pos: RelPos, relposes: Iterable<RelPos>, predicate: (char: Char) -> Boolean): List<RelPos> =
|
fun marchMatching(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)) }
|
||||||
|
|
||||||
@ -215,7 +218,7 @@ class CharGrid {
|
|||||||
val topBottom = CharArray(width + 2) { borderChar }
|
val topBottom = CharArray(width + 2) { borderChar }
|
||||||
return CharGrid(Array(height + 2) {
|
return CharGrid(Array(height + 2) {
|
||||||
if (it == 0 || it == height + 1) topBottom else
|
if (it == 0 || it == height + 1) topBottom else
|
||||||
CharArray(width + 2) { r -> if (r == 0 || r == width + 1) borderChar else get(it - 1, r - 1) }
|
CharArray(width + 2) { r -> if (r == 0 || r == width + 1) borderChar else get(r - 1, it - 1) }
|
||||||
}, borderChar)
|
}, borderChar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
122
src/aoc2024/Day12.kt
Normal file
122
src/aoc2024/Day12.kt
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package aoc2024
|
||||||
|
|
||||||
|
import CharGrid
|
||||||
|
import RelPos
|
||||||
|
import println
|
||||||
|
import readInput
|
||||||
|
|
||||||
|
/*
|
||||||
|
--- Day 12: Garden Groups ---
|
||||||
|
https://adventofcode.com/2024/day/12
|
||||||
|
*/
|
||||||
|
fun main() {
|
||||||
|
|
||||||
|
val inlineTestInput = """
|
||||||
|
RRRRIICCFF
|
||||||
|
RRRRIICCCF
|
||||||
|
VVRRRCCFFF
|
||||||
|
VVRCCCJFFF
|
||||||
|
VVVVCJJCFE
|
||||||
|
VVIVCCJJEE
|
||||||
|
VVIIICJJEE
|
||||||
|
MIIIIIJJEE
|
||||||
|
MIIISIJEEE
|
||||||
|
MMMISSJEEE
|
||||||
|
"""
|
||||||
|
|
||||||
|
fun part1(input: List<String>): Int {
|
||||||
|
val grid = CharGrid(input)
|
||||||
|
var sum = 0
|
||||||
|
for (p in grid.generateGridPos()) {
|
||||||
|
val c = grid[p]
|
||||||
|
if (c != '.') {
|
||||||
|
val areaPos = HashSet<RelPos>()
|
||||||
|
val fence = HashSet<RelPos>()
|
||||||
|
var newPos = setOf(p)
|
||||||
|
while (newPos.isNotEmpty()) {
|
||||||
|
val newSeeds = HashSet<RelPos>()
|
||||||
|
for (np in newPos) {
|
||||||
|
areaPos.add(np)
|
||||||
|
grid[np] = c.lowercaseChar()
|
||||||
|
newSeeds.addAll(grid.matchAbsoluteRelPos(np, CharGrid.PLUS_POS) { it == c })
|
||||||
|
fence.addAll(grid.matchRelative(np.dc, np.dr, CharGrid.PLUS_POS) { it.uppercaseChar() != c }
|
||||||
|
.map { RelPos(np.dc * 2 + it.dc, np.dr * 2 + it.dr) })
|
||||||
|
}
|
||||||
|
newPos = newSeeds
|
||||||
|
}
|
||||||
|
areaPos.forEach { grid[it] = '.' }
|
||||||
|
sum += areaPos.size * fence.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part2(input: List<String>): Int {
|
||||||
|
val grid = CharGrid(input)
|
||||||
|
var sum = 0
|
||||||
|
for (p in grid.generateGridPos()) {
|
||||||
|
val c = grid[p]
|
||||||
|
if (c != '.') {
|
||||||
|
println("$p: $c")
|
||||||
|
val areaPos = HashSet<RelPos>()
|
||||||
|
val fence = HashSet<RelPos>()
|
||||||
|
var newPos = setOf(p)
|
||||||
|
while (newPos.isNotEmpty()) {
|
||||||
|
val newSeeds = HashSet<RelPos>()
|
||||||
|
for (np in newPos) {
|
||||||
|
areaPos.add(np)
|
||||||
|
grid[np] = c.lowercaseChar()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
var turns = 0
|
||||||
|
while (fence.isNotEmpty()) {
|
||||||
|
val f1 = fence.first()
|
||||||
|
var dir = CharGrid.PLUS_POS.find { fence.contains(f1.translate(it)) }
|
||||||
|
if (dir == null) {
|
||||||
|
fence.remove(f1)
|
||||||
|
turns += 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// test if implementation meets criteria from the description, like:
|
||||||
|
val testInput = inlineTestInput.trim().reader().readLines()
|
||||||
|
//val testInput = readInput("aoc2024/Day12_test")
|
||||||
|
val testInputPart1Result = part1(testInput)
|
||||||
|
println("Part 1 Test: $testInputPart1Result")
|
||||||
|
val testInputPart2Result = part2(testInput)
|
||||||
|
println("Part 2 Test: $testInputPart2Result")
|
||||||
|
check(testInputPart1Result == 1930)
|
||||||
|
check(testInputPart2Result == 1206)
|
||||||
|
|
||||||
|
val input = readInput("aoc2024/Day12")
|
||||||
|
part1(input).println()
|
||||||
|
part2(input).println()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user