From 612356b109a35e79f7b27c2149bd094a81bd1963 Mon Sep 17 00:00:00 2001 From: Romain Gaillard Date: Sun, 12 Dec 2021 18:00:27 +0100 Subject: [PATCH] Kotlin solution for day 12 --- kotlin/day12.kts | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 kotlin/day12.kts diff --git a/kotlin/day12.kts b/kotlin/day12.kts new file mode 100644 index 0000000..3b849fc --- /dev/null +++ b/kotlin/day12.kts @@ -0,0 +1,79 @@ +import java.io.File + +fun findAllPaths(caves: MutableMap>, + canVisitASmallCaveTwice: Boolean): MutableList> { + + var visited = mutableListOf() + var currentPath = mutableListOf() + var paths = mutableListOf>() + + visitCave(caves, visited, currentPath, paths,"start", canVisitASmallCaveTwice, false) + + return paths +} + +fun isBigCave(cave: String): Boolean { + for (c in cave) { + if (c.isLowerCase()) + return false + } + + return true +} + +fun visitCave(caves: MutableMap>, visited: MutableList, + currentPath: MutableList, paths: MutableList>, + currentCave: String, canVisitASmallCaveTwice: Boolean, smallCaveVisitedTwice: Boolean) { + + visited.add(currentCave) + currentPath.add(currentCave) + + if (currentCave == "end") { + paths.add(currentPath.toMutableList()) + } else { + val adjacentCaves = caves.getOrDefault(currentCave, mutableListOf()) + + for (nextCave in adjacentCaves) { + if (nextCave == "start") + continue + + var canVisit = (isBigCave(nextCave) || (nextCave !in visited)) + var smallCaveVisitedTwiceNow = smallCaveVisitedTwice + + // If we are in the second part of the puzzle, one small cave can be visited twice + // We check if we are in a position where we can still do this + if (!canVisit && canVisitASmallCaveTwice && !smallCaveVisitedTwice) { + canVisit = true + smallCaveVisitedTwiceNow = true + } + + if (canVisit) + visitCave(caves, visited, currentPath, paths, nextCave, canVisitASmallCaveTwice, smallCaveVisitedTwiceNow) + } + } + + currentPath.removeLast() + visited.remove(currentCave) +} + +fun buildGraph(fileName: String): MutableMap> { + var caves = mutableMapOf>() + + File(fileName).forEachLine { + var (start, end) = it.split("-") + + // Bidirected graph, so we add both start->end and end->start into the list of edges + caves.put(start, (caves.getOrDefault(start, mutableListOf()) + end).toMutableList()) + caves.put(end, (caves.getOrDefault(end, mutableListOf()) + start).toMutableList()) + } + + return caves +} + +val fileName = if (args.size > 0) args[0] else "day12.txt" + +// List of edges of the bidirected graph +var caves = buildGraph(fileName) + +println(findAllPaths(caves, false).size) +println(findAllPaths(caves, true).size) \ No newline at end of file