From 83c078a4cb52f1b0cd19fb2fb4d7db632a5629e4 Mon Sep 17 00:00:00 2001 From: Logiar Date: Fri, 6 Dec 2024 09:56:47 +0100 Subject: [PATCH] Part 1 solved, part 2 got issues. --- day06.kts | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 day06.kts diff --git a/day06.kts b/day06.kts new file mode 100755 index 0000000..5efc3a6 --- /dev/null +++ b/day06.kts @@ -0,0 +1,130 @@ +#!/usr/bin/env kotlin +import java.io.File +import java.lang.RuntimeException +import java.util.Scanner + +data class MoveResult(val newLocation: Pair, val newDirection: Direction) +data class MoveHistory(val location: Pair, val direction: Direction) +enum class Direction(val offset: Pair) { + NORTH(Pair(0, -1)), + EAST(Pair(1, 0)), + SOUTH(Pair(0, 1)), + WEST(Pair(-1, 0)); + + fun move(currentLocation: Pair): Pair { + return Pair( + currentLocation.first + offset.first, + currentLocation.second + offset.second + ) + } + fun turnLeft(): Direction { + return when (this) { + NORTH -> WEST + WEST -> SOUTH + SOUTH -> EAST + EAST -> NORTH + } + } + fun turnRight(): Direction { + return when (this) { + NORTH -> EAST + EAST -> SOUTH + SOUTH -> WEST + WEST -> NORTH + } + } + fun moveByPartOneRules( + currentLocation: Pair, + blocks: Set> + ): MoveResult { + var currentDirection = this + do { + val potentialMove = currentDirection.move(currentLocation) + if (potentialMove !in blocks) { + return MoveResult(potentialMove, currentDirection) + } + currentDirection = currentDirection.turnRight() + } while (currentDirection != this) + throw RuntimeException("Nowhere to go! $currentLocation $this") + } +} +fun isPositionInTheRoom(player: Pair, xMax: Int, yMax: Int): Boolean { + return player.first in 0..xMax && player.second in 0..yMax +} + + +val scanner = Scanner(System.`in`) +val visited = mutableSetOf>() +val history = mutableListOf() +var playerLocation = Pair(0, 0) +var playerDirection: Direction = Direction.NORTH +val blocks = mutableSetOf>() +val potentialBlocks = mutableSetOf>() +var yMax = 0 +var xMax = 0 +while (scanner.hasNextLine()) { + val line = scanner.nextLine() + for (i in line.indices) { + if (line[i] == '.') { + continue + } + if (line[i] == '>') { + playerDirection = Direction.EAST + playerLocation = Pair(i, yMax) + } else if (line[i] == '<') { + playerDirection = Direction.WEST + playerLocation = Pair(i, yMax) + } else if (line[i] == '^') { + playerDirection = Direction.NORTH + playerLocation = Pair(i, yMax) + } else if (line[i] == 'v') { + playerDirection = Direction.SOUTH + playerLocation = Pair(i, yMax) + } else if (line[i] == '#') { + blocks.add(Pair(i, yMax)) + } + } + xMax = xMax.coerceAtLeast(line.lastIndex) + yMax++ +} +val initialPosition = playerLocation.copy() +while (isPositionInTheRoom(playerLocation, xMax, yMax)) { + visited.add(playerLocation) + if (checkForLoopIfObstacleInFront(playerLocation, playerDirection, history)) { + potentialBlocks.add(playerDirection.move(playerLocation)) + } + history.add(MoveHistory(playerLocation, playerDirection)) + val (newLocation, newDirection) = playerDirection.moveByPartOneRules(playerLocation, blocks) + playerLocation = newLocation + playerDirection = newDirection +} + +println("Player location: ${visited.size}") +println("Potential blocks: ${potentialBlocks.size}") + +fun checkForLoopIfObstacleInFront( + playerLocation: Pair, + playerDirection: Direction, + history: MutableList +): Boolean { + val potentialLocation = playerDirection.move(playerLocation) + val nextMove = playerDirection.moveByPartOneRules(playerLocation, blocks) + if (potentialLocation in visited || potentialLocation != nextMove.newLocation || !isPositionInTheRoom(potentialLocation, xMax, yMax)) { + return false + } + var localLocation = playerLocation + var localDirection = playerDirection + val localHistory = history.toMutableList() + val localBlocks = blocks.toMutableSet() + localBlocks.add(potentialLocation) + while (MoveHistory(localLocation, localDirection) !in localHistory) { + localHistory.add(MoveHistory(localLocation, localDirection)) + val (newLocation, newDirection) = localDirection.moveByPartOneRules(localLocation, localBlocks) + localLocation = newLocation + localDirection = newDirection + if (!isPositionInTheRoom(localLocation, xMax, yMax)) { + return false + } + } + return true; +}