1
0
Fork 0

day(12): add solution

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2021-12-12 10:03:01 +01:00
parent f4466c9a88
commit 96cbf099f7
5 changed files with 104 additions and 0 deletions

View file

@ -17,6 +17,14 @@ fun readInputAsCommaSeparatedInts(day: Int, name: String) = openFile(day, name)
.split(",") .split(",")
.map { it.toInt() } .map { it.toInt() }
fun readGraph(day: Int, name: String) = readInput(day, name).fold(mapOf<String, Set<String>>()) { currentGraph, edge ->
val (fromVertex, toVertex) = edge.split("-")
val fromNeighbours = currentGraph.getOrDefault(fromVertex, emptySet()) + toVertex
val toNeighbours = currentGraph.getOrDefault(toVertex, emptySet()) + fromVertex
currentGraph + mapOf(fromVertex to fromNeighbours, toVertex to toNeighbours)
}.toMap()
/** /**
* Converts string to md5 hash. * Converts string to md5 hash.
*/ */

View file

@ -0,0 +1,61 @@
package year2021.day12
import readGraph
fun findAllPaths(graph: Map<String, Set<String>>, path: List<String>, visited: Set<String>): Set<String> {
if (path.last() == "end") {
return setOf(path.joinToString("-"))
}
val neighbours = graph
.getOrDefault(path.last(), emptySet())
.filter { it == it.uppercase() || !visited.contains(it) }
return neighbours.map { neighbour ->
findAllPaths(graph, path + neighbour, visited + neighbour)
}.fold(emptySet()) { acc, it -> acc + it }
}
fun part1(input: Map<String, Set<String>>): Int =
findAllPaths(input, listOf("start"), setOf("start")).size
fun findAllPaths(
graph: Map<String, Set<String>>,
path: List<String>,
visited: Set<String>,
twiceVisited: Boolean
): Set<String> {
if (path.last() == "end") {
return setOf(path.joinToString("-"))
}
val neighbours = graph
.getOrDefault(path.last(), emptySet())
.filter { it == it.uppercase() || (!twiceVisited && it != "start") || !visited.contains(it) }
return neighbours.map { neighbour ->
if (neighbour == neighbour.lowercase() && visited.contains(neighbour))
findAllPaths(graph, path + neighbour, visited, true)
else
findAllPaths(graph, path + neighbour, visited + neighbour, twiceVisited)
}.fold(emptySet()) { acc, it -> acc + it }
}
fun part2(input: Map<String, Set<String>>): Int = findAllPaths(input, listOf("start"), setOf("start"), false).size
fun main() {
val sample = readGraph(12, "sample")
val slightlyLargerSample = readGraph(12, "slightly_larger_sample")
val evenLargerExample = readGraph(12, "even_larger_sample")
val input = readGraph(12, "input")
check(part1(sample) == 10)
check(part1(slightlyLargerSample) == 19)
check(part1(evenLargerExample) == 226)
println(part1(input))
check(part2(sample) == 36)
check(part2(slightlyLargerSample) == 103)
check(part2(evenLargerExample) == 3509)
println(part2(input))
}

View file

@ -0,0 +1,18 @@
fs-end
he-DX
fs-he
start-DX
pj-DX
end-zg
zg-sl
zg-pj
pj-he
RW-he
fs-DX
pj-RW
zg-RW
start-pj
he-WI
zg-he
pj-fs
start-RW

View file

@ -0,0 +1,7 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end

View file

@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc