Introduction
In Day 12 problem we are asked to fins all possible paths between some nodes in graph with some extra restrictions. The given data that describes the graphs is quite small because the problem of finding paths in graph is hard as there may be theoretically a lot of paths to be found.
Solution
We solve given problem with DFS algorithm in which we keep track of the current list of visited nodes from source. Additionally, we don’t mark some nodes as visited when entering them because they can be visited unlimited number of times.
We create an extra check to create common method for both parts of the problem so in the second we just mark some flag that allows us to visit single node twice. Notice, how tricky can be Kotlin definitions to make code more concise - we can write that
|
|
i.e. condition checking, modifying collection and returning in just single line of Kotlin code 😍.
We represent the graph in our approach as the map from node to the set of its adjacent nodes. To get such representation we need to group our edges and their flipped copies by the first element.
Day12.kt
|
|
Extra notes
See that we use some magical value class
in this problem which is some new Kotlin construct that corresponds
to old inline class
es. They have some similar properties as data class
es as they have a lot of predefined
functions, but they can (and have to) have only a single field with some value (for now).
Basically, we can learn a lot about them from the KEEP
that introduced them to the language, but they were introduced because of a few reasons. They allow us
to create new types with no overhead in performance and memory. That means it’s much more powerful than
introducing the typealias
to our model. That’s because defining
|
|
is much more powerful than having
|
|
because in the second situation we can mix String
with Name
while in the first we cannot.
Additionally, for value class
es we can define extra functions that can be called only for them -
same as we would work with some custom type.
There is also a lot of effort in improving performance of such data, so we can read about Project Valhalla in the KEEP description. It describes also the possibility of optimizing the arrays of such created types, so they could be as arrays of primitives in memory.