#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename It, class Pr>
It remove_neighbors(It first, It last, int nSpan, Pr Pred) {
if (first == last || nSpan <= 0) return last;
It lastGood = first;
It cur = first;
++cur;
for (; cur != last; ++cur) {
bool found = false;
It back = lastGood;
for (int i = nSpan; i > 0; --i, --back) {
if (Pred(*back, *cur)) {
found = true;
lastGood = back;
break;
}
if (back == first) break;
}
if (!found) {
++lastGood;
*lastGood = std::move(*cur);
}
}
++lastGood;
return lastGood;
}
void test_remove_neighbors(const string& in, int nSpan) {
vector<char> v(in.begin(), in.end());
vector<char>::iterator trash =
remove_neighbors(v.begin(), v.end(), nSpan, equal_to<char>());
string out(v.begin(), trash);
cout << "In: " << in << " span: " << nSpan << " out: " << out << endl;
}
int main(int argc, char *argv[])
{
// No ops:
test_remove_neighbors("abab", 1);
test_remove_neighbors("abcabc", 2);
// unique
test_remove_neighbors("aabbaaabbb", 1);
// simple
test_remove_neighbors("abadedf", 2);
// backtracking
test_remove_neighbors("abcba", 2);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dHlwZW5hbWUgSXQsIGNsYXNzIFByPgpJdCByZW1vdmVfbmVpZ2hib3JzKEl0IGZpcnN0LCBJdCBsYXN0LCBpbnQgblNwYW4sIFByIFByZWQpIHsKICBpZiAoZmlyc3QgPT0gbGFzdCB8fCBuU3BhbiA8PSAwKSByZXR1cm4gbGFzdDsKCiAgSXQgbGFzdEdvb2QgPSBmaXJzdDsKICBJdCBjdXIgPSBmaXJzdDsKICArK2N1cjsKICBmb3IgKDsgY3VyICE9IGxhc3Q7ICsrY3VyKSB7CiAgICBib29sIGZvdW5kID0gZmFsc2U7CiAgICBJdCBiYWNrID0gbGFzdEdvb2Q7CiAgICBmb3IgKGludCBpID0gblNwYW47IGkgPiAwOyAtLWksIC0tYmFjaykgewogICAgICBpZiAoUHJlZCgqYmFjaywgKmN1cikpIHsKICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgbGFzdEdvb2QgPSBiYWNrOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGlmIChiYWNrID09IGZpcnN0KSBicmVhazsKICAgIH0KCiAgICBpZiAoIWZvdW5kKSB7CiAgICAgICsrbGFzdEdvb2Q7CiAgICAgICpsYXN0R29vZCA9IHN0ZDo6bW92ZSgqY3VyKTsKICAgIH0KICB9CiAgKytsYXN0R29vZDsKICByZXR1cm4gbGFzdEdvb2Q7Cn0KCnZvaWQgdGVzdF9yZW1vdmVfbmVpZ2hib3JzKGNvbnN0IHN0cmluZyYgaW4sIGludCBuU3BhbikgewogIHZlY3RvcjxjaGFyPiB2KGluLmJlZ2luKCksIGluLmVuZCgpKTsKICB2ZWN0b3I8Y2hhcj46Oml0ZXJhdG9yIHRyYXNoID0KICAgICAgcmVtb3ZlX25laWdoYm9ycyh2LmJlZ2luKCksIHYuZW5kKCksIG5TcGFuLCBlcXVhbF90bzxjaGFyPigpKTsKICBzdHJpbmcgb3V0KHYuYmVnaW4oKSwgdHJhc2gpOwogIGNvdXQgPDwgIkluOiAiIDw8IGluIDw8ICIgc3BhbjogIiA8PCBuU3BhbiA8PCAiIG91dDogIiA8PCBvdXQgPDwgZW5kbDsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogIC8vIE5vIG9wczoKICB0ZXN0X3JlbW92ZV9uZWlnaGJvcnMoImFiYWIiLCAxKTsKICB0ZXN0X3JlbW92ZV9uZWlnaGJvcnMoImFiY2FiYyIsIDIpOwogIC8vIHVuaXF1ZQogIHRlc3RfcmVtb3ZlX25laWdoYm9ycygiYWFiYmFhYWJiYiIsIDEpOwogIC8vIHNpbXBsZQogIHRlc3RfcmVtb3ZlX25laWdoYm9ycygiYWJhZGVkZiIsIDIpOwogIC8vIGJhY2t0cmFja2luZwogIHRlc3RfcmVtb3ZlX25laWdoYm9ycygiYWJjYmEiLCAyKTsKICByZXR1cm4gMDsKfQo=