#include <cassert>
#include <cstring>
#include <iostream>
#include <iterator>
#include <string>

namespace
{
  template<class It, class C>
  It write_rle_run(It d_first, C prev, uintmax_t count) {
    if (count > 1) {
      *d_first++ = '{';
      for (char d : std::to_string(count))
        *d_first++ = d;
      *d_first++ = ',';
      *d_first++ = prev;
      *d_first++ = '}';
    }
    else {
      assert(count == 1);
      *d_first++ = prev;
    }
    return d_first;
  }

  /// aaaab4cpp -> {4,a}b4c{2,p}
  template<class InputIt, class OutputIt>
  OutputIt rle_encode(InputIt first, InputIt last, OutputIt d_first)
  {
    if (first == last) // empty
      return d_first;

    auto prev = *first++;  // previous char
    uintmax_t count = 1;
    for ( ; first != last; ++first, ++count) {
      if (prev != *first) { // ended run of the same consecutive elements
        d_first = write_rle_run(d_first, prev, count); // write the run
        prev = *first; // start new run
        count = 0;
      }
    }
    return write_rle_run(d_first, prev, count);
  }
}

int main()
{
  const char a[] = "aaaa345pp";
  char output[sizeof a];
  rle_encode(std::begin(a), std::end(a), output);
  std::cout << output << '\n';


  std::string text = "aaaa345pp";
  rle_encode(std::begin(text), std::end(text), std::ostream_iterator<char>(std::cout));
  std::cout << '\n';

  std::string s;
  rle_encode(std::begin(text), std::end(text), std::back_inserter(s));
  std::cout << s << std::endl;

  std::istream_iterator<char> chars{std::cin}, eof;
  rle_encode(chars, eof, std::ostream_iterator<char>(std::cout));
  std::cout << '\n';
}
