1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
auto isPrime = [](int x)->bool {return x == 2 || x == 3 || x == 5 || x == 7 || x == 11 || x == 13 || x == 17 || x == 19 ||
x == 23 || x == 29 || x == 31 || x == 37 || x == 41 || x == 43 || x == 47;};
// 25 placed first before anything else
// 16 to be placed after everything else,
// even numbers placed after all 25's, if any, have been placed (and the even numbers sorted in increasing value among themselves)
// prime numbers then placed in groups in the order 1-9, 10-19, 20-29, 30-39, 40-49 (and in decreasing value within each group)
// after these order on ascending last digit,
// except that last digit 7 appears before other last digits,
// if last digits are equal, order by increasing value
const auto comp = compose<int>
(
[] (int a, int b) {return a == 25 && b != 25;},
[] (int a, int b) {return a != 16 && b == 16;},
[] (int a, int b) {return a%2 == 0 && b%2 != 0;},
[] (int a, int b) {return a%2 == 0 && b%2 == 0 && a < b;},
[=] (int a, int b) {return isPrime (a) && !isPrime (b);},
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a < 10 && b >= 10;}, // need to define a method to add new predicates using loops
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a < 20 && b >= 20;},
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a < 30 && b >= 30;},
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a < 40 && b >= 40;},
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a < 50 && b >= 50;},
[=] (int a, int b) {return isPrime (a) && isPrime (b) && a > b;}, // the primes in decreasing value within their groups
[] (int a, int b) {return a%10 == 7 && b%10 != 7;},
[] (int a, int b) {return a%10 < b%10;},
[] (int a, int b) {return a < b;}
);
int a[] = {19, 22, 11, 23, 25, 31, 40, 37, 32, 35, 45, 21, 33, 21, 38, 25, 47, 27, 16, 47, 39, 16, 25, 5, 7, 35, 48, 17, 27, 57, 31, 29, 23, 43, 17, 41, 3, 7, 13};
std::sort (std::begin (a), std::end (a), comp) ;
for (int v : a)
std::cout << v << ' ' ;
std::cout << '\n' ;
|