Day 11
This commit is contained in:
123
src/main/kotlin/com/basdado/adventofcode/Day11.kt
Normal file
123
src/main/kotlin/com/basdado/adventofcode/Day11.kt
Normal file
@@ -0,0 +1,123 @@
|
||||
package com.basdado.adventofcode
|
||||
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
fun main() {
|
||||
val day = Day11()
|
||||
day.puzzle1()
|
||||
println("Puzzle 2 time: " + (1..10).map { measureTimeMillis { day.puzzle2() } }.average() + " ms")
|
||||
}
|
||||
|
||||
class Day11 {
|
||||
|
||||
fun puzzle1() {
|
||||
|
||||
val serial = lines("/day/11/input.txt").findFirst().get().toInt()
|
||||
val grid = Array(300) { y -> Array(300) { x -> PowerCell(x, y, serial) } }
|
||||
|
||||
var maxPower = 0
|
||||
var maxPowerX = 0
|
||||
var maxPowerY = 0
|
||||
for (y in 0..297) {
|
||||
for (x in 0..297) {
|
||||
val power = (0..8).map { grid[y + (it / 3)][x + (it % 3)].powerLevel }.sum()
|
||||
if (power > maxPower) {
|
||||
maxPower = power
|
||||
maxPowerX = x
|
||||
maxPowerY = y
|
||||
}
|
||||
}
|
||||
}
|
||||
println("$maxPowerX,$maxPowerY")
|
||||
|
||||
}
|
||||
|
||||
fun puzzle2() {
|
||||
val serial = lines("/day/11/input.txt").findFirst().get().toInt()
|
||||
val grid = Array(300) { y -> Array(300) { x -> PowerCell(x, y, serial) } }
|
||||
val gridSumCache = PowerBlockCache(300, 300, 300)
|
||||
(0 until grid.size).forEach {y -> (0 until grid[0].size).forEach {x ->
|
||||
gridSumCache.set(x, y, 1, grid[y][x].powerLevel)
|
||||
}}
|
||||
|
||||
var maxPower = 0
|
||||
var maxPowerX = 0
|
||||
var maxPowerY = 0
|
||||
var maxSize = 0
|
||||
for (size in 1..grid.size) {
|
||||
for (y in 0 until grid.size) {
|
||||
|
||||
if (size + y > grid.size) {
|
||||
continue
|
||||
}
|
||||
for (x in 0 until grid[0].size) {
|
||||
if (size + x > grid[0].size) {
|
||||
continue
|
||||
}
|
||||
val power = powerSum(x, y, size, gridSumCache)
|
||||
if (power > maxPower) {
|
||||
maxPower = power
|
||||
maxPowerX = x
|
||||
maxPowerY = y
|
||||
maxSize = size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println("$maxPowerX,$maxPowerY,$maxSize")
|
||||
}
|
||||
|
||||
private fun powerSum(x: Int, y: Int, size: Int, cache: PowerBlockCache): Int {
|
||||
|
||||
val cached = cache.get(x, y, size)
|
||||
if (cached != null) {
|
||||
return cached
|
||||
} else {
|
||||
|
||||
val powerSum = powerSum(x, y, size - 1, cache) +
|
||||
powerSum(x + 1, y + 1, size - 1, cache) +
|
||||
powerSum(x, y + size - 1, 1, cache) +
|
||||
powerSum(x + size - 1, y, 1, cache) -
|
||||
if (size > 2) powerSum(x + 1, y + 1, size - 2, cache) else 0
|
||||
cache.set(x, y, size, powerSum)
|
||||
return powerSum
|
||||
}
|
||||
}
|
||||
|
||||
class PowerCell(val x: Int, val y: Int, val gridSerial: Int) {
|
||||
val rackId = x + 10
|
||||
|
||||
val powerLevel = hundreds(((rackId * y) + gridSerial) * rackId) - 5
|
||||
}
|
||||
|
||||
class PowerBlockCache(val maxSize: Int, val maxX: Int, val maxY: Int) {
|
||||
val cache = Array(maxSize) { size -> Array(maxX - size) { Array<Int?>(maxY - size) {null}}}
|
||||
|
||||
fun get(x: Int, y: Int, size: Int): Int? {
|
||||
return cache[size - 1][x][y]
|
||||
}
|
||||
|
||||
fun set(x: Int, y: Int, size: Int, value: Int) {
|
||||
cache[size - 1][x][y] = value
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun hundreds(x: Int): Int {
|
||||
return (x - ((x / 1000) * 1000)) / 100
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun divisor(n: Int): Int? {
|
||||
return DEFAULT_DIVISORS.find { n % it == 0 && it < n } ?:
|
||||
(DEFAULT_DIVISORS.last()..sqrt(n.toDouble()).roundToInt()).find { n % it == 0 }
|
||||
}
|
||||
|
||||
private val DEFAULT_DIVISORS = intArrayOf(2, 3, 5, 7, 11, 13, 17, 19)
|
||||
}
|
||||
|
||||
data class PowerBlock(val x: Int, val y: Int, val size: Int)
|
||||
}
|
||||
1
src/main/resources/day/11/input.txt
Normal file
1
src/main/resources/day/11/input.txt
Normal file
@@ -0,0 +1 @@
|
||||
6303
|
||||
Reference in New Issue
Block a user