Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fun part1() {
- val amountOfEnergy = energizeLavaField(input)
- println("Part 1: " + amountOfEnergy)
- }
- fun part2() {
- val amountOfEnergy = bestEnergizeLavaField(input)
- println("Part 2: " + amountOfEnergy)
- }
- fun energizeLavaField(mirrorMap: List<String>): Int {
- val energizedField = bounceRay(mirrorMap, 0, 0, Right)
- return energizedField.size
- }
- fun bestEnergizeLavaField(mirrorMap: List<String>): Int {
- val bottom = mirrorMap.size -1
- val right = mirrorMap[0].length -1
- val horizontalEdgeMax = (0..right).map { x ->
- maxOf(bounceRay(mirrorMap, x, 0, Down).size, bounceRay(mirrorMap, x, bottom, Up).size)
- }.max() ?: 0
- val verticalEdgeMax = (0..bottom).map { y ->
- maxOf(bounceRay(mirrorMap, 0, y, Right).size, bounceRay(mirrorMap, right, y, Left).size)
- }.max() ?: 0
- return maxOf(horizontalEdgeMax, verticalEdgeMax)
- }
- private fun bounceRay(
- mirrorMap: List<String>,
- startX: Int,
- startY: Int,
- startDir: Direction,
- visitedTiles: MutableSet<Triple<Int, Int, Direction>> = mutableSetOf()
- ): Set<Pair<Int, Int>> {
- if (outOfBounds(startX, startY, startDir, mirrorMap)) return emptySet()
- val energizedField = mutableSetOf<Pair<Int, Int>>()
- var x = startX
- var y = startY
- var direction = startDir
- do {
- energizedField += x to y
- val currentTile = mirrorMap[y][x]
- if (currentTile != '.') {
- if (visitedTiles.contains(Triple(x, y, direction))) return energizedField
- visitedTiles.add(Triple(x, y, direction))
- when (direction) {
- Right -> {
- when (currentTile) {
- '\\' -> direction = Down
- '/' -> direction = Up
- '|' -> {
- direction = Up
- energizedField += bounceRay(mirrorMap, x, y + 1, Down, visitedTiles)
- }
- }
- }
- Left -> {
- when (currentTile) {
- '\\' -> direction = Up
- '/' -> direction = Down
- '|' -> {
- direction = Up
- energizedField += bounceRay(mirrorMap, x, y + 1, Down, visitedTiles)
- }
- }
- }
- Down -> {
- when (currentTile) {
- '\\' -> direction = Right
- '/' -> direction = Left
- '-' -> {
- direction = Left
- energizedField += bounceRay(mirrorMap, x + 1, y, Right, visitedTiles)
- }
- }
- }
- Up -> {
- when (currentTile) {
- '\\' -> direction = Left
- '/' -> direction = Right
- '-' -> {
- direction = Left
- energizedField += bounceRay(mirrorMap, x + 1, y, Right, visitedTiles)
- }
- }
- }
- }
- }
- val move = moveInDirection(x, y, direction)
- x = move.first
- y = move.second
- } while (!outOfBounds(x, y, direction, mirrorMap))
- return energizedField
- }
- private fun moveInDirection(x: Int, y: Int, direction: Direction) =
- when (direction) {
- Right -> x + 1 to y
- Left -> x - 1 to y
- Up -> x to y - 1
- Down -> x to y + 1
- }
- private fun outOfBounds(x: Int, y: Int, dir: Direction, map: List<String>) =
- when (dir) {
- Right -> x == map[0].length
- Left -> x == -1
- Up -> y == -1
- Down -> y == map.size
- }
- enum class Direction {
- Right, Down, Left, Up
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement