Day12: part 1 solved, just got an idea how to solve part 2, but not implemented yet

This commit is contained in:
2019-12-14 15:19:01 +01:00
parent f36344edbd
commit ab7a6aa486
3 changed files with 130 additions and 0 deletions

View 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>"
}
}
}

View 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>

View 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>