Created
November 25, 2017 14:46
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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