Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Advent Of Code – JSAbacusFramework.io – Puzzle 12

0.00/5 (No votes)
23 Sep 2019CPOL4 min read 2K  
In this new post, we are going to solve the problem named JSAbacusFramework.io.

Here is Pafrt 12 of a long series on Advent Of Code. You can find the previous part here.

For this new post, we are going to solve the problem from 12th December 2015, named "JSAbacusFramework.io". The solution I will propose is in C++, but the reasoning can be applied to other languages.

Part 1

The Problem

The full version of this problem can be found directly on the Advent of Code website, I will only describe the essence of the problem here:

Santa’s Accounting-Elves need help balancing the books after a recent order. All the information you have is a JSON document with a variety of things (array, objects, number and strings).

What we have to do then, is to find all the numbers and to sum them.

Solution

Well first of all, we have to be able to parse the information from a JSON in C++. We could write a JSON parser from scratch to do it, but that would be a long and hard work, and I don’t know for you, but I don’t want to do work that is already done. So I’ve decided to work with the JSON for Modern C++ library of nlohmann which allows us to have a easily readable code to handle JSON documents.

To include this library, I’ve used a combination of Conan and Cmake, but I won’t go into detail here. You can look at it on the Github repository. Now that everything is clear about the library, let’s get the problem solved.

First of all, we have to get the JSON document ready to be used:

C++
#include <nlohmann/json.hpp>

std::ifstream file (pathToJsonDocument);
nlohmann::json jsonDocument;
file >> jsonDocument;

Simple, right?! We get the file and then only give it to the JSON library to be ready to be used.

Now, how are we going to get the sum of all the numbers in the JSON document. As explained in the problem, there are 4 types of elements in the JSON document: array, objects, number and strings.

So we have to go through the JSON elements and define what to do with them. We can ignore the string, since there are no numbers in them. If we find a number, all we have to do is to add it to the sum. But the more difficult part is about the arrays and the objects. Indeed, they can contain the for types of objects too, and that mean only one thing for our solution (suspense …)🥁 : recursion.

Now that we have described what we have to do, let’s look a look at the actual method of doing this:

C++
int getSum (const nlohmann::json& jsonDocument)
{
    auto sum{0};
    for (const auto& [key, value] : jsonDocument.items())
    {
        if(value.is_number())
        {
            sum += value.get<int>();
        }
        else if(value.is_array() || value.is_object())
        {
            sum += getSum (value);
        }
    }
    return sum;
}

I love how the JSON library makes this function so much readable. As you can see, we have a recursion call for the arrays and the object, and each time we found a number, we add it to the global sum. And this is it. All we have to do is to call this method with the JSON we have created and we are good. We have the solution of our problem. 😃

Part 2

Problem

The Accounting-Elves have realized that they double-counted everything red. So we have now to ignore any object (and all its children) which has any property with the value "red". Only the objects, not the array.

Solution

So now, we no longer ignore the strings. By adding the following condition in the previous method, we will complete the demand of the Accounting-Elves.

C++
for (const auto& [key, value] : jsonDocument.items())
{
    // other conditions
    else if(value.is_string() && jsonDocument.is_object())
    {
        if(value.get<std::string>() == "red")
        {
            sum = 0;
            break;
        }
    }
}

Let’s explain what this condition actually does. We start by looking if the element is a string and we are in an object, so that we meet the first part of the criteria. If this is the case, we look at the value of the string, then we meet the last requirement, so we can stop including element to the sum of number. So we start by resetting the currently processing sum to 0. This sum is the one for the object, so resetting it, will also avoid to have the previously parsed elements added in the global sum, and then, we break from the for loop to not process the other elements of the object.

And voilà. we have a function allowing us to find the solution of this second part. 😃

Conclusion

You can note that the solutions, written in this post, don’t include all the sources to make running programs, but only the interesting part of the sources to solve this problem. If you want to see the programs from end to end, you can go on my GitHub account, explore the full solution, add comments or ask questions if you want to, on the platform you read this article, it will also help me improve the quality of my articles.

Here is the list of elements that we have used, I can’t encourage you enough to look at their definitions:

Thank you for reading, hope you liked it! 😃

And until next part, have fun learning and growing.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)