#include <iostream>
#include <algorithm>
#include <array>
#include <streambuf>
#include <cassert>
namespace GrosserWerner {
template< unsigned N, unsigned Reserve = 0 >
class BufferN : public std::streambuf
{
public:
BufferN( std::streambuf* src )
: src_( src )
, p0_( 0 )
{
setg( buf_, buf_, buf_ );
}
protected:
virtual int_type underflow() override
{
assert( gptr() != 0 ); // garantiert der Konstruktor
assert( gptr() == egptr() ); // ...sollte der Aufrufer garantieren
const int_type m = src_->sbumpc();
if( traits_type::eq_int_type( m, traits_type::eof() ) )
return traits_type::eof();
if( egptr() == end() )
{
traits_type::move( buf_, buf_+(Reserve+1), N-1 );
setg( buf_, buf_+(N-1), buf_+N );
p0_ += Reserve+1;
}
else
{
setg( buf_, egptr(), egptr()+1 );
}
*gptr() = traits_type::to_char_type( m );
return m;
}
virtual pos_type seekoff( off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
{
if( which != std::ios_base::in ) // nur input-Zeiger setzen erlaubt
return pos_type( off_type(-1) );
off_type local_off; // zeigt in den lokalen 'buf_'
switch( way )
{
case std::ios_base::beg:
local_off = off_type( off - p0_ );
break;
case std::ios_base::cur:
local_off = off + (gptr() - eback());
break;
case std::ios_base::end: // not implemented
default:
return pos_type( off_type(-1) );
}
if( local_off < 0 || local_off > off_type(egptr() - eback()) )
return pos_type( off_type(-1) ); // Fehler: local_off zeigt außerhalb der pending sequence
setg( buf_, buf_+local_off, egptr() );
return p0_ + local_off;
}
virtual pos_type seekpos( pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override
{
return seekoff( off_type(sp - (p0_ + off_type(gptr() - eback()))), std::ios_base::cur, which );
}
private:
const char_type* end() const { return buf_ + sizeof(buf_)/sizeof(*buf_); }
std::streambuf* src_;
char_type buf_[N+Reserve];
pos_type p0_;
};
void parse1(std::istream& in, std::ostream& out)
{
out << "Format 1\n";
std::istreambuf_iterator<char> i(in), j;
std::copy(i, j, std::ostreambuf_iterator<char>(out));
}
void parse2(std::istream& in, std::ostream& out)
{
out << "Format 2\n";
std::istreambuf_iterator<char> i(in), j;
std::copy(i, j, std::ostreambuf_iterator<char>(out));
}
void parse(std::istream& in, std::ostream& out)
{
BufferN< 64, 1 > sb( in.rdbuf() );
// ^- don't override the first character
in.rdbuf( &sb );
std::istreambuf_iterator< char > it( in );
int magic = 17;
for (int i = 0; i < 64; ++i)
magic = 13*magic + *it++;
in.seekg( 0, std::ios_base::beg );
if ( magic%2 )
parse1( in, out );
else
parse2( in, out );
}
}
namespace werni {
void parse1(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end,
std::ostream& out, std::array<char, 64> const& arr)
{
out << "Format 1\n";
std::ostreambuf_iterator<char> o(out);
std::copy(arr.begin(), arr.end(), o);
std::copy(++it, end, o);
}
void parse2(std::istreambuf_iterator<char> it, std::istreambuf_iterator<char> end,
std::ostream& out, std::array<char, 64> const& arr)
{
out << "Format 2\n";
std::ostreambuf_iterator<char> o(out);
std::copy(arr.begin(), arr.end(), o);
std::copy(++it, end, o);
}
void parse(std::istream& in, std::ostream& out)
{
std::istreambuf_iterator<char> it(in), end;
std::array<char, 64> save;
std::copy_n(it, 64, save.begin());
int magic = 17;
for (int i=0; i<64; ++i)
magic = 13*magic + save[i];
if (magic%2)
parse1(it, end, out, save);
else
parse2(in, end, out, save);
}
}
int main(int argc, char *argv[])
{
std::ios_base::sync_with_stdio(false);
if (argc != 2)
std::cout << "usage: " << argv[0] << " [werni|Werner]";
else if (std::string("werni") == argv[1])
werni::parse(std::cin, std::cout);
else
GrosserWerner::parse(std::cin, std::cout);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8YXJyYXk+CiNpbmNsdWRlIDxzdHJlYW1idWY+CiNpbmNsdWRlIDxjYXNzZXJ0PgoKbmFtZXNwYWNlIEdyb3NzZXJXZXJuZXIgewogIHRlbXBsYXRlPCB1bnNpZ25lZCBOLCB1bnNpZ25lZCBSZXNlcnZlID0gMCA+CiAgY2xhc3MgQnVmZmVyTiA6IHB1YmxpYyBzdGQ6OnN0cmVhbWJ1ZgogIHsKICBwdWJsaWM6CiAgICBCdWZmZXJOKCBzdGQ6OnN0cmVhbWJ1Ziogc3JjICkKICAgICAgOiBzcmNfKCBzcmMgKQogICAgICAsIHAwXyggMCApCiAgICB7CiAgICAgIHNldGcoIGJ1Zl8sIGJ1Zl8sIGJ1Zl8gKTsKICAgIH0KICBwcm90ZWN0ZWQ6CiAgICB2aXJ0dWFsIGludF90eXBlIHVuZGVyZmxvdygpIG92ZXJyaWRlCiAgICB7CiAgICAgIGFzc2VydCggZ3B0cigpICE9IDAgKTsgLy8gZ2FyYW50aWVydCBkZXIgS29uc3RydWt0b3IKICAgICAgYXNzZXJ0KCBncHRyKCkgPT0gZWdwdHIoKSApOyAvLyAuLi5zb2xsdGUgZGVyIEF1ZnJ1ZmVyIGdhcmFudGllcmVuCiAgICAgIGNvbnN0IGludF90eXBlIG0gPSBzcmNfLT5zYnVtcGMoKTsKICAgICAgaWYoIHRyYWl0c190eXBlOjplcV9pbnRfdHlwZSggbSwgdHJhaXRzX3R5cGU6OmVvZigpICkgKQogICAgICAgIHJldHVybiB0cmFpdHNfdHlwZTo6ZW9mKCk7CiAgICAgIGlmKCBlZ3B0cigpID09IGVuZCgpICkKICAgICAgICB7CiAgICAgICAgICB0cmFpdHNfdHlwZTo6bW92ZSggYnVmXywgYnVmXysoUmVzZXJ2ZSsxKSwgTi0xICk7CiAgICAgICAgICBzZXRnKCBidWZfLCBidWZfKyhOLTEpLCBidWZfK04gKTsKICAgICAgICAgIHAwXyArPSBSZXNlcnZlKzE7CiAgICAgICAgfQogICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgc2V0ZyggYnVmXywgZWdwdHIoKSwgZWdwdHIoKSsxICk7CiAgICAgICAgfQogICAgICAqZ3B0cigpID0gdHJhaXRzX3R5cGU6OnRvX2NoYXJfdHlwZSggbSApOwogICAgICByZXR1cm4gbTsKICAgIH0KIAogICAgdmlydHVhbCBwb3NfdHlwZSBzZWVrb2ZmKCBvZmZfdHlwZSBvZmYsIHN0ZDo6aW9zX2Jhc2U6OnNlZWtkaXIgd2F5LCBzdGQ6Omlvc19iYXNlOjpvcGVubW9kZSB3aGljaCA9IHN0ZDo6aW9zX2Jhc2U6OmluIHwgc3RkOjppb3NfYmFzZTo6b3V0KSBvdmVycmlkZQogICAgewogICAgICBpZiggd2hpY2ggIT0gc3RkOjppb3NfYmFzZTo6aW4gKSAvLyBudXIgaW5wdXQtWmVpZ2VyIHNldHplbiBlcmxhdWJ0CiAgICAgICAgcmV0dXJuIHBvc190eXBlKCBvZmZfdHlwZSgtMSkgKTsKICAgICAgb2ZmX3R5cGUgbG9jYWxfb2ZmOyAvLyB6ZWlndCBpbiBkZW4gbG9rYWxlbiAnYnVmXycKICAgICAgc3dpdGNoKCB3YXkgKQogICAgICAgIHsKICAgICAgICBjYXNlIHN0ZDo6aW9zX2Jhc2U6OmJlZzoKICAgICAgICAgIGxvY2FsX29mZiA9IG9mZl90eXBlKCBvZmYgLSBwMF8gKTsKICAgICAgICAgIGJyZWFrOwogCiAgICAgICAgY2FzZSBzdGQ6Omlvc19iYXNlOjpjdXI6CiAgICAgICAgICBsb2NhbF9vZmYgPSBvZmYgKyAoZ3B0cigpIC0gZWJhY2soKSk7CiAgICAgICAgICBicmVhazsKIAogICAgICAgIGNhc2Ugc3RkOjppb3NfYmFzZTo6ZW5kOiAvLyBub3QgaW1wbGVtZW50ZWQKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIHBvc190eXBlKCBvZmZfdHlwZSgtMSkgKTsKICAgICAgICB9CiAgICAgIGlmKCBsb2NhbF9vZmYgPCAwIHx8IGxvY2FsX29mZiA+IG9mZl90eXBlKGVncHRyKCkgLSBlYmFjaygpKSApCiAgICAgICAgcmV0dXJuIHBvc190eXBlKCBvZmZfdHlwZSgtMSkgKTsgLy8gRmVobGVyOiBsb2NhbF9vZmYgemVpZ3QgYXXDn2VyaGFsYiBkZXIgcGVuZGluZyBzZXF1ZW5jZQogICAgICBzZXRnKCBidWZfLCBidWZfK2xvY2FsX29mZiwgZWdwdHIoKSApOwogICAgICByZXR1cm4gcDBfICsgbG9jYWxfb2ZmOwogICAgfQogICAgdmlydHVhbCBwb3NfdHlwZSBzZWVrcG9zKCBwb3NfdHlwZSBzcCwgc3RkOjppb3NfYmFzZTo6b3Blbm1vZGUgd2hpY2ggPSBzdGQ6Omlvc19iYXNlOjppbiB8IHN0ZDo6aW9zX2Jhc2U6Om91dCApIG92ZXJyaWRlCiAgICB7CiAgICAgIHJldHVybiBzZWVrb2ZmKCBvZmZfdHlwZShzcCAtIChwMF8gKyBvZmZfdHlwZShncHRyKCkgLSBlYmFjaygpKSkpLCBzdGQ6Omlvc19iYXNlOjpjdXIsIHdoaWNoICk7CiAgICB9CiAKICBwcml2YXRlOgogICAgY29uc3QgY2hhcl90eXBlKiBlbmQoKSBjb25zdCB7IHJldHVybiBidWZfICsgc2l6ZW9mKGJ1Zl8pL3NpemVvZigqYnVmXyk7IH0KICAgIHN0ZDo6c3RyZWFtYnVmKiBzcmNfOwogICAgY2hhcl90eXBlIGJ1Zl9bTitSZXNlcnZlXTsKICAgIHBvc190eXBlIHAwXzsKICB9OwoKICB2b2lkIHBhcnNlMShzdGQ6OmlzdHJlYW0mIGluLCBzdGQ6Om9zdHJlYW0mIG91dCkKICB7CiAgICBvdXQgPDwgIkZvcm1hdCAxXG4iOwogICAgc3RkOjppc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+IGkoaW4pLCBqOwogICAgc3RkOjpjb3B5KGksIGosIHN0ZDo6b3N0cmVhbWJ1Zl9pdGVyYXRvcjxjaGFyPihvdXQpKTsKICB9CgogIHZvaWQgcGFyc2UyKHN0ZDo6aXN0cmVhbSYgaW4sIHN0ZDo6b3N0cmVhbSYgb3V0KQogIHsKICAgIG91dCA8PCAiRm9ybWF0IDJcbiI7CiAgICBzdGQ6OmlzdHJlYW1idWZfaXRlcmF0b3I8Y2hhcj4gaShpbiksIGo7CiAgICBzdGQ6OmNvcHkoaSwgaiwgc3RkOjpvc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+KG91dCkpOwogIH0KCiAgdm9pZCBwYXJzZShzdGQ6OmlzdHJlYW0mIGluLCBzdGQ6Om9zdHJlYW0mIG91dCkKICB7CiAgICBCdWZmZXJOPCA2NCwgMSA+IHNiKCBpbi5yZGJ1ZigpICk7CiAgICAvLyAgICAgICAgICAgXi0gZG9uJ3Qgb3ZlcnJpZGUgdGhlIGZpcnN0IGNoYXJhY3RlcgogICAgaW4ucmRidWYoICZzYiApOwogICAgc3RkOjppc3RyZWFtYnVmX2l0ZXJhdG9yPCBjaGFyID4gaXQoIGluICk7CiAgICBpbnQgbWFnaWMgPSAxNzsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjQ7ICsraSkKICAgICAgbWFnaWMgPSAxMyptYWdpYyArICppdCsrOwogICAgaW4uc2Vla2coIDAsIHN0ZDo6aW9zX2Jhc2U6OmJlZyApOwogICAgaWYgKCBtYWdpYyUyICkKICAgICAgcGFyc2UxKCBpbiwgb3V0ICk7CiAgICBlbHNlCiAgICAgIHBhcnNlMiggaW4sIG91dCApOwogIH0KfQoKbmFtZXNwYWNlIHdlcm5pIHsKICB2b2lkIHBhcnNlMShzdGQ6OmlzdHJlYW1idWZfaXRlcmF0b3I8Y2hhcj4gaXQsIHN0ZDo6aXN0cmVhbWJ1Zl9pdGVyYXRvcjxjaGFyPiBlbmQsCiAgICAgICAgICAgICAgc3RkOjpvc3RyZWFtJiBvdXQsIHN0ZDo6YXJyYXk8Y2hhciwgNjQ+IGNvbnN0JiBhcnIpCiAgewogICAgb3V0IDw8ICJGb3JtYXQgMVxuIjsKICAgIHN0ZDo6b3N0cmVhbWJ1Zl9pdGVyYXRvcjxjaGFyPiBvKG91dCk7CiAgICBzdGQ6OmNvcHkoYXJyLmJlZ2luKCksIGFyci5lbmQoKSwgbyk7CiAgICBzdGQ6OmNvcHkoKytpdCwgZW5kLCBvKTsKICB9CgogIHZvaWQgcGFyc2UyKHN0ZDo6aXN0cmVhbWJ1Zl9pdGVyYXRvcjxjaGFyPiBpdCwgc3RkOjppc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+IGVuZCwKICAgICAgICAgICAgICBzdGQ6Om9zdHJlYW0mIG91dCwgc3RkOjphcnJheTxjaGFyLCA2ND4gY29uc3QmIGFycikKICB7CiAgICBvdXQgPDwgIkZvcm1hdCAyXG4iOwogICAgc3RkOjpvc3RyZWFtYnVmX2l0ZXJhdG9yPGNoYXI+IG8ob3V0KTsKICAgIHN0ZDo6Y29weShhcnIuYmVnaW4oKSwgYXJyLmVuZCgpLCBvKTsKICAgIHN0ZDo6Y29weSgrK2l0LCBlbmQsIG8pOwogIH0KCiAgdm9pZCBwYXJzZShzdGQ6OmlzdHJlYW0mIGluLCBzdGQ6Om9zdHJlYW0mIG91dCkKICB7CiAgICBzdGQ6OmlzdHJlYW1idWZfaXRlcmF0b3I8Y2hhcj4gaXQoaW4pLCBlbmQ7CiAgICBzdGQ6OmFycmF5PGNoYXIsIDY0PiBzYXZlOwogICAgc3RkOjpjb3B5X24oaXQsIDY0LCBzYXZlLmJlZ2luKCkpOwogICAgaW50IG1hZ2ljID0gMTc7CiAgICBmb3IgKGludCBpPTA7IGk8NjQ7ICsraSkKICAgICAgbWFnaWMgPSAxMyptYWdpYyArIHNhdmVbaV07CiAgICBpZiAobWFnaWMlMikKICAgICAgcGFyc2UxKGl0LCBlbmQsIG91dCwgc2F2ZSk7CiAgICBlbHNlCiAgICAgIHBhcnNlMihpbiwgZW5kLCBvdXQsIHNhdmUpOwogIH0KfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogIHN0ZDo6aW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgaWYgKGFyZ2MgIT0gMikKICAgIHN0ZDo6Y291dCA8PCAidXNhZ2U6ICIgPDwgYXJndlswXSA8PCAiIFt3ZXJuaXxXZXJuZXJdIjsKICBlbHNlIGlmIChzdGQ6OnN0cmluZygid2VybmkiKSA9PSBhcmd2WzFdKQogICAgd2Vybmk6OnBhcnNlKHN0ZDo6Y2luLCBzdGQ6OmNvdXQpOwogIGVsc2UKICAgIEdyb3NzZXJXZXJuZXI6OnBhcnNlKHN0ZDo6Y2luLCBzdGQ6OmNvdXQpOwp9