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