diff --git a/days/src/main/kotlin/Day24.kt b/days/src/main/kotlin/Day24.kt index 54a43a3..e90aa48 100644 --- a/days/src/main/kotlin/Day24.kt +++ b/days/src/main/kotlin/Day24.kt @@ -4,6 +4,8 @@ import be.vandewalleh.aoc.utils.input.Day import be.vandewalleh.aoc.utils.input.Input import be.vandewalleh.aoc.utils.input.Lines import be.vandewalleh.aoc.utils.input.createDay +import org.eclipse.collections.api.bag.Bag +import org.eclipse.collections.api.bag.MutableBag import org.eclipse.collections.api.factory.Bags @Day(24) @@ -20,29 +22,55 @@ class Day24(@Lines val input: Input>) { val coordinates = coordinates } - private data class Tile(val directions: List) + private fun parseTile(line: String) = "e|se|sw|w|nw|ne".toRegex() + .findAll(line) + .flatMap { it.groupValues } + .map { Direction.valueOf(it.toUpperCase()) } + .toList() - private fun parseTile(line: String): Tile { - val re = "e|se|sw|w|nw|ne".toRegex() - val directions = re.findAll(line).flatMap { it.groupValues }.map { Direction.valueOf(it.toUpperCase()) } - return Tile(directions.toList()) + private val tiles = input.value.map { parseTile(it) }.map { + it.map { it.coordinates } + .reduce { acc, ints -> intArrayOf(acc[0] + ints[0], acc[1] + ints[1], acc[2] + ints[2]) } + .toList() } - fun part1() { - val tiles = input.value.map { parseTile(it) } - val bag = Bags.mutable.empty>() - for (tile in tiles) { - val encountered = tile.directions - .map { it.coordinates } - .reduce { acc, ints -> intArrayOf(acc[0] + ints[0], acc[1] + ints[1], acc[2] + ints[2]) } - .toList() - bag.add(encountered) + fun part1() = Bags.immutable.ofAll(tiles).selectBlacks().size() + + private fun Bag>.selectBlacks() = selectByOccurrences { it % 2 == 1 } + + private fun List.adjacents(): List> { + val (x, y, z) = this + return listOf( + listOf(x + 1, y - 1, z), + listOf(x, y - 1, z + 1), + listOf(x - 1, y, z + 1), + listOf(x - 1, y + 1, z), + listOf(x, y + 1, z - 1), + listOf(x + 1, y, z - 1), + ) + } + + // black -> odd + // white -> even || not in bag -> !in black + private fun day(bag: MutableBag>) { + val blacks = bag.selectBlacks().toSet() + + val all = (bag + bag.flatMap { it.adjacents() }).toSet() + + for (tile in all) { + val adjacents = tile.adjacents() + val adjacentBlacks = adjacents.count { it in blacks } + val isBlack = tile in blacks + + if (isBlack && (adjacentBlacks == 0 || adjacentBlacks > 2)) bag.setOccurrences(tile, 2) + else if (!isBlack && adjacentBlacks == 2) bag.setOccurrences(tile, 1) } - println(bag.selectByOccurrences { it % 2 == 1 }.size) } - fun part2() { - + fun part2(): Int { + val bag = Bags.mutable.ofAll(tiles) + repeat(100) { day(bag) } + return bag.selectBlacks().size() } }