Compare commits
No commits in common. "a0149c26e084f77ac72b20738d29e1ad4f9a6665" and "55271e210d3b6539db00a8ec534d277dbe7f545b" have entirely different histories.
a0149c26e0
...
55271e210d
@ -1,127 +0,0 @@
|
|||||||
package be.vandewalleh.aoc.days
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
data class Point(val x: Int, val y: Int, val z: Int)
|
|
||||||
|
|
||||||
data class Point4(val x: Int, val y: Int, val z: Int, val blah: Int)
|
|
||||||
|
|
||||||
enum class State { Active, Inactive }
|
|
||||||
|
|
||||||
@Day(17)
|
|
||||||
class Day17(@Lines val input: Input<List<String>>) {
|
|
||||||
|
|
||||||
private fun neighbours3(point: Point): List<Point> {
|
|
||||||
val points = mutableListOf<Point>()
|
|
||||||
for (x in point.x - 1..point.x + 1) {
|
|
||||||
for (y in point.y - 1..point.y + 1) {
|
|
||||||
for (z in point.z - 1..point.z + 1) {
|
|
||||||
val generatedPoint = Point(x, y, z)
|
|
||||||
if (generatedPoint != point)
|
|
||||||
points.add(generatedPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check(points.size == 26) { "Points size was ${points.size}" }
|
|
||||||
return points
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun neighbours4(point: Point4): List<Point4> {
|
|
||||||
val points = mutableListOf<Point4>()
|
|
||||||
for (x in point.x - 1..point.x + 1) {
|
|
||||||
for (y in point.y - 1..point.y + 1) {
|
|
||||||
for (z in point.z - 1..point.z + 1) {
|
|
||||||
for (blah in point.blah - 1..point.blah + 1) {
|
|
||||||
val generatedPoint = Point4(x, y, z, blah)
|
|
||||||
if (generatedPoint != point)
|
|
||||||
points.add(generatedPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check(points.size == 80) { "Points size was ${points.size}" }
|
|
||||||
return points
|
|
||||||
}
|
|
||||||
|
|
||||||
fun part1(): Int {
|
|
||||||
val grid = parseGrid3()
|
|
||||||
repeat(6) { step3(grid) }
|
|
||||||
return grid.values.count { it == State.Active }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseGrid3(): MutableMap<Point, State> {
|
|
||||||
val grid = mutableMapOf<Point, State>()
|
|
||||||
input.value.forEachIndexed { index, row ->
|
|
||||||
row.forEachIndexed { col, char ->
|
|
||||||
val state = if (char == '#') State.Active else State.Inactive
|
|
||||||
grid[Point(index, col, 0)] = state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return grid
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseGrid4(): MutableMap<Point4, State> {
|
|
||||||
val grid = mutableMapOf<Point4, State>()
|
|
||||||
input.value.forEachIndexed { index, row ->
|
|
||||||
row.forEachIndexed { col, char ->
|
|
||||||
val state = if (char == '#') State.Active else State.Inactive
|
|
||||||
grid[Point4(index, col, 0, 0)] = state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return grid
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun step3(grid: MutableMap<Point, State>) {
|
|
||||||
val pointsToConsider = grid.keys.flatMap { neighbours3(it) }.toSet()
|
|
||||||
|
|
||||||
val modifications = mutableMapOf<Point, State>()
|
|
||||||
for (point in pointsToConsider) {
|
|
||||||
val neighbours = neighbours3(point)
|
|
||||||
val activeNeighboursCount = neighbours.count { grid[it] ?: State.Inactive == State.Active }
|
|
||||||
val state = grid[point] ?: State.Inactive
|
|
||||||
if (state == State.Active && activeNeighboursCount !in 2..3) {
|
|
||||||
modifications[point] = State.Inactive
|
|
||||||
} else if (activeNeighboursCount == 3) {
|
|
||||||
modifications[point] = State.Active
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ((point, state) in modifications) {
|
|
||||||
grid[point] = state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun step4(grid: MutableMap<Point4, State>) {
|
|
||||||
val pointsToConsider = grid.keys.flatMap { neighbours4(it) }.toSet()
|
|
||||||
|
|
||||||
val modifications = mutableMapOf<Point4, State>()
|
|
||||||
for (point in pointsToConsider) {
|
|
||||||
val neighbours = neighbours4(point)
|
|
||||||
val activeNeighboursCount = neighbours.count { grid[it] ?: State.Inactive == State.Active }
|
|
||||||
val state = grid[point] ?: State.Inactive
|
|
||||||
if (state == State.Active && activeNeighboursCount !in 2..3) {
|
|
||||||
modifications[point] = State.Inactive
|
|
||||||
} else if (activeNeighboursCount == 3) {
|
|
||||||
modifications[point] = State.Active
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ((point, state) in modifications) {
|
|
||||||
grid[point] = state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun part2(): Int {
|
|
||||||
val grid = parseGrid4()
|
|
||||||
repeat(6) { step4(grid) }
|
|
||||||
return grid.values.count { it == State.Active }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main() = with(createDay<Day17>(
|
|
||||||
)) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
##..#.#.
|
|
||||||
#####.##
|
|
||||||
#######.
|
|
||||||
#..#..#.
|
|
||||||
#.#...##
|
|
||||||
..#....#
|
|
||||||
....#..#
|
|
||||||
..##.#..
|
|
||||||
@ -6,7 +6,6 @@ import io.micronaut.core.annotation.AnnotationMetadataDelegate
|
|||||||
import io.micronaut.core.annotation.AnnotationMetadataProvider
|
import io.micronaut.core.annotation.AnnotationMetadataProvider
|
||||||
import io.micronaut.core.annotation.AnnotationValue
|
import io.micronaut.core.annotation.AnnotationValue
|
||||||
import io.micronaut.core.beans.BeanIntrospection
|
import io.micronaut.core.beans.BeanIntrospection
|
||||||
import java.io.File
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal inline fun <reified T> getIntrospection(): BeanIntrospection<T> =
|
internal inline fun <reified T> getIntrospection(): BeanIntrospection<T> =
|
||||||
@ -22,15 +21,3 @@ internal inline fun <reified T : Annotation> AnnotationMetadataProvider.hasAnnot
|
|||||||
findAnnotation(T::class.java).isPresent
|
findAnnotation(T::class.java).isPresent
|
||||||
|
|
||||||
inline fun <reified T> createDay() = BeanContext.run().getBean<T>()
|
inline fun <reified T> createDay() = BeanContext.run().getBean<T>()
|
||||||
|
|
||||||
// A custom resourceLoader that returns a string should be more appropriate but ¯\_(ツ)_/¯
|
|
||||||
fun BeanContext.registerExampleLoader(example: String) {
|
|
||||||
registerSingleton(TempFileResourceLoader(File.createTempFile("aoc-example", ".txt").apply {
|
|
||||||
writeText(example)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> createDay(example: String): T = BeanContext.build()
|
|
||||||
.apply { registerExampleLoader(example) }
|
|
||||||
.start()
|
|
||||||
.getBean()
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package be.vandewalleh.aoc.utils.input
|
package be.vandewalleh.aoc.utils.input
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -20,7 +19,3 @@ class ResourceLoaderImpl : ResourceLoader {
|
|||||||
return Path.of(url.toURI())
|
return Path.of(url.toURI())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TempFileResourceLoader(private val tempFile: File) : ResourceLoader {
|
|
||||||
override fun ofDay(day: Int) = Path.of(tempFile.path)
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user