Advent Of Code — Aunt Sue — Puzzle 16

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:

  • children, by human DNA age analysis.
  • cats. It doesn't differentiate individual breeds.
  • Several seemingly random breeds of dog: samoyeds, pomeranians, akitas, and vizslas. goldfish. No other kinds of fish.
  • trees, all in one group.
  • cars, presumably by exhaust or gasoline or something.
  • perfumes, which is handy, since many of your Aunts Sue wear a few kinds.
children: 3
cats: 7
samoyeds: 2
pomeranians: 3
akitas: 0
vizslas: 0
goldfish: 5
trees: 3
cars: 2
perfumes: 1

Solution

First, let’s describe what are the characteristics of each Aunt. Each Aunt have 10 compounds : children, cats, samoyeds, pomeranians, akitas, vizslas, goldfish, trees, cars and perfumes. And some of them won’t be specified. We can implement those characteristics like so:

using CompoundValue = std::optional<size_t>;
using Compound = std::pair<std::string, CompoundValue>;
class Aunt
{
std::array<Compound, 10> compounds;
};
Aunt::Aunt() {
compounds[0].first = "children";
compounds[1].first = "cats";
compounds[2].first = "samoyeds";
compounds[3].first = "pomeranians";
compounds[4].first = "akitas";
compounds[5].first = "vizslas";
compounds[6].first = "goldfish";
compounds[7].first = "trees";
compounds[8].first = "cars";
compounds[9].first = "perfumes";
}
Aunt::Aunt(std::vector<Compound> knownElements) : Aunt() {
for (const auto &knownElement : knownElements) {
auto compound = std::find_if(
std::begin(compounds),
std::end(compounds),
[&knownElement](const auto &compound) {
return compound.first == knownElement.first;
});
assert(compound != std::end(compounds));
compound->second = knownElement.second;
}
}
std::vector<Aunt> aunts;// Creation of the 500 aunts
foreachLineIn(fileContent, [&aunts](const std::string &line) {
aunts.emplace_back(extractCompounds(line));
});
std::array<Compound, 10> ticketTape{
Compound{"children", 3}, Compound{"cats", 7},
Compound{"samoyeds", 2}, Compound{"pomeranians", 3},
Compound{"akitas", 0}, Compound{"vizslas", 0},
Compound{"goldfish", 5}, Compound{"trees", 3},
Compound{"cars", 2}, Compound{"perfumes", 1}};
auto aunt = std::find_if(
std::begin(aunts),
std::end(aunts),
[&ticketTape](const auto &aunt) {
const auto &auntCompounds = aunt.getCompounds();
for (auto i = size_t{0}; i < auntCompounds.size(); ++i) {
if (auntCompounds[i].second.has_value() &&
auntCompounds[i].second.value() != ticketTape[i].second) {
return false;
}
}
return true;
});
const auto numberOfAuntSue = std::distance(std::begin(aunts), aunt) + 1;

Part 2

Problem

Just before you send your thank you note, you look at the MFCSAM’s instructions and see that you miss some details.

Solution

To do so, all we have to change is the content of the std::find_if used to find the right Aunt Sue:

auto aunt = std::find_if(
std::begin(aunts),
std::end(aunts),
[&ticketTape](const auto &aunt)
{
const auto &auntCompounds = aunt.getCompounds();
for (auto i = size_t{0}; i < auntCompounds.size(); ++i)
{
if (!auntCompounds[i].second.has_value()) { continue; }
if (auntCompounds[i].first == "cats"
|| auntCompounds[i].first == "trees")
{
if (auntCompounds[i].second.value() <= ticketTape[i].second)
{
return false;
}
continue;
}
if (auntCompounds[i].first == "pomeranians"
|| auntCompounds[i].first == "goldfish")
{
if (auntCompounds[i].second.value() >= ticketTape[i].second)
{
return false;
}
continue;
}
if (auntCompounds[i].second.has_value()
&& auntCompounds[i].second.value() != ticketTape[i].second)
{
return false;
}
}
return true;
});

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.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store