Day12: part 1 solved, just got an idea how to solve part 2, but not implemented yet
This commit is contained in:
122
src/main/kotlin/com/basdado/adventofcode/day12/Day12.kt
Normal file
122
src/main/kotlin/com/basdado/adventofcode/day12/Day12.kt
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package com.basdado.adventofcode.day12
|
||||||
|
|
||||||
|
import com.basdado.adventofcode.lines
|
||||||
|
import java.lang.Long.compare
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
import java.util.stream.LongStream
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
const val DAY12_INPUT_PATH = "/day/12/input.txt"
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
Day12.puzzle1()
|
||||||
|
Day12.puzzle2()
|
||||||
|
}
|
||||||
|
|
||||||
|
object Day12 {
|
||||||
|
|
||||||
|
fun puzzle1() {
|
||||||
|
val positions = parseInput()
|
||||||
|
val velocities = Array(positions.size) { Vector3l.ZERO }
|
||||||
|
|
||||||
|
repeat(1000) {
|
||||||
|
println("$it: ${positions.toList()}")
|
||||||
|
// println("$it: energy: ${energy(positions, velocities)}")
|
||||||
|
applyGravity(positions, velocities)
|
||||||
|
applyVelocity(positions, velocities)
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Total: ${energy(positions, velocities)}")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun puzzle2() {
|
||||||
|
|
||||||
|
val positions = parseInput()
|
||||||
|
val velocities = Array(positions.size) { Vector3l.ZERO }
|
||||||
|
|
||||||
|
val initialPositions = positions.clone()
|
||||||
|
val initialVelocities = velocities.clone()
|
||||||
|
val initialRelativePositions = relative(positions)
|
||||||
|
|
||||||
|
println(LongStream.iterate(0) { it + 1 }
|
||||||
|
.peek {
|
||||||
|
applyGravity(positions, velocities)
|
||||||
|
applyVelocity(positions, velocities)
|
||||||
|
if (it % 100000L == 0L) println("$it: pos: ${positions.toList()}, vel: ${velocities.toList()}")
|
||||||
|
}
|
||||||
|
.dropWhile { !(positions.contentEquals(initialRelativePositions) && velocities.contentEquals(initialVelocities)) }
|
||||||
|
.findFirst()!!
|
||||||
|
)
|
||||||
|
|
||||||
|
// Oh wait, X, Y and Z are completely independent, so we could just simulate the universe per component, and
|
||||||
|
// then find the lowest number that's divisible by all three numbers
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun energy(positions: Array<Vector3l>, velocities: Array<Vector3l>): Long {
|
||||||
|
return positions.indices.map { i -> positions[i].manhattan() * velocities[i].manhattan() }.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyGravity(positions: Array<Vector3l>, velocities: Array<Vector3l>) {
|
||||||
|
|
||||||
|
for (i in positions.indices) {
|
||||||
|
for (j in (i + 1) until positions.size) {
|
||||||
|
val compare = positions[i].compareComponents(positions[j])
|
||||||
|
velocities[i] -= compare
|
||||||
|
velocities[j] += compare
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyVelocity(positions: Array<Vector3l>, velocities: Array<Vector3l>) {
|
||||||
|
for (i in positions.indices) {
|
||||||
|
positions[i] += velocities[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun relative(positions: Array<Vector3l>): Array<Vector3l> {
|
||||||
|
return Array(positions.size) { positions[it] - positions[0] }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseInput(): Array<Vector3l> {
|
||||||
|
return lines(DAY12_INPUT_PATH)
|
||||||
|
.map { Regex("^<x=(-?\\d+)\\s*,\\s*y=(-?\\d+)\\s*,\\s*z=(-?\\d+)>$").matchEntire(it) }
|
||||||
|
.filter { it != null }
|
||||||
|
.map { Vector3l(it!!.groups[1]!!.value.toLong(), it.groups[2]!!.value.toLong(), it.groups[3]!!.value.toLong()) }
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class Vector3l(
|
||||||
|
val x: Long,
|
||||||
|
val y: Long,
|
||||||
|
val z: Long
|
||||||
|
) {
|
||||||
|
operator fun plus(other: Vector3l) = Vector3l(x + other.x, y + other.y, z + other.z)
|
||||||
|
operator fun minus(other: Vector3l) = Vector3l(x - other.x, y - other.y, z - other.z)
|
||||||
|
|
||||||
|
fun manhattan() = abs(x) + abs(y) + abs(z)
|
||||||
|
|
||||||
|
fun compareComponents(other: Vector3l) = Vector3l(
|
||||||
|
x.compareTo(other.x).toLong(),
|
||||||
|
y.compareTo(other.y).toLong(),
|
||||||
|
z.compareTo(other.z).toLong()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun sign() = Vector3l(
|
||||||
|
if (x == 0L) 0 else if (x > 0L) 1L else -1L,
|
||||||
|
if (y == 0L) 0 else if (y > 0L) 1L else -1L,
|
||||||
|
if (z == 0L) 0 else if (z > 0L) 1L else -1L)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ZERO = Vector3l(0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "<x=$x, y=$y, z=$z>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/main/resources/day/12/ex1.txt
Normal file
4
src/main/resources/day/12/ex1.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<x=-1, y=0, z=2>
|
||||||
|
<x=2, y=-10, z=-7>
|
||||||
|
<x=4, y=-8, z=8>
|
||||||
|
<x=3, y=5, z=-1>
|
||||||
4
src/main/resources/day/12/input.txt
Normal file
4
src/main/resources/day/12/input.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<x=6, y=10, z=10>
|
||||||
|
<x=-9, y=3, z=17>
|
||||||
|
<x=9, y=-4, z=14>
|
||||||
|
<x=4, y=14, z=4>
|
||||||
Reference in New Issue
Block a user