fork download
  1. #include<iostream>
  2. #include<type_traits>
  3.  
  4. int constexpr powOf10(size_t power)
  5. {
  6. return power == 0 ? 1 : 10 * powOf10(power - 1);
  7. }
  8.  
  9. template<int... digits>
  10. struct buildNumber;
  11.  
  12. template<int first, int... digits>
  13. struct buildNumber<first, digits...> : std::integral_constant<int, first * powOf10(sizeof...(digits)) + buildNumber<digits...>::value>
  14. {
  15. };
  16.  
  17. template<>
  18. struct buildNumber<> : std::integral_constant<int, 0>
  19. {
  20. };
  21.  
  22. template<int... digits>
  23. struct areAllDigits;
  24.  
  25. template<int first, int... digits>
  26. struct areAllDigits<first, digits...>
  27. {
  28. static bool constexpr value = first > 0 && first < 10 && areAllDigits<digits...>::value;
  29. };
  30.  
  31. template<int first>
  32. struct areAllDigits<first>
  33. {
  34. static bool constexpr value = first>0 && first < 10;
  35. };
  36.  
  37. template<class T>
  38. struct buildNumberT;
  39.  
  40.  
  41. template<int... digits>
  42. struct digitContainer
  43. {
  44.  
  45. };
  46.  
  47.  
  48. template<int... digits>
  49. struct buildNumberT<digitContainer<digits...>> : buildNumber<digits...> {};
  50.  
  51. template<class T1, class T2>
  52. struct concatCtr;
  53.  
  54. template<int... digits1, int... digits2>
  55. struct concatCtr<digitContainer<digits1...>, digitContainer<digits2...>>
  56. {
  57. typedef digitContainer<digits1..., digits2...> type;
  58. };
  59.  
  60. template<int number, size_t digit>
  61. struct breakIntoDigits
  62. {
  63. typedef typename concatCtr<digitContainer<number / powOf10(digit)>, typename breakIntoDigits<number % powOf10(digit), digit - 1>::ctr>::type ctr;
  64. };
  65.  
  66. template<int number>
  67. struct breakIntoDigits<number, 0>
  68. {
  69. typedef digitContainer<number> ctr;
  70. };
  71.  
  72. template<int needle, int... haystack>
  73. struct contains;
  74.  
  75. template<int needle, int first, int... haystack>
  76. struct contains<needle, first, haystack...>
  77. {
  78. static bool constexpr value = needle == first || contains<needle, haystack...>::value;
  79. };
  80.  
  81. template<int needle>
  82. struct contains<needle>
  83. {
  84. static constexpr bool value = false;
  85. };
  86.  
  87. template<int... values>
  88. struct max;
  89.  
  90. template<int first, int... rest>
  91. struct max<first, rest...>
  92. {
  93. static constexpr int value = first > max<rest...>::value ? first : max<rest...>::value;
  94. };
  95.  
  96. template<>
  97. struct max<>
  98. {
  99. static int constexpr value = 0;
  100. };
  101.  
  102. template<class container, int... digits>
  103. struct ruleChecker;
  104.  
  105. template<int current, int... allPrevious, int... rest>
  106. struct ruleChecker<digitContainer<allPrevious...>, current, rest...>
  107. {
  108. static bool constexpr value = (current == 0 || sizeof...(allPrevious) == 0 || contains<current, allPrevious...>::value || current > max<allPrevious...>::value) && ruleChecker<digitContainer<allPrevious..., current>, rest...>::value;
  109. };
  110.  
  111. template<class container>
  112. struct ruleChecker<container>
  113. {
  114. static bool constexpr value = true;
  115. };
  116.  
  117. template<class ctr1, class ctr2>
  118. struct ruleCheckerT;
  119.  
  120. template<class ctr1, int... set2>
  121. struct ruleCheckerT<ctr1, digitContainer<set2...>> : ruleChecker<ctr1, set2...>{};
  122.  
  123.  
  124. template<int number, int length>
  125. struct isValidNumber : ruleCheckerT<digitContainer<>, typename breakIntoDigits<number, length>::ctr>
  126. {
  127. };
  128.  
  129.  
  130. template<int number, int length>
  131. struct generateList
  132. {
  133. typedef typename std::conditional<number % powOf10(length) == 0,
  134. digitContainer<>,
  135. typename concatCtr<
  136. typename generateList<number + 1, length>::container,
  137. typename std::conditional<isValidNumber<number, length>::value,
  138. digitContainer<number>,
  139. digitContainer<>
  140. >::type
  141. >::type
  142. >::type container;
  143. };
  144.  
  145. template<int number>
  146. struct generateList<number, 1>
  147. {
  148. typedef typename concatCtr<
  149. typename generateList<number + 1, 1>::container,
  150. typename std::conditional<isValidNumber<number, 1>::value,
  151. digitContainer<number>,
  152. digitContainer<>
  153. >::type
  154. >::type container;
  155. };
  156.  
  157. #define DEFINE_ENDPOINT_FOR_LENGTH(length) template<> struct generateList<powOf10(length), (length)>{typedef digitContainer<> container;}
  158.  
  159. template<int length>
  160. struct insanity
  161. {
  162. static_assert(length > 0, "Length must be greater than 0.");
  163. typedef typename concatCtr<typename generateList<1, length>::container, digitContainer<0>>::type numberList;
  164. };
  165.  
  166. template<int first, int... rest>
  167. void outputContainer(digitContainer<first, rest...> values)
  168. {
  169. std::cout<<first<<'\n';
  170. outputContainer(digitContainer<rest...>{});
  171. }
  172.  
  173. void outputContainer(digitContainer<> empty)
  174. {
  175. std::flush(std::cout);
  176. }
  177. DEFINE_ENDPOINT_FOR_LENGTH(1);
  178. DEFINE_ENDPOINT_FOR_LENGTH(2);
  179. int main()
  180. {
  181. outputContainer(insanity<2>::numberList{});
  182. }
Success #stdin #stdout 0s 2900KB
stdin
Standard input is empty
stdout
99
90
89
88
80
79
78
77
70
69
68
67
66
60
59
58
57
56
55
50
49
48
47
46
45
44
40
39
38
37
36
35
34
33
30
29
28
27
26
25
24
23
22
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0