#include <iostream>
#include <cstdint>
#include <cstring>
using namespace std;
namespace prism
{
struct token_t
{
uint64_t m_value;
token_t();
token_t(const token_t& rhs);
token_t(const char *str);
std::string to_string() const;
token_t& from_string(const char *str);
token_t& operator=(const char *str) { return from_string(str); }
};
struct _ulldiv_t
{
uint64_t quot;
uint64_t rem;
_ulldiv_t() : quot(0ull), rem(0ull) { }
};
_ulldiv_t _div(uint64_t num, uint64_t divider)
{
_ulldiv_t result;
result.rem = num%divider;
result.quot = (uint64_t)num / divider;
return result;
}
uint64_t powull(uint64_t base, uint32_t num)
{
uint64_t result = 1;
for (uint32_t i = 0; num > i; ++i)
result = result * base;
return result;
}
const uint32_t g_num_letters = 38;
const char g_letters[g_num_letters] =
{ '\0', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_'
};
uint32_t get_id_char(char letter)
{
for (uint32_t i = 0; i < g_num_letters; ++i)
if (letter == g_letters[i])
return i;
return 0;
}
std::string token_to_string(prism::token_t token)
{
char output[16] = { 0 };
_ulldiv_t result;
int i = 0;
for (; token.m_value != 0; ++i)
{
result = _div(token.m_value, g_num_letters);
token.m_value = result.quot;
output[i] = g_letters[result.rem];
}
output[i] = '\0';
return std::string(output);
}
token_t string_to_token(const char *str)
{
token_t result;
uint32_t len = strlen(str);
for (uint32_t i = 0; i < len; ++i)
result.m_value += powull(g_num_letters, i) * get_id_char(tolower(str[i]));
return result;
}
token_t::token_t() : m_value(0) {}
token_t::token_t(const token_t& rhs) : m_value(rhs.m_value) {}
token_t::token_t(const char *str) { m_value = string_to_token(str).m_value; }
std::string token_t::to_string() const { return token_to_string((*this)); }
token_t& token_t::from_string(const char *str) { m_value = string_to_token(str).m_value; return (*this); }
}
int main()
{
std::string line;
while(std::getline(std::cin, line))
{
prism::token_t token(line.c_str());
cout << line << " = " << token.m_value << " " << token.to_string() << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPGNzdHJpbmc+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpuYW1lc3BhY2UgcHJpc20KewoJc3RydWN0IHRva2VuX3QKCXsKCQl1aW50NjRfdCBtX3ZhbHVlOwoKCQl0b2tlbl90KCk7CgkJdG9rZW5fdChjb25zdCB0b2tlbl90JiByaHMpOwoJCXRva2VuX3QoY29uc3QgY2hhciAqc3RyKTsKCgkJc3RkOjpzdHJpbmcgdG9fc3RyaW5nKCkgY29uc3Q7CgkJdG9rZW5fdCYgZnJvbV9zdHJpbmcoY29uc3QgY2hhciAqc3RyKTsKCQl0b2tlbl90JiBvcGVyYXRvcj0oY29uc3QgY2hhciAqc3RyKSB7IHJldHVybiBmcm9tX3N0cmluZyhzdHIpOyB9Cgl9OwoKCXN0cnVjdCBfdWxsZGl2X3QKCXsKCQl1aW50NjRfdCBxdW90OwoJCXVpbnQ2NF90IHJlbTsKCgkJX3VsbGRpdl90KCkgOiBxdW90KDB1bGwpLCByZW0oMHVsbCkgeyB9Cgl9OwoKCV91bGxkaXZfdCBfZGl2KHVpbnQ2NF90IG51bSwgdWludDY0X3QgZGl2aWRlcikKCXsKCQlfdWxsZGl2X3QgcmVzdWx0OwoJCXJlc3VsdC5yZW0gPSBudW0lZGl2aWRlcjsKCQlyZXN1bHQucXVvdCA9ICh1aW50NjRfdCludW0gLyBkaXZpZGVyOwoJCXJldHVybiByZXN1bHQ7Cgl9CgoJdWludDY0X3QgcG93dWxsKHVpbnQ2NF90IGJhc2UsIHVpbnQzMl90IG51bSkKCXsKCQl1aW50NjRfdCByZXN1bHQgPSAxOwoJCWZvciAodWludDMyX3QgaSA9IDA7IG51bSA+IGk7ICsraSkKCQkJcmVzdWx0ID0gcmVzdWx0ICogYmFzZTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoKCWNvbnN0IHVpbnQzMl90IGdfbnVtX2xldHRlcnMgPSAzODsKCWNvbnN0IGNoYXIgZ19sZXR0ZXJzW2dfbnVtX2xldHRlcnNdID0gCgl7ICAnXDAnLCAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsICdhJywgJ2InLAoJCSdjJywgJ2QnLCAnZScsICdmJywgJ2cnLCAnaCcsICdpJywgJ2onLCAnaycsICdsJywgJ20nLCAnbicsICdvJywKCQkncCcsICdxJywgJ3InLCAncycsICd0JywgJ3UnLCAndicsICd3JywgJ3gnLCAneScsICd6JywgJ18nIAoJfTsKCgl1aW50MzJfdCBnZXRfaWRfY2hhcihjaGFyIGxldHRlcikKCXsKCQlmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwgZ19udW1fbGV0dGVyczsgKytpKQoJCQlpZiAobGV0dGVyID09IGdfbGV0dGVyc1tpXSkKCQkJCXJldHVybiBpOwoJCXJldHVybiAwOwoJfQoKCXN0ZDo6c3RyaW5nIHRva2VuX3RvX3N0cmluZyhwcmlzbTo6dG9rZW5fdCB0b2tlbikKCXsKCQljaGFyIG91dHB1dFsxNl0gPSB7IDAgfTsKCQlfdWxsZGl2X3QgcmVzdWx0OwoJCWludCBpID0gMDsKCQlmb3IgKDsgdG9rZW4ubV92YWx1ZSAhPSAwOyArK2kpCgkJewoJCQlyZXN1bHQgPSBfZGl2KHRva2VuLm1fdmFsdWUsIGdfbnVtX2xldHRlcnMpOwoJCQl0b2tlbi5tX3ZhbHVlID0gcmVzdWx0LnF1b3Q7CgkJCW91dHB1dFtpXSA9IGdfbGV0dGVyc1tyZXN1bHQucmVtXTsKCQl9CgkJb3V0cHV0W2ldID0gJ1wwJzsKCQlyZXR1cm4gc3RkOjpzdHJpbmcob3V0cHV0KTsKCX0KCgl0b2tlbl90IHN0cmluZ190b190b2tlbihjb25zdCBjaGFyICpzdHIpCgl7CgkJdG9rZW5fdCByZXN1bHQ7CgkJdWludDMyX3QgbGVuID0gc3RybGVuKHN0cik7CgkJZm9yICh1aW50MzJfdCBpID0gMDsgaSA8IGxlbjsgKytpKQoJCQlyZXN1bHQubV92YWx1ZSArPSBwb3d1bGwoZ19udW1fbGV0dGVycywgaSkgKiBnZXRfaWRfY2hhcih0b2xvd2VyKHN0cltpXSkpOwoJCXJldHVybiByZXN1bHQ7Cgl9CgoJdG9rZW5fdDo6dG9rZW5fdCgpIDogbV92YWx1ZSgwKSB7fQoJdG9rZW5fdDo6dG9rZW5fdChjb25zdCB0b2tlbl90JiByaHMpIDogbV92YWx1ZShyaHMubV92YWx1ZSkge30KCXRva2VuX3Q6OnRva2VuX3QoY29uc3QgY2hhciAqc3RyKSB7IG1fdmFsdWUgPSBzdHJpbmdfdG9fdG9rZW4oc3RyKS5tX3ZhbHVlOyB9CglzdGQ6OnN0cmluZyB0b2tlbl90Ojp0b19zdHJpbmcoKSBjb25zdCB7IHJldHVybiB0b2tlbl90b19zdHJpbmcoKCp0aGlzKSk7IH0KCXRva2VuX3QmIHRva2VuX3Q6OmZyb21fc3RyaW5nKGNvbnN0IGNoYXIgKnN0cikgeyBtX3ZhbHVlID0gc3RyaW5nX3RvX3Rva2VuKHN0cikubV92YWx1ZTsgcmV0dXJuICgqdGhpcyk7IH0KfQoKaW50IG1haW4oKSAKewoJc3RkOjpzdHJpbmcgbGluZTsKCXdoaWxlKHN0ZDo6Z2V0bGluZShzdGQ6OmNpbiwgbGluZSkpCgl7CgkJcHJpc206OnRva2VuX3QgdG9rZW4obGluZS5jX3N0cigpKTsKCQljb3V0IDw8IGxpbmUgPDwgIiA9ICIgPDwgdG9rZW4ubV92YWx1ZSA8PCAiICIgPDwgdG9rZW4udG9fc3RyaW5nKCkgPDwgZW5kbDsKCX0KCXJldHVybiAwOwp9