article banner

Advent of Kotlin: Week 1: JSON stringify and possible value parentheses

I am happy to announce the Advent of Kotlin 2021! What is more, it starts now. In this event, I will be announcing a challenge each week, and your task is to write the solution. If you want to have some fun together, post your solution on Twitter with the tag AdventOfKotlin. You can also send it to contact@kt.academy. We assume that if you send it to us, you agree to publish it here.

The contest

I would also like to announce a contest. Those, who will share their solutions on Twitter, can win special gifts. The biggest one is an entry to the Kotlin Coroutines workshop in March (the workshop will be conducted online and will take place in the European time zone). As part of the activity we will be counting:

  • sharing solutions with others (with #AdventOfKotlin @KtDotAcademy),
  • creativity, readability, efficiency, scalability and style in solutions,
  • helping others and engaging in discussions.

In the end, my final verdict has to be subjective, but I hope that doesn't prevent us from having fun.

The prerequisite to participate in the competition is to solve all the tasks. But beware, the challenges will get more difficult as time goes on.

This week's challenge

This is a warm-up week. Instead of one complex challenge, there will be two easy ones. Although they still give you plenty of room to show good style :)

During the advent, you can work on this project:

JSON stringify

The first challenge is to stringify the JsonElement represented with the following hierarchy of types:

sealed class JsonElement data class JsonObject(val fields: Map<String, JsonElement>) : JsonElement() { constructor(vararg fields: Pair<String, JsonElement>) : this(fields.toMap()) } data class JsonArray(val elements: List<JsonElement>) : JsonElement() { constructor(vararg elements: JsonElement) : this(elements.toList()) } data class JsonNumber(val value: Double) : JsonElement() data class JsonString(val value: String) : JsonElement() data class JsonBoolean(val value: Boolean) : JsonElement() object JsonNull : JsonElement()

This is how your function should look like and behave:

fun JsonElement.stringify(): String = TODO() assertEquals("""{"i":10}""", JsonObject("i" to JsonNumber(10.0)).stringify()) assertEquals( """{"a":"AAA","b":123.45,"c":true,"d":false,"e":null}""", JsonObject( "a" to JsonString("AAA"), "b" to JsonNumber(123.45), "c" to JsonBoolean(true), "d" to JsonBoolean(false), "e" to JsonNull, ).stringify() ) assertEquals( """{"letters":["A","B","C"]}""", JsonObject( "letters" to JsonArray( JsonString("A"), JsonString("B"), JsonString("C"), ) ).stringify() ) assertEquals( """{"users":[{"name":"Marcin"},{"name":"Maja"}]}""", JsonObject( "users" to JsonArray( JsonObject("name" to JsonString("Marcin")), JsonObject("name" to JsonString("Maja")), ) ).stringify() )

Here you can find unit tests to this exercise:

Here are the files with setup and tests in the project template:

Possible well-formed parentheses

The next challenge is from @cassidoo newsletter. I had a lot of fun solving it, so I am happy to share it with you.

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:

fun generateParenthesisCombinations(num: Int): List<String> = TODO() assertEquals(listOf("()"), generateParenthesisCombinations(1)) assertEquals(listOf("(())", "()()"), generateParenthesisCombinations(2).sorted()) assertEquals( listOf("((()))", "(()())", "(())()", "()(())", "()()()"), generateParenthesisCombinations(3).sorted() ) assertEquals( listOf( "(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()" ), generateParenthesisCombinations(4).sorted() )

You can find more tests here:

Here are the files with setup and tests in the project template:

Ending

I wish you the best of luck in this and future challenges and can't wait to see your solutions :)