fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <sstream>
  5. using namespace std;
  6.  
  7. enum class ElemType
  8. {
  9. VAL,
  10. DOWN,
  11. UP,
  12. NONE
  13. };
  14.  
  15. template <typename T>
  16. class Elem
  17. {
  18. public:
  19. Elem(): t(ElemType::VAL), val(0) {}
  20. Elem(const ElemType _t, const T _val): t(_t), val(_val) {}
  21. Elem(const ElemType _t) : Elem(_t, 0) {}
  22.  
  23. ElemType t;
  24. T val;
  25. };
  26.  
  27.  
  28. template <typename T=int>
  29. class MyDS
  30. {
  31. public:
  32. // Initialization Example: [1,2],3,[4,5],[], [6]
  33. MyDS(): v({{ElemType::DOWN}, {ElemType::VAL,1}, {ElemType::VAL,2}, {ElemType::UP}, {ElemType::VAL,3}, {ElemType::DOWN}, {ElemType::VAL,4}, {ElemType::VAL,5}, {ElemType::UP}, {ElemType::DOWN}, {ElemType::NONE}, {ElemType::UP}, {ElemType::DOWN}, {ElemType::VAL,6}, {ElemType::UP}}) {}
  34.  
  35. vector< Elem<T> > v;
  36.  
  37. string toStr() const
  38. {
  39. stringstream res;
  40. unsigned int curr_depth=0;
  41.  
  42. bool isComma=false;
  43. for(const auto& e : v)
  44. {
  45. if(e.t == ElemType::DOWN) {res << (isComma?",":"") << "["; isComma=false;}
  46. else if(e.t == ElemType::UP) {res << "]"; isComma=true; }
  47. else if(e.t == ElemType::VAL) {res << ( (isComma)?",":"" ) << e.val; isComma=true;}
  48. else if(e.t == ElemType::NONE) {res << ""; isComma=true;}
  49. }
  50.  
  51. return res.str();
  52. }
  53. };
  54.  
  55. template <typename T>
  56. class MaybeMonad
  57. {
  58. public:
  59. MaybeMonad(const T& _data): isValid(true), data(_data) {}
  60. MaybeMonad() : isValid(false), data(0) {}
  61.  
  62. const bool isValid;
  63. const T data;
  64.  
  65. string toStr() const
  66. {
  67. if(isValid) return to_string(data);
  68. return "";
  69. }
  70. };
  71.  
  72.  
  73.  
  74. template <typename T=int>
  75. class Iterator
  76. {
  77. public:
  78. Iterator(const MyDS<T>& _d) : d(_d), index(0), n_vals(0), tot_n_vals(count()) {}
  79.  
  80. bool hasNext() const
  81. {
  82. return n_vals<tot_n_vals;
  83. }
  84.  
  85. MaybeMonad<T> get()
  86. {
  87. //MaybeMonad<T> res;
  88. if(!is_index_valid) {is_index_valid=true; index=0;}
  89. else index++;
  90. if(index == d.v.size()) throw runtime_error("No more elements");
  91. while( (d.v[index].t != ElemType::VAL) && (d.v[index].t != ElemType::NONE ) )
  92. {
  93. index++;
  94. if(index == d.v.size()) throw runtime_error("No more elements");
  95. }
  96.  
  97. n_vals++;
  98. if(d.v[index].t == ElemType::VAL) return MaybeMonad<T>(d.v[index].val);
  99. index++;
  100. return MaybeMonad<T>();
  101. }
  102.  
  103. private:
  104.  
  105. // Just get the reference, do not copy it
  106. const MyDS<T>& d;
  107.  
  108. bool is_index_valid;
  109. unsigned int index;
  110. unsigned int n_vals;
  111. unsigned int tot_n_vals;
  112.  
  113. // O(N) loop to count the actual elements
  114. unsigned int count() const
  115. {
  116. unsigned int res=0;
  117. for(const auto& e : d.v) res += ( (e.t == ElemType::VAL) || (e.t == ElemType::NONE) )?1:0;
  118. return res;
  119. }
  120. };
  121.  
  122. int main() {
  123. // your code goes here
  124. MyDS<> d;
  125. cout << d.toStr() << endl;
  126. Iterator<> it(d);
  127. while(it.hasNext()) cout << it.get().toStr() << ",";
  128. cout << endl;
  129. return 0;
  130. }
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
Success #stdin #stdout 0s 4436KB
stdin
Standard input is empty
stdout
[1,2],3,[4,5],[],[6]
1,2,3,4,5,,6,