Introduction
The Day 2 problem can be solved in pretty straightforward way, but let’s try to express our solution in the way, that would make the code most readable in functional style.
Quick notes
In my solution I wanted to focus on the functional coding style in Kotlin and the well known from functional
languages function fold
which can be seen as foldLeft
function from other languages. Its role is to
iterate over the specified collection of items, using some accumulator to hold the current result and return
this result at the end.
In my opinion, if you don’t understand what’s the purpose of some function from standard library, the easiest
approach is to look into its source to analyze its behavior (what can be easily done with Ctrl + B
shortcut
in Intellij). Let’s see then at the definition of fold
|
|
which now should be obvious how it works. If you have problem with seeing the way of applying it, you should
think what is actually your current result (represented by acc
) and how you extend this current value to
the state after processing one more element from collection (which is realized with transformation f
).
It needs some time to get used to such approach, but you get some benefits with it - your code becomes more declarative and expresses your intention directly, because you write only what’s the initial state and how to transform current state to the next one, and the whole processing is done with your transformation.
What’s worth mentioning here is the inline
keyword before this and many, many more functions from standard
library in Kotlin - this code compiled and disassembled can be seen as old-style loop over items that you
probably would write in place of calling the fold
- so we get this readability in our cost with no
overhead for performance in execution 😍.
Solution
The solution to the problem was implemented according to the description oof the task -
the code is more readable thanks to using sealed interface Cmd
that we parse only once (with fun String.cmd()
) and
then use as typed value.
The whole logic is contained in single when
expression that allows us to define
mentioned transformation of current result. As an accumulator we keep the values (x, y)
or
(x, y, aim)
and accordingly transform them.
Day2.kt
|
|
Extra notes
It’s worth seeing how we implement also the fun String.cmd()
as it contains the standard library
function takeIf
which in my opinion is pretty straightforward but not well-known among
developers because we don’t have a lot of other languages with similar constructs. Using
it brings no overhead too but makes the code more declarative and allows chaining functions'
calls in multiple situations.
Additionally, let’s notice that we defined the data class Cmd
which is destructured in fold
transformation as (dir, v)
- that’s one of beauties of data classes
that we should not forget
about and don’t worry about introducing new, local types for such transformations.