Skip to content

Instantly share code, notes, and snippets.

@shintakezou
Created November 25, 2017 14:46
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/094c7669fa1b73c630c18418e40b0ade to your computer and use it in GitHub Desktop.
Save shintakezou/094c7669fa1b73c630c18418e40b0ade to your computer and use it in GitHub Desktop.
This is like another gist (https://gist.github.com/shintakezou/aab5d6c3a76689a6370ab6477f8cff2e) but it uses more lambdas...
/* 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()> chk_func;
// 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 {
return std::all_of(s_.cbegin(), s_.cend(),
[](chk_func f) -> bool { return f(); });
}
};
void dump(const arg0& names)
{
for (const auto& name : names) {
std::cout << name << " ";
}
std::cout << "\n";
}
chk_func not0(chk_func& f)
{
return [&f]()->bool{ return !f(); };
}
int main()
{
arg0 names{"Giovanni", "Marco", "Elisa", "Simone"};
// sorting just because of std::next_permutation()
std::sort(names.begin(), names.end());
// 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)
auto h = [&names](const std::string& s) {
return std::find(names.begin(), names.end(), s) - names.begin();
};
// statements
chk_func f1 = [&h]() -> bool {
return h("Marco") > h("Giovanni");
};
chk_func f2 = [&h]() -> bool {
return h("Giovanni") < h("Simone");
};
chk_func f3 = [&h]() -> bool {
return
h("Giovanni") < h("Simone") &&
h("Giovanni") < h("Marco") &&
h("Giovanni") < h("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, not0(f3)},
Checker{f1, not0(f2), f3},
Checker{not0(f1), f2, f3}
};
do {
for (const auto& check : checklist) {
if (check()) {
// 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