File size: 3,041 Bytes
497f2f3 | 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <iostream> // compiled with clang (tags/RELEASE_600/final)
#include <type_traits> // or g++ (GCC) 7.3.1 20180406 -- from hare1039
namespace functional_list // basic building block for template meta programming
{
struct NIL
{
using head = NIL;
using tail = NIL;
friend std::ostream& operator << (std::ostream& os, NIL const) { return os; }
};
template <typename H, typename T = NIL>
struct list
{
using head = H;
using tail = T;
};
template <int i>
struct integer
{
static constexpr int value = i;
friend std::ostream& operator << (std::ostream& os, integer<i> const) { os << integer<i>::value; return os;}
};
template <typename L, int nTH> constexpr
auto at()
{
if constexpr (nTH == 0)
return (typename L::head){};
else if constexpr (not std::is_same_v<typename L::tail, NIL>)
return at<typename L::tail, nTH - 1>();
else
return NIL{};
}
template <typename L, int nTH>
using at_t = decltype(at<L, nTH>());
template <typename L, typename elem> constexpr
auto prepend() { return list<elem, L>{}; }
template <typename L, typename elem>
using prepend_t = decltype(prepend<L, elem>());
template <int Size, typename Dat = integer<0>> constexpr
auto gen_list()
{
if constexpr (Size == 0)
return NIL{};
else
{
using next = decltype(gen_list<Size - 1, Dat>());
return prepend<next, Dat>();
}
}
template <int Size, typename Dat = integer<0>>
using gen_list_t = decltype(gen_list<Size, Dat>());
} namespace fl = functional_list;
constexpr int door_amount = 101; // index from 1 to 100
template <typename L, int current, int moder> constexpr
auto construct_loop()
{
using val_t = fl::at_t<L, current>;
if constexpr (std::is_same_v<val_t, fl::NIL>)
return fl::NIL{};
else
{
constexpr int val = val_t::value;
using val_add_t = fl::integer<val + 1>;
using val_old_t = fl::integer<val>;
if constexpr (current == door_amount)
{
if constexpr(current % moder == 0)
return fl::list<val_add_t>{};
else
return fl::list<val_old_t>{};
}
else
{
using sub_list = decltype(construct_loop<L, current + 1, moder>());
if constexpr(current % moder == 0)
return fl::prepend<sub_list, val_add_t>();
else
return fl::prepend<sub_list, val_old_t>();
}
}
}
template <int iteration> constexpr
auto construct()
{
if constexpr (iteration == 1) // door index = 1
{
using l = fl::gen_list_t<door_amount>;
return construct_loop<l, 0, iteration>();
}
else
{
using prev_iter_list = decltype(construct<iteration - 1>());
return construct_loop<prev_iter_list, 0, iteration>();
}
}
template <typename L, int pos> constexpr
void show_ans()
{
if constexpr (std::is_same_v<typename L::head, fl::NIL>)
return;
else
{
if constexpr (L::head::value % 2 == 1)
std::cout << "Door " << pos << " is opened.\n";
show_ans<typename L::tail, pos + 1>();
}
}
int main()
{
using result = decltype(construct<100>());
show_ans<result, 0>();
}
|