#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
enum class ElemType
{
VAL,
DOWN,
UP,
NONE
};
template <typename T>
class Elem
{
public:
Elem(): t(ElemType::VAL), val(0) {}
Elem(const ElemType _t, const T _val): t(_t), val(_val) {}
Elem(const ElemType _t) : Elem(_t, 0) {}
ElemType t;
T val;
};
template <typename T=int>
class MyDS
{
public:
// Initialization Example: [1,2],3,[4,5],[], [6]
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}}) {}
vector< Elem<T> > v;
string toStr() const
{
stringstream res;
unsigned int curr_depth=0;
bool isComma=false;
for(const auto& e : v)
{
if(e.t == ElemType::DOWN) {res << (isComma?",":"") << "["; isComma=false;}
else if(e.t == ElemType::UP) {res << "]"; isComma=true; }
else if(e.t == ElemType::VAL) {res << ( (isComma)?",":"" ) << e.val; isComma=true;}
else if(e.t == ElemType::NONE) {res << ""; isComma=true;}
}
return res.str();
}
};
template <typename T>
class MaybeMonad
{
public:
MaybeMonad(const T& _data): isValid(true), data(_data) {}
MaybeMonad() : isValid(false), data(0) {}
const bool isValid;
const T data;
string toStr() const
{
if(isValid) return to_string(data);
return "";
}
};
template <typename T=int>
class Iterator
{
public:
Iterator(const MyDS<T>& _d) : d(_d), index(0), n_vals(0), tot_n_vals(count()) {}
bool hasNext() const
{
return n_vals<tot_n_vals;
}
MaybeMonad<T> get()
{
//MaybeMonad<T> res;
if(!is_index_valid) {is_index_valid=true; index=0;}
else index++;
if(index == d.v.size()) throw runtime_error("No more elements");
while( (d.v[index].t != ElemType::VAL) && (d.v[index].t != ElemType::NONE ) )
{
index++;
if(index == d.v.size()) throw runtime_error("No more elements");
}
n_vals++;
if(d.v[index].t == ElemType::VAL) return MaybeMonad<T>(d.v[index].val);
index++;
return MaybeMonad<T>();
}
private:
// Just get the reference, do not copy it
const MyDS<T>& d;
bool is_index_valid;
unsigned int index;
unsigned int n_vals;
unsigned int tot_n_vals;
// O(N) loop to count the actual elements
unsigned int count() const
{
unsigned int res=0;
for(const auto& e : d.v) res += ( (e.t == ElemType::VAL) || (e.t == ElemType::NONE) )?1:0;
return res;
}
};
int main() {
// your code goes here
MyDS<> d;
cout << d.toStr() << endl;
Iterator<> it(d);
while(it.hasNext()) cout << it.get().toStr() << ",";
cout << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c3N0cmVhbT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmVudW0gY2xhc3MgRWxlbVR5cGUKewoJVkFMLCAKCURPV04sIAoJVVAsIAoJTk9ORQp9OyAKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyBFbGVtCnsKCXB1YmxpYzogCglFbGVtKCk6IHQoRWxlbVR5cGU6OlZBTCksIHZhbCgwKSB7fQoJRWxlbShjb25zdCBFbGVtVHlwZSBfdCwgY29uc3QgVCBfdmFsKTogdChfdCksIHZhbChfdmFsKSB7fQoJRWxlbShjb25zdCBFbGVtVHlwZSBfdCkgOiBFbGVtKF90LCAwKSB7fQoJCglFbGVtVHlwZSB0OyAKCVQgdmFsOyAKfTsgCgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ9aW50PgpjbGFzcyBNeURTCnsKCXB1YmxpYzogCgkvLyBJbml0aWFsaXphdGlvbiBFeGFtcGxlOiBbMSwyXSwzLFs0LDVdLFtdLCBbNl0KCU15RFMoKTogdih7e0VsZW1UeXBlOjpET1dOfSwge0VsZW1UeXBlOjpWQUwsMX0sIHtFbGVtVHlwZTo6VkFMLDJ9LCB7RWxlbVR5cGU6OlVQfSwge0VsZW1UeXBlOjpWQUwsM30sIHtFbGVtVHlwZTo6RE9XTn0sIHtFbGVtVHlwZTo6VkFMLDR9LCB7RWxlbVR5cGU6OlZBTCw1fSwge0VsZW1UeXBlOjpVUH0sIHtFbGVtVHlwZTo6RE9XTn0sIHtFbGVtVHlwZTo6Tk9ORX0sIHtFbGVtVHlwZTo6VVB9LCB7RWxlbVR5cGU6OkRPV059LCB7RWxlbVR5cGU6OlZBTCw2fSwge0VsZW1UeXBlOjpVUH19KSB7fQoJCgl2ZWN0b3I8IEVsZW08VD4gPiB2OwoJCglzdHJpbmcgdG9TdHIoKSBjb25zdCAKCXsKCQlzdHJpbmdzdHJlYW0gcmVzOyAKCQl1bnNpZ25lZCBpbnQgY3Vycl9kZXB0aD0wOyAKCQkKCQlib29sIGlzQ29tbWE9ZmFsc2U7IAoJCWZvcihjb25zdCBhdXRvJiBlIDogdikKCQl7CgkJCWlmKGUudCA9PSBFbGVtVHlwZTo6RE9XTikge3JlcyA8PCAoaXNDb21tYT8iLCI6IiIpIDw8ICJbIjsgaXNDb21tYT1mYWxzZTt9IAoJCQllbHNlIGlmKGUudCA9PSBFbGVtVHlwZTo6VVApIHtyZXMgPDwgIl0iOyBpc0NvbW1hPXRydWU7IH0KCQkJZWxzZSBpZihlLnQgPT0gRWxlbVR5cGU6OlZBTCkge3JlcyA8PCAoIChpc0NvbW1hKT8iLCI6IiIgKSA8PCBlLnZhbDsgaXNDb21tYT10cnVlO30gCgkJCWVsc2UgaWYoZS50ID09IEVsZW1UeXBlOjpOT05FKSB7cmVzIDw8ICIiOyBpc0NvbW1hPXRydWU7fSAKCQl9CgkJCgkJcmV0dXJuIHJlcy5zdHIoKTsgCgl9Cn07IAoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIE1heWJlTW9uYWQKewoJcHVibGljOiAKCU1heWJlTW9uYWQoY29uc3QgVCYgX2RhdGEpOiBpc1ZhbGlkKHRydWUpLCBkYXRhKF9kYXRhKSB7fQoJTWF5YmVNb25hZCgpIDogaXNWYWxpZChmYWxzZSksIGRhdGEoMCkge30KCQoJY29uc3QgYm9vbCBpc1ZhbGlkOyAKCWNvbnN0IFQgZGF0YTsgCgkKCXN0cmluZyB0b1N0cigpIGNvbnN0IAoJewoJCWlmKGlzVmFsaWQpIHJldHVybiB0b19zdHJpbmcoZGF0YSk7IAoJCXJldHVybiAiIjsgCgl9Cn07IAoKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD1pbnQ+CmNsYXNzIEl0ZXJhdG9yCnsKCXB1YmxpYzogCglJdGVyYXRvcihjb25zdCBNeURTPFQ+JiBfZCkgOiBkKF9kKSwgaW5kZXgoMCksIG5fdmFscygwKSwgdG90X25fdmFscyhjb3VudCgpKSB7fQoJCglib29sIGhhc05leHQoKSBjb25zdAoJewoJCXJldHVybiBuX3ZhbHM8dG90X25fdmFsczsgCgl9CgkKCU1heWJlTW9uYWQ8VD4gZ2V0KCkgIAoJewoJCS8vTWF5YmVNb25hZDxUPiByZXM7IAoJCWlmKCFpc19pbmRleF92YWxpZCkge2lzX2luZGV4X3ZhbGlkPXRydWU7IGluZGV4PTA7fQoJCWVsc2UgaW5kZXgrKzsgCgkJaWYoaW5kZXggPT0gZC52LnNpemUoKSkgdGhyb3cgcnVudGltZV9lcnJvcigiTm8gbW9yZSBlbGVtZW50cyIpOyAKCQl3aGlsZSggKGQudltpbmRleF0udCAhPSBFbGVtVHlwZTo6VkFMKSAmJiAoZC52W2luZGV4XS50ICE9IEVsZW1UeXBlOjpOT05FICkgKQoJCXsKCQkJaW5kZXgrKzsgCgkJCWlmKGluZGV4ID09IGQudi5zaXplKCkpIHRocm93IHJ1bnRpbWVfZXJyb3IoIk5vIG1vcmUgZWxlbWVudHMiKTsgCgkJfQoJCQoJCW5fdmFscysrOyAJCQoJCWlmKGQudltpbmRleF0udCA9PSBFbGVtVHlwZTo6VkFMKSByZXR1cm4gTWF5YmVNb25hZDxUPihkLnZbaW5kZXhdLnZhbCk7IAoJCWluZGV4Kys7IAoJCXJldHVybiBNYXliZU1vbmFkPFQ+KCk7IAoJfQoJCglwcml2YXRlOiAKCQoJLy8gSnVzdCBnZXQgdGhlIHJlZmVyZW5jZSwgZG8gbm90IGNvcHkgaXQgCgljb25zdCBNeURTPFQ+JiBkOyAKCQoJYm9vbCBpc19pbmRleF92YWxpZDsgCgl1bnNpZ25lZCBpbnQgaW5kZXg7IAoJdW5zaWduZWQgaW50IG5fdmFsczsgCgl1bnNpZ25lZCBpbnQgdG90X25fdmFsczsgCgkKCS8vIE8oTikgbG9vcCB0byBjb3VudCB0aGUgYWN0dWFsIGVsZW1lbnRzIAoJdW5zaWduZWQgaW50IGNvdW50KCkgY29uc3QgCgl7CgkJdW5zaWduZWQgaW50IHJlcz0wOyAKCQlmb3IoY29uc3QgYXV0byYgZSA6IGQudikgcmVzICs9ICggKGUudCA9PSBFbGVtVHlwZTo6VkFMKSB8fCAoZS50ID09IEVsZW1UeXBlOjpOT05FKSApPzE6MDsgCgkJcmV0dXJuIHJlczsgCgl9Cn07IAoKaW50IG1haW4oKSB7CgkvLyB5b3VyIGNvZGUgZ29lcyBoZXJlCglNeURTPD4gZDsgCgljb3V0IDw8IGQudG9TdHIoKSA8PCBlbmRsOyAKCUl0ZXJhdG9yPD4gaXQoZCk7IAoJd2hpbGUoaXQuaGFzTmV4dCgpKSBjb3V0IDw8IGl0LmdldCgpLnRvU3RyKCkgPDwgIiwiOyAKCWNvdXQgPDwgZW5kbDsgCglyZXR1cm4gMDsKfQoKCgoKCgoKCgoKCgoK