Skip to content

Instantly share code, notes, and snippets.

@shintakezou
Last active November 25, 2017 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shintakezou/aab5d6c3a76689a6370ab6477f8cff2e to your computer and use it in GitHub Desktop.
Save shintakezou/aab5d6c3a76689a6370ab6477f8cff2e to your computer and use it in GitHub Desktop.
Solving "Quesito con la Susi n. 946"
/* This trivially solves a quiz on the Italian magazine
"La Settimana Enigmistica", namely
"Quesito con la Susi n. 946".
It uses, without any special reason, >C++11
features.
Problem:
There are four friends (Giovanni, Marco, Simone, Elisa)
sat down behind a desk; Susi must say who's the shortest
taking into account their statements and the fact that one
among Giovanni, Marco and Simone, always lies.
Marco says he's taller than Giovanni;
Giovanni says he's shorter than Simone;
Simone says that Giovanni is the shortest.
(Elisa says that only one of the other three lies)
Output:
Elisa Giovanni Marco Simone
Elisa Giovanni Simone Marco
That means, Elisa is the shortest.
*/
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <initializer_list>
typedef std::vector<std::string> arg0;
typedef std::function<bool(arg0)> chk_func;
// returns the (supposed) height of s (given by its
// position into the vector: the higher the index, the taller
// the person. (s must exist in n)
int h(const arg0& n, const std::string& s)
{
return std::find(n.begin(), n.end(), s) - n.begin();
}
// collection of statements which must all hold
class Checker
{
private:
std::vector<chk_func> s_;
public:
Checker(std::initializer_list<chk_func> cks) : s_(cks) {}
bool operator()(const arg0& p) const {
return std::all_of(s_.cbegin(), s_.cend(),
[&p](chk_func f) -> bool { return f(p); });
}
};
void dump(const arg0& names)
{
for (const auto& name : names) {
std::cout << name << " ";
}
std::cout << "\n";
}
int main()
{
arg0 names{"Giovanni", "Marco", "Elisa", "Simone"};
// sorting just because of std::next_permutation()
std::sort(names.begin(), names.end());
// statements
chk_func f1 = [](const arg0& n) -> bool {
return h(n, "Marco") > h(n, "Giovanni");
};
chk_func f2 = [](const arg0& n) -> bool {
return h(n, "Giovanni") < h(n, "Simone");
};
chk_func f3 = [](const arg0& n) -> bool {
return
h(n, "Giovanni") < h(n, "Simone") &&
h(n, "Giovanni") < h(n, "Marco") &&
h(n, "Giovanni") < h(n, "Elisa");
};
// in each set of statements we are negating the
// statement of the person who's supposedly lying.
std::vector<Checker> checklist{
Checker{f1, f2, std::not1(f3)},
Checker{f1, std::not1(f2), f3},
Checker{std::not1(f1), f2, f3}
};
do {
for (const auto& check : checklist) {
if (check(names)) {
// dump the vector in its current permutation
dump(names);
}
}
} while (std::next_permutation(names.begin(), names.end()));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment