# Advent of Kotlin Solutions

Everything good must come to an end, it is time to end Advent of Kotlin 2021 as well. See how those problems could be solved.

## Week 1: JSON stringify

Our first challenge, was to stringify an object representing JSON.

This is a typical exercise to practice using `when`

with type smart-casting. This pattern is really popular in Kotlin (sometimes referred as Kotlin pattern matching). So I expected implementing `stringify`

function as a single-expression function with `when`

and a separate handling for each child of the `JsonElement`

sealed class.

Now think, what should there be in each case.

`JsonNull`

is always`null`

.`JsonBoolean`

value just needs to be transformed to`String`

.`JsonString`

value just needs to be wrapped with quotes.`JsonNumber`

is a bit more tricky, because a value 1.0 should be presented as 1. This means, that such values need to be transformed to Int first. I decided to recognize numbers with no decimal part by chaching if they are changed by`floor`

.`JsonArray`

is just a collection of elements of type`JsonElement`

. Each of them should be stringified with`stringify`

function (so we use recursion). They should be separated with comma, and the array should start and end with box bracket. This is a perfect case for using`joinToString`

function.`JsonObject`

is quite similar, but each value has a name. Since`Map`

does not have`joinToString`

function, we first need to transform it to`List`

with`toList`

(transforms`Map<K, V>`

to`List<Pair<K, V>>`

).

## Week 1: Possible well-formed parentheses

The task is to create a function, that for a given `n`

, generates all combinations of `n`

well-formed pairs of parentheses. Here are a few usage examples:

There are planty of ways, how this problem can be solved. One might generate all possible combinations, and filter out those that are not correct. Another one might insert parenthesis at different positions. But the most efficient and simple solution I know is quite simple. Let's build possible strings character by character. At the beginning, we have a number of parentheses to open, and no opened ones. In such case, we need to place "(". Now we have one open parenthesis, and one less to open. If the number of parenthesis to open is bigger than zero, then we can place either "(" or ")". Otherwise, we need to close those that are opened with ")". All the possible combinations can be implemented recursively in the following way:

## Week 2: Tree algorithms

This is a continuation of classic exercises to practive recursive thinking and using Kotlin pattern matching (when expression with smart-casting). My solution is not the fastest, but it is readable and presents the algorithm quite clearly.

## Week 3: k-means clustering

k-means was a bit more complicated task, and figuring out the algorithm was part of it. Here is my solution:

## Week 4: JSON parsing

Parsing JSON is not a simple task. The below implementation is not perfect, but covers the most essential functionalities. As you might analize, it is parsing elements recursively. A big problem is finding where an element ends. For instance, when you parse a content of an array, you cannot just separate string with comma, because each element might incluse a comma inside (it might be another array or an object). Solving this kind of problems is not easy, but also sharpens our minds. In my implementation, I also used many regexes.

All the solutions, together with passing unit tests, can be found on GitHub: