#include <algorithm>
#include <bitset>
#include <iostream>
#include <iterator>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>
class HexPic {
protected:
std::string hex_to_string(unsigned int value) {
return std::bitset<8>(value).to_string();
}
template <typename Iter>
void binary_to_stream(Iter begin, Iter end, std::ostream& stream) const {
char on = display_on_;
char off = display_off_;
if (inverted_) std::swap(on, off);
std::string temp = std::accumulate(begin, end, std::string(""),
[&](std::string& res, char ch) {
return res += std::string(static_cast<int>(magnification_), (ch == '0' ? off : on));
});
for (int i = 0; i < magnification_; ++i) {
stream << temp << '\n';
}
}
public:
enum RotateDirection { top, right, bottom, left };
friend HexPic::RotateDirection& operator++(HexPic::RotateDirection& r) {
if (static_cast<int>(r) == 3) return r = HexPic::RotateDirection(0);
return r = HexPic::RotateDirection((static_cast<int>(r) + 1));
}
friend HexPic::RotateDirection& operator--(HexPic::RotateDirection& r) {
if (static_cast<int>(r) == 0) return r = HexPic::RotateDirection(3);
return r = HexPic::RotateDirection((static_cast<int>(r) - 1));
}
explicit HexPic() : inverted_{false}, magnification_{1.0},
direction_{RotateDirection::top},
display_on_{'X'}, display_off_{'.'} {}
void add_hexrow(const unsigned int hexval) {
bitmap_.push_back(hex_to_string(hexval));
}
void draw(std::ostream& stream) const {
switch (direction_) {
case top: {
for (const auto& row : bitmap_) {
binary_to_stream(row.begin(), row.end(), stream);
}
break;
}
case right: {
std::vector<std::string> columns(bitmap_[0].size());
std::for_each(bitmap_.rbegin(),
bitmap_.rend(),
[&](const std::string& row) {
std::transform(row.begin(),
row.end(),
columns.begin(),
columns.begin(),
[](char ch, std::string str) {
return str + ch;
});
});
for (const auto& col : columns) {
binary_to_stream(col.begin(), col.end(), stream);
}
break;
}
case bottom: {
std::for_each(bitmap_.rbegin(),
bitmap_.rend(),
[&](const std::string& row) {
binary_to_stream(row.rbegin(), row.rend(), stream);
});
break;
}
case left: {
std::vector<std::string> columns(bitmap_[0].size());
std::for_each(bitmap_.begin(),
bitmap_.end(),
[&](const std::string& row) {
std::transform(row.rbegin(),
row.rend(),
columns.begin(),
columns.begin(),
[](char ch, std::string str) {
return str + ch;
});
});
for (const auto& col : columns) {
binary_to_stream(col.begin(), col.end(), stream);
}
break;
}
}
stream << '\n';
}
void rotate_cw() {
++direction_;
}
void rotate_ccw() {
--direction_;
}
void zoom(double multiplier) {
magnification_ = std::max(1.0, magnification_ * multiplier);
}
void invert_display_bits() {
inverted_ = !inverted_;
}
friend std::istream& operator>>(std::istream& stream, HexPic& pic) {
HexPic temp;
std::string input;
std::getline(stream, input);
std::istringstream iss(input);
unsigned int value;
while (iss >> std::hex >> value) {
temp.add_hexrow(value);
}
pic = temp;
return stream;
}
private:
std::vector<std::string> bitmap_;
RotateDirection direction_;
char display_off_;
char display_on_;
bool inverted_;
double magnification_;
};
int main() {
std::vector<HexPic> pics((std::istream_iterator<HexPic>(std::cin)),
std::istream_iterator<HexPic>());
for (auto& pic : pics) {
pic.draw(std::cout);
pic.zoom(2);
pic.rotate_cw();
pic.zoom(2);
pic.invert_display_bits();
pic.zoom(0.5);
pic.draw(std::cout);
}
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGJpdHNldD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHZlY3Rvcj4KCmNsYXNzIEhleFBpYyB7CnByb3RlY3RlZDoKICAgIHN0ZDo6c3RyaW5nIGhleF90b19zdHJpbmcodW5zaWduZWQgaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN0ZDo6Yml0c2V0PDg+KHZhbHVlKS50b19zdHJpbmcoKTsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KICAgIHZvaWQgYmluYXJ5X3RvX3N0cmVhbShJdGVyIGJlZ2luLCBJdGVyIGVuZCwgc3RkOjpvc3RyZWFtJiBzdHJlYW0pIGNvbnN0IHsKICAgICAgICBjaGFyIG9uID0gZGlzcGxheV9vbl87CiAgICAgICAgY2hhciBvZmYgPSBkaXNwbGF5X29mZl87CgogICAgICAgIGlmIChpbnZlcnRlZF8pIHN0ZDo6c3dhcChvbiwgb2ZmKTsKCiAgICAgICAgc3RkOjpzdHJpbmcgdGVtcCA9IHN0ZDo6YWNjdW11bGF0ZShiZWdpbiwgZW5kLCBzdGQ6OnN0cmluZygiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJl0oc3RkOjpzdHJpbmcmIHJlcywgY2hhciBjaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMgKz0gc3RkOjpzdHJpbmcoc3RhdGljX2Nhc3Q8aW50PihtYWduaWZpY2F0aW9uXyksIChjaCA9PSAnMCcgPyBvZmYgOiBvbikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFnbmlmaWNhdGlvbl87ICsraSkgewogICAgICAgICAgICBzdHJlYW0gPDwgdGVtcCA8PCAnXG4nOwogICAgICAgIH0KICAgIH0KCgpwdWJsaWM6CiAgICBlbnVtIFJvdGF0ZURpcmVjdGlvbiB7IHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdCB9OwoKICAgIGZyaWVuZCBIZXhQaWM6OlJvdGF0ZURpcmVjdGlvbiYgb3BlcmF0b3IrKyhIZXhQaWM6OlJvdGF0ZURpcmVjdGlvbiYgcikgewogICAgICAgIGlmIChzdGF0aWNfY2FzdDxpbnQ+KHIpID09IDMpIHJldHVybiByID0gSGV4UGljOjpSb3RhdGVEaXJlY3Rpb24oMCk7CiAgICAgICAgcmV0dXJuIHIgPSBIZXhQaWM6OlJvdGF0ZURpcmVjdGlvbigoc3RhdGljX2Nhc3Q8aW50PihyKSArIDEpKTsKICAgIH0KCiAgICBmcmllbmQgSGV4UGljOjpSb3RhdGVEaXJlY3Rpb24mIG9wZXJhdG9yLS0oSGV4UGljOjpSb3RhdGVEaXJlY3Rpb24mIHIpIHsKICAgICAgICBpZiAoc3RhdGljX2Nhc3Q8aW50PihyKSA9PSAwKSByZXR1cm4gciA9IEhleFBpYzo6Um90YXRlRGlyZWN0aW9uKDMpOwogICAgICAgIHJldHVybiByID0gSGV4UGljOjpSb3RhdGVEaXJlY3Rpb24oKHN0YXRpY19jYXN0PGludD4ocikgLSAxKSk7CiAgICB9CgogICAgZXhwbGljaXQgSGV4UGljKCkgOiBpbnZlcnRlZF97ZmFsc2V9LCBtYWduaWZpY2F0aW9uX3sxLjB9LAogICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb25fe1JvdGF0ZURpcmVjdGlvbjo6dG9wfSwKICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheV9vbl97J1gnfSwgZGlzcGxheV9vZmZfeycuJ30ge30KCiAgICB2b2lkIGFkZF9oZXhyb3coY29uc3QgdW5zaWduZWQgaW50IGhleHZhbCkgewogICAgICAgIGJpdG1hcF8ucHVzaF9iYWNrKGhleF90b19zdHJpbmcoaGV4dmFsKSk7CiAgICB9CgogICAgdm9pZCBkcmF3KHN0ZDo6b3N0cmVhbSYgc3RyZWFtKSBjb25zdCB7CiAgICAgICAgc3dpdGNoIChkaXJlY3Rpb25fKSB7CiAgICAgICAgICAgIGNhc2UgdG9wOiB7CiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGF1dG8mIHJvdyA6IGJpdG1hcF8pIHsKICAgICAgICAgICAgICAgICAgICBiaW5hcnlfdG9fc3RyZWFtKHJvdy5iZWdpbigpLCByb3cuZW5kKCksIHN0cmVhbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIHJpZ2h0OiB7CiAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gY29sdW1ucyhiaXRtYXBfWzBdLnNpemUoKSk7CgogICAgICAgICAgICAgICAgc3RkOjpmb3JfZWFjaChiaXRtYXBfLnJiZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRtYXBfLnJlbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdKGNvbnN0IHN0ZDo6c3RyaW5nJiByb3cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dHJhbnNmb3JtKHJvdy5iZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93LmVuZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucy5iZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucy5iZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW10oY2hhciBjaCwgc3RkOjpzdHJpbmcgc3RyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0ciArIGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYXV0byYgY29sIDogY29sdW1ucykgewogICAgICAgICAgICAgICAgICAgIGJpbmFyeV90b19zdHJlYW0oY29sLmJlZ2luKCksIGNvbC5lbmQoKSwgc3RyZWFtKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIGJvdHRvbTogewogICAgICAgICAgICAgICAgc3RkOjpmb3JfZWFjaChiaXRtYXBfLnJiZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRtYXBfLnJlbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdKGNvbnN0IHN0ZDo6c3RyaW5nJiByb3cpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeV90b19zdHJlYW0ocm93LnJiZWdpbigpLCByb3cucmVuZCgpLCBzdHJlYW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgbGVmdDogewogICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IGNvbHVtbnMoYml0bWFwX1swXS5zaXplKCkpOwoKICAgICAgICAgICAgICAgIHN0ZDo6Zm9yX2VhY2goYml0bWFwXy5iZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRtYXBfLmVuZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJl0oY29uc3Qgc3RkOjpzdHJpbmcmIHJvdykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp0cmFuc2Zvcm0ocm93LnJiZWdpbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93LnJlbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnMuYmVnaW4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnMuYmVnaW4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtdKGNoYXIgY2gsIHN0ZDo6c3RyaW5nIHN0cikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIgKyBjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGF1dG8mIGNvbCA6IGNvbHVtbnMpIHsKICAgICAgICAgICAgICAgICAgICBiaW5hcnlfdG9fc3RyZWFtKGNvbC5iZWdpbigpLCBjb2wuZW5kKCksIHN0cmVhbSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHN0cmVhbSA8PCAnXG4nOwogICAgfQoKICAgIHZvaWQgcm90YXRlX2N3KCkgewogICAgICAgICsrZGlyZWN0aW9uXzsKICAgIH0KCiAgICB2b2lkIHJvdGF0ZV9jY3coKSB7CiAgICAgICAgLS1kaXJlY3Rpb25fOwogICAgfQoKICAgIHZvaWQgem9vbShkb3VibGUgbXVsdGlwbGllcikgewogICAgICAgIG1hZ25pZmljYXRpb25fID0gc3RkOjptYXgoMS4wLCBtYWduaWZpY2F0aW9uXyAqIG11bHRpcGxpZXIpOwogICAgfQoKICAgIHZvaWQgaW52ZXJ0X2Rpc3BsYXlfYml0cygpIHsKICAgICAgICBpbnZlcnRlZF8gPSAhaW52ZXJ0ZWRfOwogICAgfQoKICAgIGZyaWVuZCBzdGQ6OmlzdHJlYW0mIG9wZXJhdG9yPj4oc3RkOjppc3RyZWFtJiBzdHJlYW0sIEhleFBpYyYgcGljKSB7CiAgICAgICAgSGV4UGljIHRlbXA7CiAgICAgICAgc3RkOjpzdHJpbmcgaW5wdXQ7CiAgICAgICAgc3RkOjpnZXRsaW5lKHN0cmVhbSwgaW5wdXQpOwogICAgICAgIHN0ZDo6aXN0cmluZ3N0cmVhbSBpc3MoaW5wdXQpOwoKICAgICAgICB1bnNpZ25lZCBpbnQgdmFsdWU7CiAgICAgICAgd2hpbGUgKGlzcyA+PiBzdGQ6OmhleCA+PiB2YWx1ZSkgewogICAgICAgICAgICB0ZW1wLmFkZF9oZXhyb3codmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgcGljID0gdGVtcDsKICAgICAgICByZXR1cm4gc3RyZWFtOwogICAgfQoKcHJpdmF0ZToKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBiaXRtYXBfOwogICAgUm90YXRlRGlyZWN0aW9uIGRpcmVjdGlvbl87CiAgICBjaGFyIGRpc3BsYXlfb2ZmXzsKICAgIGNoYXIgZGlzcGxheV9vbl87CiAgICBib29sIGludmVydGVkXzsKICAgIGRvdWJsZSBtYWduaWZpY2F0aW9uXzsKfTsKCmludCBtYWluKCkgewogICAgc3RkOjp2ZWN0b3I8SGV4UGljPiBwaWNzKChzdGQ6OmlzdHJlYW1faXRlcmF0b3I8SGV4UGljPihzdGQ6OmNpbikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aXN0cmVhbV9pdGVyYXRvcjxIZXhQaWM+KCkpOwoKICAgIGZvciAoYXV0byYgcGljIDogcGljcykgewogICAgICAgIHBpYy5kcmF3KHN0ZDo6Y291dCk7CgogICAgICAgIHBpYy56b29tKDIpOwogICAgICAgIHBpYy5yb3RhdGVfY3coKTsKICAgICAgICBwaWMuem9vbSgyKTsKICAgICAgICBwaWMuaW52ZXJ0X2Rpc3BsYXlfYml0cygpOwogICAgICAgIHBpYy56b29tKDAuNSk7CiAgICAgICAgcGljLmRyYXcoc3RkOjpjb3V0KTsKICAgIH0KfQ==