Další z ne-úplně lehkých dnů. Nyní již bylo zapotřebí trochy odhadu a víry, že se člověk vydal správnou cestou 🙂 .
import com.svetylkovo.rojo.Rojo import com.svetylkovo.rojo.annotations.Group import com.svetylkovo.rojo.annotations.Regex import java.io.ByteArrayOutputStream import java.io.File import java.io.OutputStream @Regex("(-?\\d+).+?(-?\\d+).+?(-?\\d+).+?(-?\\d+)") data class Star( @Group(1) var x: Long = 0, @Group(2) var y: Long = 0, @Group(3) var vx: Int = 0, @Group(4) var vy: Int = 0 ) { /** * Direction can be either 1 (forward movement) or -1 (backward movement) */ fun move(direction: Int) { x += vx * direction y += vy * direction } } class NightSky(val stars: List<Star>) { var width: Long = 0 var height: Long = 0 val size get() = width * height private fun transposeStarsToTopLeft() { val xOffset = stars.asSequence() .map { it.x } .min() ?.times(-1) ?: 0 val yOffset = stars.asSequence() .map { it.y } .min() ?.times(-1) ?: 0 stars.forEach { it.x += xOffset it.y += yOffset } width = stars.maxBy { it.x }?.x ?: 1 height = stars.maxBy { it.y }?.y ?: 1 } fun moveTheStars(direction: Int = 1) { if (direction == 1) { transposeStarsToTopLeft() stars.forEach { it.move(direction) } } else { stars.forEach { it.move(direction) } transposeStarsToTopLeft() } } fun writeSkyState(out: OutputStream) { val writer = out.writer() val newline = "\n" val star = "#" val emptyness = "." val starsPosition = stars.asSequence() .map { it.x to it.y } .toHashSet() for (y in 0..height) { for (x in 0..width) { if (x to y in starsPosition) writer.write(star) else writer.write(emptyness) } writer.write(newline) writer.flush() } writer.flush() } fun getSkyStateAsString(): String { val out = ByteArrayOutputStream() writeSkyState(out) return out.toString() } } fun main() { val input = File("input10.txt").readText() val outDir = File("output10").apply { mkdir() } val stars = Rojo.of(Star::class.java).matchList(input) val nightSky = NightSky(stars) var lastSize = Long.MAX_VALUE //A println("Searching for minimal step") var minimalStepNumeber = 0 for (step in 1..20000) { minimalStepNumeber = step nightSky.moveTheStars() if (nightSky.size > lastSize) break else lastSize = nightSky.size } repeat(5) { step -> println("Generating step $step") outDir.resolve("Out$step.txt") .outputStream() .use { nightSky.writeSkyState(it) } nightSky.moveTheStars(-1) } println("Done, let's investigate the files output!") //B println("They would have to wait ${minimalStepNumeber - 2} seconds") }