Introduction
In Day 14 seems to be pretty straightforward when we read it for the first time and try to implement brute-force solution. When it comes to running the same approach for some larger data, it becomes impossible as may take exponential time and memory - let’s see then how to come up with some smarter solution 😉.
Solution
We may try to represent the current state of the polymer as counts of every pair of consecutive letters
in polymer. We can do that because we are interested only in the occurrences of subsequences of size 2
in our polymer, not in their order. To build such a representation, we can use windowed(2)
function
to iterate through the String
that represents the polymer and count every type of subsequence.
Let’s see that we need to remember also the first and the last character in polymer in our representation.
It’s required in Polymer::counts
- when we want to count the number of each character in polymer,
we count these characters in the counts of subsequences, but these subsequences are overlapping
and every almost every character in them is counted twice - apart from the first and the last characters
that we count manually with
|
|
At the end we need to divide the counts values by 2 (just with mapValues { it.value / 2 }
) because of the
described representation.
It’s worth noticing that in brute-force approach the data may grow exponentially as there may be even a
situation in which the length of polymer is almost doubled in single step (e.g. with AAAA
and AA -> B
we get
ABABABA
). That’s why we need to provide such a smart approach to this problem 😎.
Day14.kt
|
|
Extra notes
Notice that we defined the operator fun invoke
for InsertionRules
. It’s one more and in my opinion
really nice operator in Kotlin that can be defined for any class. We can think of it as about applying
some class to the other e.g. in our class we apply InsertionRules
to Polymer
to get some
new Polymer
. Then, taking Polymer
and applying some rules many times to it can be defined in single
line with such a pretty syntactically code
|
|
Keep in mind that this kind of operator
exists in Kotlin especially when you design some libraries
as there are many cases in which such syntax look just 🆒 for other developers.