Day 12, finish part 2 + refactoring
This commit is contained in:
parent
6c5111b38c
commit
b8411307bb
2 changed files with 42 additions and 39 deletions
|
@ -1,21 +1,19 @@
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|
||||||
var part1 = 0
|
var part1 = 0
|
||||||
var part2 = 0
|
var part2 = 0
|
||||||
|
|
||||||
while (all.isNotEmpty()) {
|
while (all.isNotEmpty()) {
|
||||||
val start = all.elementAt(0)
|
val start = all.elementAt(0)
|
||||||
val (area, fenceLength, fenceSides) = input.floodFill(start)
|
val (area, fenceLength, fenceSides) = input.floodFill(start)
|
||||||
part1 += area * fenceLength
|
part1 += area * fenceLength
|
||||||
part2 += area * fenceSides
|
part2 += area * fenceSides
|
||||||
|
|
||||||
println("$area x $fenceSides")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Part 1: $part1")
|
println("Part 1: $part1")
|
||||||
println("Part 2: $part2")
|
println("Part 2: $part2")
|
||||||
}
|
}
|
||||||
|
|
||||||
val input = CharGrid.read("day12-sample.txt")
|
val input = CharGrid.read("day12.txt")
|
||||||
val all = sequence {
|
val all = sequence {
|
||||||
for (y in 0..<input.height) {
|
for (y in 0..<input.height) {
|
||||||
for (x in 0..<input.width) {
|
for (x in 0..<input.width) {
|
||||||
|
@ -32,33 +30,29 @@ fun CharGrid.floodFill(start: Grid.Coordinate): Triple<Int, Int, Int> {
|
||||||
|
|
||||||
all.removeAll(visited)
|
all.removeAll(visited)
|
||||||
|
|
||||||
println(fence.horizontalSides.flatMap { it.value.sides.values.toSet().map { side -> it.key to side} })
|
|
||||||
println(fence.verticalSides.flatMap { it.value.sides.values.toSet().map { side -> it.key to side} })
|
|
||||||
|
|
||||||
return Triple(visited.count(), fence.length, fence.sides)
|
return Triple(visited.count(), fence.length, fence.sides)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Fence {
|
class Fence {
|
||||||
var length = 0
|
val horizontalSides = mutableMapOf<Int, SideList>()
|
||||||
|
val verticalSides = mutableMapOf<Int, SideList>()
|
||||||
|
val length
|
||||||
|
get() = horizontalSides.values.sumOf { it.length } +
|
||||||
|
verticalSides.values.sumOf { it.length }
|
||||||
|
|
||||||
val sides
|
val sides
|
||||||
get() = horizontalSides.values.fold(0) { acc, sides -> acc + sides.count } +
|
get() = horizontalSides.values.sumOf { it.count } +
|
||||||
verticalSides.values.fold(0) { acc, sides -> acc + sides.count }
|
verticalSides.values.sumOf { it.count }
|
||||||
|
|
||||||
fun add(coordinate: Grid.Coordinate, horizontal: Boolean) {
|
|
||||||
length += 1
|
|
||||||
|
|
||||||
|
fun add(coordinate: Grid.Coordinate, horizontal: Boolean, first: Boolean) {
|
||||||
if (horizontal) {
|
if (horizontal) {
|
||||||
horizontalSides.getOrPut(coordinate.y) { SideList() }.add(coordinate.x)
|
horizontalSides.getOrPut(coordinate.y) { SideList() }.add(coordinate.x, first)
|
||||||
} else {
|
} else {
|
||||||
verticalSides.getOrPut(coordinate.x) { SideList() }.add(coordinate.y)
|
verticalSides.getOrPut(coordinate.x) { SideList() }.add(coordinate.y, first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Side(val first: Boolean, val start: Int, val end: Int = start) {
|
||||||
val horizontalSides = mutableMapOf<Int, SideList>()
|
|
||||||
val verticalSides = mutableMapOf<Int, SideList>()
|
|
||||||
|
|
||||||
data class Side(val start: Int, val end: Int = start) {
|
|
||||||
init {
|
init {
|
||||||
require(start <= end)
|
require(start <= end)
|
||||||
}
|
}
|
||||||
|
@ -67,31 +61,33 @@ class Fence {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SideList {
|
class SideList {
|
||||||
val sides = mutableMapOf<Int, Side>()
|
val sidesByPosition = mutableMapOf<Int, Side>()
|
||||||
val count: Int get() = sides.values.toSet().count()
|
val sides: Set<Side> get() = sidesByPosition.values.toSet()
|
||||||
|
val count: Int get() = sides.count()
|
||||||
|
val length: Int get() = sides.sumOf { it.length }
|
||||||
|
|
||||||
fun add(position: Int) {
|
fun add(position: Int, first: Boolean) {
|
||||||
if (sides.containsKey(position)) return
|
if (sidesByPosition.containsKey(position)) return
|
||||||
|
|
||||||
val before = sides[position - 1]
|
val before = sidesByPosition[position - 1]?.takeIf { it.first == first }
|
||||||
val after = sides[position + 1]
|
val after = sidesByPosition[position + 1]?.takeIf { it.first == first }
|
||||||
|
|
||||||
val newSide = when {
|
val newSide = when {
|
||||||
before != null && after != null -> Side(before.start, after.end)
|
before != null && after != null -> Side(first, before.start, after.end)
|
||||||
before != null -> Side(before.start, position)
|
before != null -> Side(first, before.start, position)
|
||||||
after != null -> Side(position, after.end)
|
after != null -> Side(first, position, after.end)
|
||||||
else -> Side(position)
|
else -> Side(first, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(before == null || newSide.start == before.start)
|
assert(before == null || newSide.start == before.start)
|
||||||
assert(after == null ||newSide.end == after.end)
|
assert(after == null || newSide.end == after.end)
|
||||||
assert(position in newSide.start..newSide.end)
|
assert(position in newSide.start..newSide.end)
|
||||||
|
|
||||||
for (pos in newSide.start..newSide.end) {
|
for (pos in newSide.start..newSide.end) {
|
||||||
sides[pos] = newSide
|
sidesByPosition[pos] = newSide
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sides[position] === newSide)
|
assert(sidesByPosition[position] === newSide)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +104,9 @@ fun CharGrid.floodFill(start: Grid.Coordinate, type: Char, visited: MutableSet<G
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inside(neighbor) || this[neighbor] != type) {
|
if (!inside(neighbor) || this[neighbor] != type) {
|
||||||
fence.add(neighbor, direction == Direction.North || direction == Direction.South)
|
val first = direction == Direction.North || direction == Direction.West
|
||||||
|
val fencePosition = if (first) neighbor else start
|
||||||
|
fence.add(fencePosition, direction == Direction.North || direction == Direction.South, first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
EEEEE
|
RRRRIICCFF
|
||||||
EXXXX
|
RRRRIICCCF
|
||||||
EEEEE
|
VVRRRCCFFF
|
||||||
EXXXX
|
VVRCCCJFFF
|
||||||
EEEEE
|
VVVVCJJCFE
|
||||||
|
VVIVCCJJEE
|
||||||
|
VVIIICJJEE
|
||||||
|
MIIIIIJJEE
|
||||||
|
MIIISIJEEE
|
||||||
|
MMMISSJEEE
|
Loading…
Add table
Reference in a new issue