#include <iterator>
#include <iostream>
template <typename In, typename Out>
Out t9_transform(In f, In l, Out out)
{
auto magic = [](decltype(*f) i) { return '2' + std::min(7, (i - (i >> 4)) / 3); };
decltype(0+*f) previous = 0;
for(;f!=l;++f) {
if (*f>='a' && *f<='z') {
auto idx = *f - 'a';
auto digit = magic(idx);
if (digit == previous) *out++ = ' ';
previous = digit;
static_assert(std::is_signed<decltype(idx)>::value, "difference type is required to be signed here");
for (; idx>=0 && digit == magic(idx); --idx)
*out++ = digit;
} else
*out++ = '0';
}
return out;
}
std::string t9(std::string const& input)
{
std::string result;
// result.reserve(2*input.size());
t9_transform(begin(input), end(input), std::back_inserter(result));
return result;
}
int main()
{
const std::string input = "abcdefghijklmnopqrstuvwxyz";
auto output = t9_transform(begin(input), end(input), std::ostream_iterator<char>(std::cout));
std::cout << std::endl << t9("hello world!") << std::endl;
// or, how about translating all of stdin to stdout, in streaming mode?
*t9_transform(std::istreambuf_iterator<char>(std::cin), std::istreambuf_iterator<char>(), output) = '\n';
}
I2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSW4sIHR5cGVuYW1lIE91dD4KICAgT3V0IHQ5X3RyYW5zZm9ybShJbiBmLCBJbiBsLCBPdXQgb3V0KQp7CiAgICBhdXRvIG1hZ2ljID0gW10oZGVjbHR5cGUoKmYpIGkpIHsgcmV0dXJuICcyJyArIHN0ZDo6bWluKDcsIChpIC0gKGkgPj4gNCkpIC8gMyk7IH07CiAgICBkZWNsdHlwZSgwKypmKSBwcmV2aW91cyA9IDA7CgogICAgZm9yKDtmIT1sOysrZikgewogICAgICAgIGlmICgqZj49J2EnICYmICpmPD0neicpIHsKICAgICAgICAgICAgYXV0byBpZHggPSAqZiAtICdhJzsKCiAgICAgICAgICAgIGF1dG8gZGlnaXQgPSBtYWdpYyhpZHgpOwogICAgICAgICAgICBpZiAoZGlnaXQgPT0gcHJldmlvdXMpICpvdXQrKyA9ICcgJzsKICAgICAgICAgICAgcHJldmlvdXMgPSBkaWdpdDsKCiAgICAgICAgICAgIHN0YXRpY19hc3NlcnQoc3RkOjppc19zaWduZWQ8ZGVjbHR5cGUoaWR4KT46OnZhbHVlLCAiZGlmZmVyZW5jZSB0eXBlIGlzIHJlcXVpcmVkIHRvIGJlIHNpZ25lZCBoZXJlIik7CiAgICAgICAgICAgIGZvciAoOyBpZHg+PTAgJiYgZGlnaXQgPT0gbWFnaWMoaWR4KTsgLS1pZHgpCiAgICAgICAgICAgICAgICAqb3V0KysgPSBkaWdpdDsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgKm91dCsrID0gJzAnOwogICAgfQoKICAgIHJldHVybiBvdXQ7Cn0KCnN0ZDo6c3RyaW5nIHQ5KHN0ZDo6c3RyaW5nIGNvbnN0JiBpbnB1dCkKewogICAgc3RkOjpzdHJpbmcgcmVzdWx0OwogICAgLy8gcmVzdWx0LnJlc2VydmUoMippbnB1dC5zaXplKCkpOwogICAgdDlfdHJhbnNmb3JtKGJlZ2luKGlucHV0KSwgZW5kKGlucHV0KSwgc3RkOjpiYWNrX2luc2VydGVyKHJlc3VsdCkpOwogICAgcmV0dXJuIHJlc3VsdDsKfQoKaW50IG1haW4oKQp7CiAgICBjb25zdCBzdGQ6OnN0cmluZyBpbnB1dCA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CiAgICBhdXRvIG91dHB1dCA9IHQ5X3RyYW5zZm9ybShiZWdpbihpbnB1dCksIGVuZChpbnB1dCksIHN0ZDo6b3N0cmVhbV9pdGVyYXRvcjxjaGFyPihzdGQ6OmNvdXQpKTsKCiAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8IHQ5KCJoZWxsbyB3b3JsZCEiKSA8PCBzdGQ6OmVuZGw7CgogICAgLy8gb3IsIGhvdyBhYm91dCB0cmFuc2xhdGluZyBhbGwgb2Ygc3RkaW4gdG8gc3Rkb3V0LCBpbiBzdHJlYW1pbmcgbW9kZT8KICAgICp0OV90cmFuc2Zvcm0oc3RkOjppc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+KHN0ZDo6Y2luKSwgc3RkOjppc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+KCksIG91dHB1dCkgPSAnXG4nOwp9Cg==