#include <iostream>
#include <cassert>
#include <vector>
#include <cctype>
int const ADD_SIZE = 10;
class MyIntSet {
private:
std::pair<int, int> *setTable;
int tableSize;
int tableCapacitySize;
void _initialize();
void _erase(std::pair<int, int> *p);
void _insert(std::pair<int, int> *p, std::pair<int, int>q);
std::pair<int, int> *positionToInsert(int, bool &);
public:
MyIntSet() { this->_initialize(); }
MyIntSet(int beg, int end) {this->_initialize(); this->insert(beg, end); }
~MyIntSet();
void insert(int n);
void insert(int beg, int end);
void erase(int n);
bool isFoundP(int n);
bool isEmptyP();
bool isRegularP();
void dump();
};
/* コンストラクタ共通 */
void MyIntSet::_initialize() {
setTable = nullptr;
tableSize = 0;
tableCapacitySize = 0;
}
/* myVector 要素削除 */
/* 配列の縮小は行わない */
void MyIntSet::_erase(std::pair<int, int> *erase_point) {
assert(erase_point >= setTable && erase_point < &setTable[tableSize]);
std::pair<int, int> *p, *q;
if (tableSize > 0) {
p = erase_point;
q = p + 1;
for (; q != &setTable[tableSize]; p++, q++)
*p = *q;
--tableSize;
if (tableSize == 0) {
delete[] setTable;
setTable = nullptr;
tableCapacitySize = 0;
}
}
}
/* myVector 要素追加 */
void MyIntSet::_insert(std::pair<int, int> *insert_point, std::pair<int, int>insert_value) {
assert((insert_point >= setTable && insert_point <= &setTable[tableSize]) || (insert_point == nullptr && tableCapacitySize == 0));
if (tableSize >= tableCapacitySize) {
/* リサイズ */
tableCapacitySize += ADD_SIZE; tableCapacitySize *= 2;
std::pair<int, int> *setTableNew = new std::pair<int, int>[tableCapacitySize];
std::pair<int, int> *p, *q;
for (p = setTable, q = setTableNew; p != &setTable[tableSize]; p++, q++) {
*q = *p;
}
/* インサート位置のリサイズによる修正 */
if (insert_point == nullptr)
insert_point = setTableNew;
else
insert_point =setTableNew + (insert_point - setTable);
delete[] setTable;
setTable = setTableNew;
}
/* データの移動 */
std::pair<int, int> *p, *q;
if (tableSize > 0) {
p = &setTable[tableSize - 1];
q = &setTable[tableSize];
for (; p >= insert_point; --p, --q)
*q = *p;
}
tableSize++;
*insert_point = insert_value;
}
MyIntSet::~MyIntSet() { delete[] setTable; setTable = nullptr; }
/*-------------------------------------------------------------------------*/
/*
std::pair<int, int> *MyIntSet::positionToInsertObsolete(int n, bool &isInSet) {
std::pair<int, int> *p;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++) {
if (n >= p->first && n <= p->second) {
isInSet = true;
return p;
}
if (n < p->first) {
isInSet = false;
return p;
}
}
isInSet = false;
return p;
}
*/
/* binary-search */
std::pair<int, int> *MyIntSet::positionToInsert(int n, bool &isBelongToSet) {
int s = 0, t = tableSize, h;
if (tableSize == 0) {
isBelongToSet = false;
return setTable;
}
for (;;) {
if (s >= t) {
isBelongToSet = false;
return &setTable[t];
}
h = (s + t) / 2;
if (n >= setTable[h].first && n <= setTable[h].second) {
isBelongToSet = true;
return &setTable[h];
}
if (n < setTable[h].first) {
if ((h > 0 && n > setTable[h - 1].second) || h == 0) {
isBelongToSet = false;
return &setTable[h];
}
t = h;
continue;
}
if (n > setTable[h].second) {
s = h + 1;
continue;
}
std::cout << "positionToInsert(): s = " << s << ", t = " << t << std::endl;
assert(1==0);
}
}
/*-------------------------------------------------------------------------*/
/* 集合に n は含まれるか?*/
bool MyIntSet::isFoundP(int n) {
bool isBelongToMyIntSet;
this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (isBelongToMyIntSet) {
return true;
}
return false;
}
/* for デバッグ・ダンプ*/
void MyIntSet::dump() {
std::pair<int, int> *p;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++)
std::cout << p->first << "-" << p->second << ",";
std::cout << std::endl;
}
/* for デバッグ・集合の内部表現が矛盾なく正しいか?*/
bool MyIntSet::isRegularP() {
std::pair<int, int> *p;
bool isRegularReturn = true;
for (p = &this->setTable[0]; p != &this->setTable[tableSize]; p++) {
if (p->first > p->second) {
isRegularReturn = false;
break;
}
if (p != &setTable[0] && p->first <= (p - 1)->second) {
isRegularReturn = false;
break;
}
}
if (isRegularReturn == false) {
this->dump();
}
return isRegularReturn;
}
/* 集合への整数要素の追加 */
void MyIntSet::insert(int n) {
std::pair<int, int> *p;
bool isBelongToMyIntSet;
bool isStored = false;
p = this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (isBelongToMyIntSet) {
return;
}
if (p != &setTable[0] && (p - 1)->second == n - 1) {
(p - 1)->second = n;
isStored = true;
}
if (p != &setTable[tableSize] && p->first == n + 1) {
p->first = n;
isStored = true;
}
if (p != &setTable[tableSize] && (p - 1)->second == p->first) {
/* section merging */
(p - 1)->second = p->second;
this->_erase(p);
isStored = true;
}
if (!isStored)
this->_insert(p, std::pair<int, int>(n, n));
}
void MyIntSet::insert(int beg, int end) {
for (int n = beg; n <= end; n++)
this->insert(n);
}
/* 集合への整数要素の削除 */
void MyIntSet::erase(int n) {
std::pair<int, int> *p;
bool isBelongToMyIntSet;
p = this->positionToInsert(n, /*ref*/isBelongToMyIntSet);
if (!isBelongToMyIntSet) return;
if (n == p->first && n == p->second) {
this->_erase(p);
return;
}
if (n == p->first && n < p->second) {
p->first++;
return;
}
if (n == p->second && n > p->first) {
p->second--;
return;
}
/* division */
int q = p->second;
p->second = n - 1;
this->_insert(++p, std::pair<int, int>(n + 1, q));
}
bool MyIntSet::isEmptyP() {
return (this->tableSize == 0);
}
/*-------------------------------------------------*/
int const min = 1;
int const max = 999;
void anchor_list(std::string str) {
MyIntSet myIntSet;
if (str.find(">>") != 0) return;
std::string::const_iterator p = str.begin(), q;
p++; p++;
for (; p != str.end();) {
if (!isdigit(*p))
break;
q = p;
while (isdigit(*p)) p++;
int n = std::atoi(std::string(q, p).c_str());
if (p == str.end()) {
myIntSet.insert(n);
break;
}
if (*p == ',') {
myIntSet.insert(n);
p++;
continue;
}
if (*p == '-') {
p++;
if (*p == ',') {
myIntSet.insert(n, max);
p++;
continue;
}
if (p == str.end()) {
myIntSet.insert(n, max);
continue;
}
if (isdigit(*p)) {
q = p;
while (isdigit(*p)) p++;
int m = std::atoi(std::string(q, p).c_str());
if (n > m) {int t = n; n = m; m = t; }
myIntSet.insert(n, m);
if (*p == ',') {
p++;
continue;
}
}
break;
}
}
int buf = -1;
std::cout << "[ ";
for (int n = min; n <= max; n++) {
if (myIntSet.isFoundP(n)) {
if (buf != -1) std::cout << buf << ",";
buf = n;
}
}
if (buf != -1)
std::cout << buf;
std::cout << " ]";
}
void f(std::string str) {
std::cout << str << " : ";
anchor_list(str);
std::cout << std::endl;
}
int main() {
f(">>1");
f(">>1-3");
f(">>1,3");
f(">>1,3-5");
f(">>1,1");
f(">>1-3,2");
f(">>1-4,2-3");
f(">>1-4,3-5");
f(">>1-3,5,9-10");
f(">>000000-000000001");
f(">>2894");
f(">>0-2,998-1000");
f(">>3,0-3,4,5,6,4,2-8");
f(">>1-3,5,9-10");
f(">>4-1");
f(">>7-4,5-9");
f(">>990-");
f(">>5-5");
f(">>6-5,998-,10-8");
return 0;
}
/* end */
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNjdHlwZT4KIAppbnQgY29uc3QgQUREX1NJWkUgPSAxMDsKIApjbGFzcyBNeUludFNldCB7CnByaXZhdGU6CiAgc3RkOjpwYWlyPGludCwgaW50PiAqc2V0VGFibGU7CiAgaW50IHRhYmxlU2l6ZTsKICBpbnQgdGFibGVDYXBhY2l0eVNpemU7CiAKICB2b2lkIF9pbml0aWFsaXplKCk7CiAgdm9pZCBfZXJhc2Uoc3RkOjpwYWlyPGludCwgaW50PiAqcCk7CiAgdm9pZCBfaW5zZXJ0KHN0ZDo6cGFpcjxpbnQsIGludD4gKnAsIHN0ZDo6cGFpcjxpbnQsIGludD5xKTsKIAogIHN0ZDo6cGFpcjxpbnQsIGludD4gKnBvc2l0aW9uVG9JbnNlcnQoaW50LCAgYm9vbCAmKTsKIApwdWJsaWM6CiAgTXlJbnRTZXQoKSB7IHRoaXMtPl9pbml0aWFsaXplKCk7IH0KICBNeUludFNldChpbnQgYmVnLCBpbnQgZW5kKSB7dGhpcy0+X2luaXRpYWxpemUoKTsgdGhpcy0+aW5zZXJ0KGJlZywgZW5kKTsgfQogIH5NeUludFNldCgpOwogIHZvaWQgaW5zZXJ0KGludCBuKTsKICB2b2lkIGluc2VydChpbnQgYmVnLCBpbnQgZW5kKTsKICB2b2lkIGVyYXNlKGludCBuKTsKICBib29sIGlzRm91bmRQKGludCBuKTsKICBib29sIGlzRW1wdHlQKCk7CiAKICBib29sIGlzUmVndWxhclAoKTsKICB2b2lkIGR1bXAoKTsKIAp9OwogCi8qIOOCs+ODs+OCueODiOODqeOCr+OCv+WFsemAmiAqLwp2b2lkIE15SW50U2V0OjpfaW5pdGlhbGl6ZSgpIHsKICBzZXRUYWJsZSA9IG51bGxwdHI7CiAgdGFibGVTaXplID0gMDsKICB0YWJsZUNhcGFjaXR5U2l6ZSA9IDA7Cn0KIAovKiBteVZlY3RvciDopoHntKDliYrpmaQgICovCi8qIOmFjeWIl+OBrue4ruWwj+OBr+ihjOOCj+OBquOBhCAqLwp2b2lkIE15SW50U2V0OjpfZXJhc2Uoc3RkOjpwYWlyPGludCwgaW50PiAqZXJhc2VfcG9pbnQpIHsKICBhc3NlcnQoZXJhc2VfcG9pbnQgPj0gc2V0VGFibGUgJiYgZXJhc2VfcG9pbnQgPCAmc2V0VGFibGVbdGFibGVTaXplXSk7CiAgc3RkOjpwYWlyPGludCwgaW50PiAqcCwgKnE7CiAgaWYgKHRhYmxlU2l6ZSA+IDApIHsKICAgIHAgPSBlcmFzZV9wb2ludDsKICAgIHEgPSBwICsgMTsKICAgIGZvciAoOyBxICE9ICZzZXRUYWJsZVt0YWJsZVNpemVdOyBwKyssIHErKykKICAgICAgKnAgPSAqcTsKICAgIC0tdGFibGVTaXplOwogICAgaWYgKHRhYmxlU2l6ZSA9PSAwKSB7CiAgICAgIGRlbGV0ZVtdIHNldFRhYmxlOwogICAgICBzZXRUYWJsZSA9IG51bGxwdHI7CiAgICAgIHRhYmxlQ2FwYWNpdHlTaXplID0gMDsKICAgIH0KICB9ICAKfQogCi8qIG15VmVjdG9yIOimgee0oOi/veWKoCAgKi8Kdm9pZCBNeUludFNldDo6X2luc2VydChzdGQ6OnBhaXI8aW50LCBpbnQ+ICppbnNlcnRfcG9pbnQsIHN0ZDo6cGFpcjxpbnQsIGludD5pbnNlcnRfdmFsdWUpIHsKICBhc3NlcnQoKGluc2VydF9wb2ludCA+PSBzZXRUYWJsZSAmJiBpbnNlcnRfcG9pbnQgPD0gJnNldFRhYmxlW3RhYmxlU2l6ZV0pIHx8IChpbnNlcnRfcG9pbnQgPT0gbnVsbHB0ciAmJiB0YWJsZUNhcGFjaXR5U2l6ZSA9PSAwKSk7CiAKICBpZiAodGFibGVTaXplID49IHRhYmxlQ2FwYWNpdHlTaXplKSB7CiAgICAvKiDjg6rjgrXjgqTjgrogKi8KICAgIHRhYmxlQ2FwYWNpdHlTaXplICs9IEFERF9TSVpFOyB0YWJsZUNhcGFjaXR5U2l6ZSAqPSAyOwogICAgc3RkOjpwYWlyPGludCwgaW50PiAqc2V0VGFibGVOZXcgPSBuZXcgc3RkOjpwYWlyPGludCwgaW50Plt0YWJsZUNhcGFjaXR5U2l6ZV07CiAgICBzdGQ6OnBhaXI8aW50LCBpbnQ+ICpwLCAqcTsKICAgIGZvciAocCA9IHNldFRhYmxlLCBxID0gc2V0VGFibGVOZXc7IHAgIT0gJnNldFRhYmxlW3RhYmxlU2l6ZV07IHArKywgcSsrKSB7CiAgICAgICpxID0gKnA7CiAgICB9CiAgICAvKiDjgqTjg7PjgrXjg7zjg4jkvY3nva7jga7jg6rjgrXjgqTjgrrjgavjgojjgovkv67mraMgKi8KICAgIGlmIChpbnNlcnRfcG9pbnQgPT0gbnVsbHB0cikKICAgICAgaW5zZXJ0X3BvaW50ID0gc2V0VGFibGVOZXc7CiAgICBlbHNlCiAgICAgIGluc2VydF9wb2ludCA9c2V0VGFibGVOZXcgKyAoaW5zZXJ0X3BvaW50IC0gc2V0VGFibGUpOwogCiAgICBkZWxldGVbXSBzZXRUYWJsZTsKICAgIHNldFRhYmxlID0gc2V0VGFibGVOZXc7CiAgfQogCiAgLyog44OH44O844K/44Gu56e75YuVICovCiAgc3RkOjpwYWlyPGludCwgaW50PiAqcCwgKnE7CiAgaWYgKHRhYmxlU2l6ZSA+IDApIHsKICAgIHAgPSAmc2V0VGFibGVbdGFibGVTaXplIC0gMV07CiAgICBxID0gJnNldFRhYmxlW3RhYmxlU2l6ZV07CiAgICBmb3IgKDsgcCA+PSBpbnNlcnRfcG9pbnQ7IC0tcCwgLS1xKQogICAgICAqcSA9ICpwOwogIH0KICB0YWJsZVNpemUrKzsKICAqaW5zZXJ0X3BvaW50ID0gaW5zZXJ0X3ZhbHVlOwp9CiAKTXlJbnRTZXQ6On5NeUludFNldCgpIHsgZGVsZXRlW10gc2V0VGFibGU7IHNldFRhYmxlID0gbnVsbHB0cjsgfQogCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCi8qCnN0ZDo6cGFpcjxpbnQsIGludD4gKk15SW50U2V0Ojpwb3NpdGlvblRvSW5zZXJ0T2Jzb2xldGUoaW50IG4sIGJvb2wgJmlzSW5TZXQpIHsKICBzdGQ6OnBhaXI8aW50LCBpbnQ+ICpwOwogIGZvciAocCA9ICZ0aGlzLT5zZXRUYWJsZVswXTsgcCAhPSAmdGhpcy0+c2V0VGFibGVbdGFibGVTaXplXTsgcCsrKSB7CiAgICBpZiAobiA+PSBwLT5maXJzdCAmJiBuIDw9IHAtPnNlY29uZCkgewogICAgICBpc0luU2V0ID0gdHJ1ZTsKICAgICAgcmV0dXJuIHA7CiAgICB9CiAgICBpZiAobiA8IHAtPmZpcnN0KSB7CiAgICAgIGlzSW5TZXQgPSBmYWxzZTsKICAgICAgcmV0dXJuIHA7CiAgICB9CiAgfQogIGlzSW5TZXQgPSBmYWxzZTsKICByZXR1cm4gcDsKfQoqLwogCi8qIGJpbmFyeS1zZWFyY2ggKi8Kc3RkOjpwYWlyPGludCwgaW50PiAqTXlJbnRTZXQ6OnBvc2l0aW9uVG9JbnNlcnQoaW50IG4sIGJvb2wgJmlzQmVsb25nVG9TZXQpIHsKICBpbnQgcyA9IDAsIHQgPSB0YWJsZVNpemUsIGg7CiAgaWYgKHRhYmxlU2l6ZSA9PSAwKSB7CiAgICBpc0JlbG9uZ1RvU2V0ID0gZmFsc2U7CiAgICByZXR1cm4gc2V0VGFibGU7CiAgfQogIGZvciAoOzspIHsKICAgIGlmIChzID49IHQpIHsKICAgICAgaXNCZWxvbmdUb1NldCA9IGZhbHNlOwogICAgICByZXR1cm4gJnNldFRhYmxlW3RdOwogICAgfQogCiAgICBoID0gKHMgKyB0KSAvIDI7CiAKICAgIGlmIChuID49IHNldFRhYmxlW2hdLmZpcnN0ICYmIG4gPD0gc2V0VGFibGVbaF0uc2Vjb25kKSB7CiAgICAgIGlzQmVsb25nVG9TZXQgPSB0cnVlOwogICAgICByZXR1cm4gJnNldFRhYmxlW2hdOwogICAgfQogICAgaWYgKG4gPCBzZXRUYWJsZVtoXS5maXJzdCkgewogICAgICBpZiAoKGggPiAwICYmIG4gPiBzZXRUYWJsZVtoIC0gMV0uc2Vjb25kKSB8fCBoID09IDApIHsKICAgICAgICBpc0JlbG9uZ1RvU2V0ID0gZmFsc2U7CiAgICAgICAgcmV0dXJuICZzZXRUYWJsZVtoXTsKICAgICAgfQogICAgICB0ID0gaDsKICAgICAgY29udGludWU7CiAgICB9CiAgICBpZiAobiA+IHNldFRhYmxlW2hdLnNlY29uZCkgewogICAgICBzID0gaCArIDE7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgc3RkOjpjb3V0IDw8ICJwb3NpdGlvblRvSW5zZXJ0KCk6IHMgPSAiIDw8IHMgPDwgIiwgdCA9ICIgPDwgdCA8PCBzdGQ6OmVuZGw7CiAgICBhc3NlcnQoMT09MCk7CiAgfQp9CiAKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLyog6ZuG5ZCI44GrIG4g44Gv5ZCr44G+44KM44KL44GL77yfKi8KYm9vbCBNeUludFNldDo6aXNGb3VuZFAoaW50IG4pIHsKICBib29sIGlzQmVsb25nVG9NeUludFNldDsKIAogIHRoaXMtPnBvc2l0aW9uVG9JbnNlcnQobiwgLypyZWYqL2lzQmVsb25nVG9NeUludFNldCk7CiAgaWYgKGlzQmVsb25nVG9NeUludFNldCkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIHJldHVybiBmYWxzZTsKfQogCi8qIGZvciDjg4fjg5Djg4PjgrDjg7vjg4Djg7Pjg5cqLwp2b2lkIE15SW50U2V0OjpkdW1wKCkgewogIHN0ZDo6cGFpcjxpbnQsIGludD4gKnA7CiAgZm9yIChwID0gJnRoaXMtPnNldFRhYmxlWzBdOyBwICE9ICZ0aGlzLT5zZXRUYWJsZVt0YWJsZVNpemVdOyBwKyspCiAgICBzdGQ6OmNvdXQgPDwgcC0+Zmlyc3QgPDwgIi0iIDw8IHAtPnNlY29uZCA8PCAiLCI7CiAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKfQogCi8qIGZvciDjg4fjg5Djg4PjgrDjg7vpm4blkIjjga7lhoXpg6jooajnj77jgYznn5vnm77jgarjgY/mraPjgZfjgYTjgYvvvJ8qLwpib29sIE15SW50U2V0Ojppc1JlZ3VsYXJQKCkgewogIHN0ZDo6cGFpcjxpbnQsIGludD4gKnA7CiAgYm9vbCBpc1JlZ3VsYXJSZXR1cm4gPSB0cnVlOwogIGZvciAocCA9ICZ0aGlzLT5zZXRUYWJsZVswXTsgcCAhPSAmdGhpcy0+c2V0VGFibGVbdGFibGVTaXplXTsgcCsrKSB7CiAgICBpZiAocC0+Zmlyc3QgPiBwLT5zZWNvbmQpIHsKICAgICAgaXNSZWd1bGFyUmV0dXJuID0gZmFsc2U7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHAgIT0gJnNldFRhYmxlWzBdICYmIHAtPmZpcnN0IDw9IChwIC0gMSktPnNlY29uZCkgewogICAgICBpc1JlZ3VsYXJSZXR1cm4gPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgICB9CiAgfSAgCiAgaWYgKGlzUmVndWxhclJldHVybiA9PSBmYWxzZSkgewogICAgdGhpcy0+ZHVtcCgpOwogIH0KICByZXR1cm4gaXNSZWd1bGFyUmV0dXJuOwp9CiAKLyog6ZuG5ZCI44G444Gu5pW05pWw6KaB57Sg44Gu6L+95YqgICovCnZvaWQgTXlJbnRTZXQ6Omluc2VydChpbnQgbikgewogIHN0ZDo6cGFpcjxpbnQsIGludD4gKnA7ICAKICBib29sIGlzQmVsb25nVG9NeUludFNldDsKICBib29sIGlzU3RvcmVkID0gZmFsc2U7CiAKICBwID0gdGhpcy0+cG9zaXRpb25Ub0luc2VydChuLCAvKnJlZiovaXNCZWxvbmdUb015SW50U2V0KTsKICBpZiAoaXNCZWxvbmdUb015SW50U2V0KSB7CiAgICByZXR1cm47CiAgfQogIGlmIChwICE9ICZzZXRUYWJsZVswXSAmJiAocCAtIDEpLT5zZWNvbmQgPT0gbiAtIDEpIHsKICAgIChwIC0gMSktPnNlY29uZCA9IG47CiAgICBpc1N0b3JlZCA9IHRydWU7CiAgfQogIGlmIChwICE9ICZzZXRUYWJsZVt0YWJsZVNpemVdICYmIHAtPmZpcnN0ID09IG4gKyAxKSB7CiAgICBwLT5maXJzdCA9IG47CiAgICBpc1N0b3JlZCA9IHRydWU7CiAgfQogIGlmIChwICE9ICZzZXRUYWJsZVt0YWJsZVNpemVdICYmIChwIC0gMSktPnNlY29uZCA9PSBwLT5maXJzdCkgewogICAgLyogc2VjdGlvbiBtZXJnaW5nICovCiAgICAocCAtIDEpLT5zZWNvbmQgPSBwLT5zZWNvbmQ7CiAgICB0aGlzLT5fZXJhc2UocCk7CiAgICBpc1N0b3JlZCA9IHRydWU7CiAgfQogIGlmICghaXNTdG9yZWQpCiAgICB0aGlzLT5faW5zZXJ0KHAsIHN0ZDo6cGFpcjxpbnQsIGludD4obiwgbikpOwp9CiAKdm9pZCBNeUludFNldDo6aW5zZXJ0KGludCBiZWcsIGludCBlbmQpIHsKICBmb3IgKGludCBuID0gYmVnOyBuIDw9IGVuZDsgbisrKQogICAgdGhpcy0+aW5zZXJ0KG4pOwp9CiAKLyog6ZuG5ZCI44G444Gu5pW05pWw6KaB57Sg44Gu5YmK6ZmkICovCnZvaWQgTXlJbnRTZXQ6OmVyYXNlKGludCBuKSB7CiAgc3RkOjpwYWlyPGludCwgaW50PiAqcDsgIAogIGJvb2wgaXNCZWxvbmdUb015SW50U2V0OwogCiAgcCA9IHRoaXMtPnBvc2l0aW9uVG9JbnNlcnQobiwgLypyZWYqL2lzQmVsb25nVG9NeUludFNldCk7CiAgaWYgKCFpc0JlbG9uZ1RvTXlJbnRTZXQpIHJldHVybjsKIAogIGlmIChuID09IHAtPmZpcnN0ICYmIG4gPT0gcC0+c2Vjb25kKSB7CiAgICB0aGlzLT5fZXJhc2UocCk7CiAgICByZXR1cm47CiAgfQogCiAgaWYgKG4gPT0gcC0+Zmlyc3QgJiYgbiA8IHAtPnNlY29uZCkgewogICAgcC0+Zmlyc3QrKzsKICAgIHJldHVybjsKICB9CiAgaWYgKG4gPT0gcC0+c2Vjb25kICYmIG4gPiBwLT5maXJzdCkgewogICAgcC0+c2Vjb25kLS07CiAgICByZXR1cm47CiAgfQogIC8qIGRpdmlzaW9uICovCiAgaW50IHEgPSBwLT5zZWNvbmQ7CiAgcC0+c2Vjb25kID0gbiAtIDE7CiAgdGhpcy0+X2luc2VydCgrK3AsIHN0ZDo6cGFpcjxpbnQsIGludD4obiArIDEsIHEpKTsKfQogCmJvb2wgTXlJbnRTZXQ6OmlzRW1wdHlQKCkgewogIHJldHVybiAodGhpcy0+dGFibGVTaXplID09IDApOwp9CiAKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KaW50IGNvbnN0IG1pbiA9IDE7CmludCBjb25zdCBtYXggPSA5OTk7CiAKdm9pZCBhbmNob3JfbGlzdChzdGQ6OnN0cmluZyBzdHIpIHsKICBNeUludFNldCBteUludFNldDsKIAogIGlmIChzdHIuZmluZCgiPj4iKSAhPSAwKSByZXR1cm47CiAgc3RkOjpzdHJpbmc6OmNvbnN0X2l0ZXJhdG9yIHAgPSBzdHIuYmVnaW4oKSwgcTsKICBwKys7IHArKzsKICBmb3IgKDsgcCAhPSBzdHIuZW5kKCk7KSB7CiAgICBpZiAoIWlzZGlnaXQoKnApKQogICAgICBicmVhazsKICAgIHEgPSBwOwogICAgd2hpbGUgKGlzZGlnaXQoKnApKSBwKys7CiAgICBpbnQgbiA9IHN0ZDo6YXRvaShzdGQ6OnN0cmluZyhxLCBwKS5jX3N0cigpKTsKICAgIGlmIChwID09IHN0ci5lbmQoKSkgewogICAgICBteUludFNldC5pbnNlcnQobik7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKCpwID09ICcsJykgewogICAgICBteUludFNldC5pbnNlcnQobik7CiAgICAgIHArKzsKICAgICAgY29udGludWU7CiAgICB9CiAgICBpZiAoKnAgPT0gJy0nKSB7CiAgICAgIHArKzsKICAgICAgaWYgKCpwID09ICcsJykgewogICAgICAgIG15SW50U2V0Lmluc2VydChuLCBtYXgpOwogICAgICAgIHArKzsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAocCA9PSBzdHIuZW5kKCkpIHsKICAgICAgICBteUludFNldC5pbnNlcnQobiwgbWF4KTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaXNkaWdpdCgqcCkpIHsKICAgICAgICBxID0gcDsKICAgICAgICB3aGlsZSAoaXNkaWdpdCgqcCkpIHArKzsKICAgICAgICBpbnQgbSA9IHN0ZDo6YXRvaShzdGQ6OnN0cmluZyhxLCBwKS5jX3N0cigpKTsKICAgICAgICBpZiAobiA+IG0pIHtpbnQgdCA9IG47IG4gPSBtOyBtID0gdDsgfQogICAgICAgIG15SW50U2V0Lmluc2VydChuLCBtKTsKICAgICAgICBpZiAoKnAgPT0gJywnKSB7CiAgICAgICAgICBwKys7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICB9CiAgfSAgICAKICBpbnQgYnVmID0gLTE7CiAgc3RkOjpjb3V0IDw8ICJbICI7CiAKICBmb3IgKGludCBuID0gbWluOyBuIDw9IG1heDsgbisrKSB7CiAgICBpZiAobXlJbnRTZXQuaXNGb3VuZFAobikpIHsKICAgICAgaWYgKGJ1ZiAhPSAtMSkgc3RkOjpjb3V0IDw8IGJ1ZiA8PCAiLCI7CiAgICAgIGJ1ZiA9IG47CiAgICB9CiAgfQogIGlmIChidWYgIT0gLTEpCiAgICBzdGQ6OmNvdXQgPDwgYnVmOwogIHN0ZDo6Y291dCA8PCAiIF0iOwp9CiAKdm9pZCBmKHN0ZDo6c3RyaW5nIHN0cikgewogIHN0ZDo6Y291dCA8PCBzdHIgPDwgIiA6ICI7CiAgYW5jaG9yX2xpc3Qoc3RyKTsKICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwp9CiAKaW50IG1haW4oKSB7CiAgZigiPj4xIik7CiAgZigiPj4xLTMiKTsKICBmKCI+PjEsMyIpOwogIGYoIj4+MSwzLTUiKTsKICBmKCI+PjEsMSIpOwogIGYoIj4+MS0zLDIiKTsKICBmKCI+PjEtNCwyLTMiKTsKICBmKCI+PjEtNCwzLTUiKTsKCiAgZigiPj4xLTMsNSw5LTEwIik7CiAgZigiPj4wMDAwMDAtMDAwMDAwMDAxIik7CiAgZigiPj4yODk0Iik7CiAgZigiPj4wLTIsOTk4LTEwMDAiKTsKICBmKCI+PjMsMC0zLDQsNSw2LDQsMi04Iik7CiAgZigiPj4xLTMsNSw5LTEwIik7CiAgZigiPj40LTEiKTsKICBmKCI+PjctNCw1LTkiKTsKICBmKCI+Pjk5MC0iKTsKICBmKCI+PjUtNSIpOwogIGYoIj4+Ni01LDk5OC0sMTAtOCIpOwoKICByZXR1cm4gMDsKfQovKiBlbmQgKi8KIA==
>>1 : [ 1 ]
>>1-3 : [ 1,2,3 ]
>>1,3 : [ 1,3 ]
>>1,3-5 : [ 1,3,4,5 ]
>>1,1 : [ 1 ]
>>1-3,2 : [ 1,2,3 ]
>>1-4,2-3 : [ 1,2,3,4 ]
>>1-4,3-5 : [ 1,2,3,4,5 ]
>>1-3,5,9-10 : [ 1,2,3,5,9,10 ]
>>000000-000000001 : [ 1 ]
>>2894 : [ ]
>>0-2,998-1000 : [ 1,2,998,999 ]
>>3,0-3,4,5,6,4,2-8 : [ 1,2,3,4,5,6,7,8 ]
>>1-3,5,9-10 : [ 1,2,3,5,9,10 ]
>>4-1 : [ 1,2,3,4 ]
>>7-4,5-9 : [ 4,5,6,7,8,9 ]
>>990- : [ 990,991,992,993,994,995,996,997,998,999 ]
>>5-5 : [ 5 ]
>>6-5,998-,10-8 : [ 5,6,8,9,10,998,999 ]