// // Problem: Golf // Solution by: MORI Shingo // Prune Search // // implement 65min // debug ?h // #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; static const long double EPS = 1e-9; static const long double PI = acos(-1.0); #define REP(i, n) for (ll i = 0; i < (ll)(n); i++) #define FOR(i, s, n) for (ll i = (s); i < (ll)(n); i++) #define FOREQ(i, s, n) for (ll i = (s); i <= (ll)(n); i++) #define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++) #define MEMSET(v, h) memset((v), h, sizeof(v)) const char op[4] = { '+', '-', '*', '/' }; ll calc(char c, ll lhs, ll rhs) { if (c == '+') { return lhs + rhs; } if (c == '-') { return lhs - rhs; } if (c == '*') { return lhs * rhs; } if (c == '/') { return lhs / rhs; } assert(false); return -1; } ll findAns(char c, ll lhs, ll n) { assert(lhs > 0); if (c == '+') { return n - lhs; } if (c == '-') { return lhs - n; } if (c == '*') { ll v = n / lhs; if (lhs * v != n) { return -1; } return v; } if (c == '/') { ll v = lhs / n; if (v == 0 || lhs / v != n) { return -1; } return v; } assert(false); return -1; } ll Len(ll v) { if (v == 0) { return 1; } ll ret = 0; while (v > 0) { v /= 10; ret++; } return ret; } ll MaxValue(ll len) { ll ret = 0; REP(i, len) { ret = ret * 10 + 9; } return ret; } struct Str { string str; ll len; ll v; Str() {;} Str(const char *src, ll v) : v(v) { str = src; len = strlen(src); } bool operator<(const Str &rhs) const { return len < rhs.len; } }; map power; vector sorted_power; char str[100]; ll n; ll ans; char ans_str[100]; const ll MIN_N = 0; //const ll MAX_N = (1LL << 31) - 1; const ll MAX_N = 68719476735LL; //const ll MAX_N = 99999999999LL; int main() { // Init REP(i, sqrt(MAX_N) + 1) { ll v = i; FOR(j, 2, 100) { v *= i; if (v > MAX_N) { break; } snprintf(str, 99, "%lld", v); int l = strlen(str); snprintf(str, 99, "%lld^%lld", i, j); if (l <= (int)strlen(str) || (power.count(v) && power[v].len <= (int)strlen(str))) { continue; } power[v] = Str(str, v); } } FORIT(it, power) { // cout << it->first << " " << it->second.str << endl; sorted_power.push_back(it->second); } sort(sorted_power.begin(), sorted_power.end()); // calc start // FOREQ(n, 0, MAX_N) { while (scanf("%lld", &n) > 0 && n != -1) { ans = Len(n); assert(ans <= 11); assert(0 <= n && n <= MAX_N); snprintf(ans_str, 99, "%lld", n); if (power.count(n)) { ans = min(ans, power[n].len); snprintf(ans_str, 99, "%s", power[n].str.c_str()); } if (ans <= 4) { goto end; } // a^b+-*/c // c-/a^b is not needed FORIT(it, sorted_power) { if (it->len + 2 >= ans) { break; } REP(o, 4) { ll c = findAns(op[o], it->v, n); ll sum = it->len + 1 + Len(c); if (0 < c && c <= MAX_N && sum < ans) { assert(calc(op[o], it->v, c) == n); ans = sum; snprintf(ans_str, 99, "%s%c%lld", it->str.c_str(), op[o], c); } } } // a^b+-*/c^d FORIT(it1, sorted_power) { if (it1->len + 4 >= ans) { break; } FORIT(it2, sorted_power) { ll sum = it1->len + it2->len + 1; if (sum >= ans) { break; } REP(o, 4) { ll v = calc(op[o], it1->v, it2->v); if (v == n && sum < ans) { ans = sum; snprintf(ans_str, 99, "%s%c%s", it1->str.c_str(), op[o], it2->str.c_str()); } } } } // a^b*/c+-*/d // (a^b+-c)+-*/d FORIT(it, sorted_power) { if (it->len + 4 >= ans) { break; } FOR(o1, 0, 4) { ll bracket = o1 < 2 ? 2 : 0; ll restLen = ans - 1 - (it->len + 3 + bracket); ll upper = MaxValue(restLen); FOREQ(c, 1, upper) { ll v = calc(op[o1], it->v, c); if (v <= 0 || MAX_N < v) { continue; } REP(o2, 4) { ll d = findAns(op[o2], v, n); ll sum = it->len + Len(c) + Len(d) + 2 + bracket; if (sum < ans && 0 < d && d < MAX_N && calc(op[o2], v, d) == n) { ans = sum; if (bracket) { snprintf(ans_str, 99, "(%s%c%lld)%c%lld", it->str.c_str(), op[o1], c, op[o2], d); } else { snprintf(ans_str, 99, "%s%c%lld%c%lld", it->str.c_str(), op[o1], c, op[o2], d); } } } } } } // a^b+-*/c^d+-*/e // e+-*/a^b+-*/c^d is not needed FORIT(it1, sorted_power) { if (it1->len + 4 >= ans) { break; } FORIT(it2, sorted_power) { if (it1->len + it2->len + 3 >= ans) { break; } ll restLen = ans - 1 - (it1->len + it2->len + 2); ll upper = MaxValue(restLen); FOREQ(e, 1, upper) { ll sum = it1->len + it2->len + Len(e)+ 2; if (sum >= ans) { break; } REP(o1, 4) { REP(o2, 4) { ll v; if (o1 < 2 && op[o2] >= 2) { ll rhs = calc(op[o2], it2->v, e); if (rhs < 0 || MAX_N < rhs) { continue; } v = calc(op[o1], it1->v, rhs); } else { ll lhs = calc(op[o1], it1->v, it2->v); if (lhs < 0 || MAX_N < lhs) { continue; } v = calc(op[o2], lhs, e); } if (v == n) { ans = sum; snprintf(ans_str, 99, "%s%c%s%c%lld", it1->str.c_str(), op[o1], it2->str.c_str(), op[o2], e); } } } } } } // a^b+-*/e+-*/c^d FORIT(it1, sorted_power) { if (it1->len + 4 >= ans) { break; } FORIT(it2, sorted_power) { if (it1->len + it2->len + 3 >= ans) { break; } ll restLen = ans - 1 - (it1->len + it2->len + 2); ll upper = MaxValue(restLen); FOREQ(e, 1, upper) { ll sum = it1->len + it2->len + Len(e)+ 2; if (sum >= ans) { break; } REP(o1, 4) { REP(o2, 4) { ll v; if (o1 < 2 && op[o2] >= 2) { ll rhs = calc(op[o2], e, it2->v); if (rhs < 0 || MAX_N < rhs) { continue; } v = calc(op[o1], it1->v, rhs); } else { ll lhs = calc(op[o1], it1->v, e); if (lhs < 0 || MAX_N < lhs) { continue; } v = calc(op[o2], lhs, it2->v); } if (v == n) { ans = sum; snprintf(ans_str, 99, "%s%c%lld%c%s", it1->str.c_str(), op[o1], e, op[o2], it2->str.c_str()); } } } } } } // a^b*/c*/d+-*/e FORIT(it, sorted_power) { if (it->len + 6 >= ans) { break; } ll restLen1 = ans - 1 - (it->len + 5); ll upper1 = MaxValue(restLen1); FOR(o1, 2, 4) { FOREQ(c, 1, upper1) { ll v1 = calc(op[o1], it->v, c); ll restLen2 = ans - 1 - (it->len + Len(c) + 4); ll upper2 = MaxValue(restLen2); if (v1 <= 0 || MAX_N <= v1) { continue; } FOR(o2, 2, 4) { FOREQ(d, 1, upper2) { ll v2 = calc(op[o2], v1, d); if (v2 <= 0 || MAX_N <= v2) { continue; } FOR(o3, 0, 4) { ll e = findAns(op[o3], v2, n); ll sum = it->len + Len(c) + Len(d) + Len(e) + 3; if (0 < e && e <= MAX_N && sum < ans && calc(op[o3], v2, e) == n) { ans = sum; snprintf(ans_str, 99, "%s%c%lld%c%lld%c%lld", it->str.c_str(), op[o1], c, op[o2], d, op[o3], e); } } } } } } } end: printf("%lld\n", ans); // printf("%lld %s\n", ans, ans_str); } }