Day 10, a day late
This commit is contained in:
@@ -7,10 +7,10 @@ import java.util.stream.Stream
|
||||
|
||||
fun lines(resourceFile: String): Stream<String> {
|
||||
|
||||
val uri = Paths.get(Utils::class.java.getResource(resourceFile).toURI())
|
||||
val env = mapOf(Pair("create", "true"))
|
||||
FileSystems.newFileSystem(uri, env)
|
||||
return Files.lines(uri)
|
||||
val uri = Utils::class.java.getResource(resourceFile).toURI()
|
||||
// val env = mapOf(Pair("create", "true"))
|
||||
// FileSystems.newFileSystem(uri, env)
|
||||
return Files.lines(Paths.get(uri))
|
||||
}
|
||||
|
||||
fun line(resourceFile: String): String {
|
||||
|
||||
@@ -1,33 +1,121 @@
|
||||
const val DAY10_INPUT_PATH = "/day/10/input.txt"
|
||||
package com.basdado.adventofcode.day10
|
||||
|
||||
import com.basdado.adventofcode.lines;
|
||||
import java.util.stream.Collectors;
|
||||
import com.basdado.adventofcode.lines
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.min
|
||||
|
||||
const val DAY10_INPUT_PATH = "/day/10/input.txt"
|
||||
|
||||
fun main() {
|
||||
|
||||
// val circle = listOf(
|
||||
// Day10.Vector2i(0, 1),
|
||||
// Day10.Vector2i(1, 1),
|
||||
// Day10.Vector2i(1, 0),
|
||||
// Day10.Vector2i(0, -1),
|
||||
// Day10.Vector2i(-1, -1),
|
||||
// Day10.Vector2i(-1, 0),
|
||||
// Day10.Vector2i(-1, 1)
|
||||
// )
|
||||
//
|
||||
// circle.map {
|
||||
// - (it.angle() + 0.5 * PI)
|
||||
// }.map { if (it < 0) it + 2 * PI else it }.forEach(::println)
|
||||
|
||||
// println(Day10.Vector2i(5, 2).angle())
|
||||
|
||||
Day10.puzzle1()
|
||||
// Day10.puzzle2()
|
||||
Day10.puzzle2()
|
||||
}
|
||||
|
||||
object Day10 {
|
||||
|
||||
fun puzzle1() {
|
||||
println("Hello world!")
|
||||
val rawData = lines(DAY10_INPUT_PATH).collect(Collectors.toList())
|
||||
val asteroids =
|
||||
(0..rawData.size).forEach { y ->
|
||||
(0..rawData[y].length).forEach { x ->
|
||||
if (rawData[y][x] == '#') {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
val asteroids = loadAsteroids()
|
||||
println(optimalAsteroidsPerDirection(asteroids).second.size)
|
||||
|
||||
}
|
||||
|
||||
fun puzzle2() {
|
||||
val asteroids = loadAsteroids()
|
||||
val optimalAsteroid = optimalAsteroidsPerDirection(asteroids)
|
||||
// val optimalAsteroid = Pair(Vector2i(8, 3), asteroidsPerDirection(Vector2i(8, 3), asteroids))
|
||||
// println(optimalAsteroid.first)
|
||||
// optimalAsteroid.second.keys.forEach {
|
||||
// var angle = (it.angle() + 0.5 * PI);
|
||||
// angle = if (angle < 0) 2*PI + angle else angle
|
||||
// println("(${it.x}, ${it.y}) = $angle")
|
||||
// }
|
||||
val sortedAsteroidLists = optimalAsteroid.second
|
||||
.entries
|
||||
.sortedBy { val angle = (it.key.angle() + 0.5 * PI); if (angle < 0) 2*PI + angle else angle }
|
||||
.map { it.value.sortedBy( Vector2i::manhattan ) }
|
||||
// And now we're gonna keep taking one of each list until we reach number 200
|
||||
var listIndex = 0
|
||||
var itemIndexPerList = IntArray(sortedAsteroidLists.size)
|
||||
var i = 0
|
||||
var curItem: Vector2i? = null
|
||||
while (i < 200) {
|
||||
val list = sortedAsteroidLists[listIndex]
|
||||
if (itemIndexPerList[listIndex] < list.size) {
|
||||
curItem = list[itemIndexPerList[listIndex]]
|
||||
// println(optimalAsteroid.first + curItem)
|
||||
itemIndexPerList[listIndex]++
|
||||
i++
|
||||
}
|
||||
listIndex++
|
||||
}
|
||||
val asteroid200 = optimalAsteroid.first + curItem!!
|
||||
println(asteroid200.x * 100 + asteroid200.y)
|
||||
}
|
||||
|
||||
private fun optimalAsteroidsPerDirection(asteroids: List<Vector2i>): Pair<Vector2i, Map<Vector2i, List<Vector2i>>> {
|
||||
return asteroids.map { Pair(it, asteroidsPerDirection(it, asteroids)) }.maxBy { it.second.size }!!
|
||||
}
|
||||
|
||||
private fun asteroidsPerDirection(asteroid: Vector2i, asteroids: List<Vector2i>): Map<Vector2i, List<Vector2i>> {
|
||||
return asteroids
|
||||
.filter { it != asteroid }
|
||||
.map { it - asteroid }
|
||||
.groupBy { it.normalize() }
|
||||
}
|
||||
|
||||
private fun loadAsteroids(): List<Vector2i> {
|
||||
val rawData = lines(DAY10_INPUT_PATH).collect(Collectors.toList())
|
||||
return (0 until rawData.size).flatMap { y ->
|
||||
(rawData[y].indices)
|
||||
.filter { x -> rawData[y][x] == '#' }
|
||||
.map { x -> Vector2i(x, y) }
|
||||
}
|
||||
}
|
||||
|
||||
data class Vector2i(val x: Int, val y: Int) {
|
||||
|
||||
fun normalize(): Vector2i {
|
||||
|
||||
return this / gcd(x, y)
|
||||
}
|
||||
|
||||
fun angle() = atan2(y.toDouble(), x.toDouble())
|
||||
fun manhattan() = abs(x) + abs(y)
|
||||
|
||||
operator fun div(d: Int) = Vector2i(x / d, y / d)
|
||||
operator fun minus(n: Int) = Vector2i(x - n, y - n)
|
||||
operator fun minus(v: Vector2i) = Vector2i(x - v.x, y - v.y)
|
||||
operator fun plus(n: Int) = Vector2i(x + n, y + n)
|
||||
operator fun plus(v: Vector2i) = Vector2i(x + v.x, y + v.y)
|
||||
}
|
||||
|
||||
val ORIGIN = Vector2i(0, 0)
|
||||
|
||||
fun gcd(n1: Int, n2: Int) = when {
|
||||
n1 == 0 && n2 == 0 -> 1 // Actually undefined/any number, but whatever
|
||||
n1 == 0 -> abs(n2)
|
||||
n2 == 0 -> abs(n1)
|
||||
else -> (1..(min(abs(n1), abs(n2))))
|
||||
.filter { n1 % it == 0 && n2 % it == 0 }
|
||||
.max() ?: 1
|
||||
}
|
||||
}
|
||||
5
src/main/resources/day/10/ex0.txt
Normal file
5
src/main/resources/day/10/ex0.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
.#....#####...#..
|
||||
##...##.#####..##
|
||||
##...#...#.#####.
|
||||
..#.....X...###..
|
||||
..#.#.....#....##
|
||||
10
src/main/resources/day/10/ex1.txt
Normal file
10
src/main/resources/day/10/ex1.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
......#.#.
|
||||
#..#.#....
|
||||
..#######.
|
||||
.#.#.###..
|
||||
.#..#.....
|
||||
..#....#.#
|
||||
#..#....#.
|
||||
.##.#..###
|
||||
##...#..#.
|
||||
.#....####
|
||||
10
src/main/resources/day/10/ex2.txt
Normal file
10
src/main/resources/day/10/ex2.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
#.#...#.#.
|
||||
.###....#.
|
||||
.#....#...
|
||||
##.#.#.#.#
|
||||
....#.#.#.
|
||||
.##..###.#
|
||||
..#...##..
|
||||
..##....##
|
||||
......#...
|
||||
.####.###.
|
||||
10
src/main/resources/day/10/ex3.txt
Normal file
10
src/main/resources/day/10/ex3.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
.#..#..###
|
||||
####.###.#
|
||||
....###.#.
|
||||
..###.##.#
|
||||
##.##.#.#.
|
||||
....###..#
|
||||
..#.#..#.#
|
||||
#..#.#.###
|
||||
.##...##.#
|
||||
.....#.#..
|
||||
20
src/main/resources/day/10/ex4.txt
Normal file
20
src/main/resources/day/10/ex4.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
.#..##.###...#######
|
||||
##.############..##.
|
||||
.#.######.########.#
|
||||
.###.#######.####.#.
|
||||
#####.##.#.##.###.##
|
||||
..#####..#.#########
|
||||
####################
|
||||
#.####....###.#.#.##
|
||||
##.#################
|
||||
#####.##.###..####..
|
||||
..######..##.#######
|
||||
####.##.####...##..#
|
||||
.#####..#.######.###
|
||||
##...#.##########...
|
||||
#.##########.#######
|
||||
.####.#.###.###.#.##
|
||||
....##.##.###..#####
|
||||
.#.#.###########.###
|
||||
#.#.#.#####.####.###
|
||||
###.##.####.##.#..##
|
||||
Reference in New Issue
Block a user