Skip to content

Commit

Permalink
Visualize day 14.
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulWoitaschek committed Dec 14, 2024
1 parent e1987ce commit c7b208c
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 17 deletions.
7 changes: 7 additions & 0 deletions 2024/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
plugins {
id("aoc")
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose.compiler)
}

dependencies {
implementation(compose.desktop.common)
implementation(compose.desktop.currentOs)
}
88 changes: 74 additions & 14 deletions 2024/src/main/kotlin/aoc/year2024/Day14.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
package aoc.year2024

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication
import aoc.library.Point
import aoc.library.Puzzle
import aoc.library.print
import aoc.library.aocInput
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.String

object Day14 : Puzzle<Int, Int>(day = 14) {

override fun solvePart1(input: String): Int = solvePart1(input, 101, 103)
private const val DEFAULT_WIDTH = 101
private const val DEFAULT_HEIGHT = 103

override fun solvePart1(input: String): Int = solvePart1(input, DEFAULT_WIDTH, DEFAULT_HEIGHT)

fun solvePart1(
input: String,
Expand All @@ -33,19 +55,16 @@ object Day14 : Puzzle<Int, Int>(day = 14) {
.filterKeys { it != null }.values
.reduce(Int::times)

override fun solvePart2(input: String): Int = generateSequence(parse(input)) { robots ->
robots.map { robot -> robot.step(101, 103) }
}.indexOfFirst { robots ->
hasRobotCluster(robots)
.also { hasCluster ->
if (hasCluster) {
val map = robots.groupingBy { it.position }.eachCount()
map.print {
map[it]?.toString() ?: "."
}
}
}
override fun solvePart2(input: String): Int = solvePart2(input, onStep = {})

private fun solvePart2(
input: String,
onStep: (List<Robot>) -> Unit,
) = generateSequence(parse(input)) { robots ->
robots.map { robot -> robot.step(DEFAULT_WIDTH, DEFAULT_HEIGHT) }
}
.onEach { onStep(it) }
.indexOfFirst(::hasRobotCluster)

private fun hasRobotCluster(robots: List<Robot>): Boolean {
val positions = robots.map { it.position }.toSet()
Expand Down Expand Up @@ -75,4 +94,45 @@ object Day14 : Puzzle<Int, Int>(day = 14) {
),
)
}

@JvmStatic
fun main(args: Array<String>) {
val tileSize = 8.dp
singleWindowApplication(
title = "Advent of Code in Kotlin",
state = WindowState(width = tileSize * DEFAULT_WIDTH, height = tileSize * DEFAULT_HEIGHT),
) {
var state by remember { mutableStateOf<Set<Point>>(emptySet()) }
LaunchedEffect(Unit) {
val steps = mutableListOf<Set<Point>>()
solvePart2(
aocInput(2024, 14),
onStep = {
launch {
steps += it.map { it.position }.toSet()
}
},
)
withContext(Dispatchers.Default) {}
steps.forEach {
delay(1)
state = it
}
}
Column {
repeat(DEFAULT_HEIGHT) { y ->
Row {
repeat(DEFAULT_WIDTH) { x ->
val color = if (Point(x, y) in state) {
Color(0xFF228B22)
} else {
Color(0xFF001F3F)
}
Box(Modifier.size(tileSize).background(color))
}
}
}
}
}
}
}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ kotlin-jvmPlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", versi

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlintGradlePlugin" }
jetbrains-compose = {id="org.jetbrains.compose", version="1.7.1"}
11 changes: 8 additions & 3 deletions library/src/main/kotlin/aoc/library/Input.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ fun <Part1, Part2> Puzzle<Part1, Part2>.solvePart1(): Part1 = solvePart1(input()

fun <Part1, Part2> Puzzle<Part1, Part2>.solvePart2(): Part2 = solvePart2(input())

fun Puzzle<*, *>.input(): String = aocInput(day = day)
fun Puzzle<*, *>.input(): String = aocInput(
year = File(System.getProperty("user.dir")).name.toInt(),
day = day,
)

private fun aocInput(day: Int): String {
val year = File(System.getProperty("user.dir")).name
fun aocInput(
year: Int,
day: Int,
): String {
val file = File("../inputs/$year/$day.txt")
.apply { parentFile.mkdirs() }
if (!file.exists() || file.length() == 0L) {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pluginManagement {
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}

Expand Down

0 comments on commit c7b208c

Please sign in to comment.