#include <iostream>
#include <algorithm>
#include <vector>
#include <cctype>
using namespace std;
#define UNDEF 1000000000
int target;
vector<pair<char, int> > ops;
// Apply the inverse of ops[j] to the value i.
int invOp(int i, int j) {
switch (ops[j - 1].first) {
case '+': return i - ops[j - 1].second;
case '-': return i + ops[j - 1].second;
case '*':
if (i % ops[j - 1].second == 0) {
return i / ops[j - 1].second;
} else {
return UNDEF;
}
case '/': return i * ops[j - 1].second;
default: throw "Yikes!";
}
}
// _m[0][i][j] == 2 => can compute i using some subset of the first j ops
// _m[0][i][j] == 1 => can't compute i using some subset of the first j ops
// _m[0][i][j] == 0 => don't know yet
// _m[1][i][j] == 2 => can compute -i using some subset of the first j ops
// _m[1][i][j] == 1 => can't compute -i using some subset of the first j ops
// _m[1][i][j] == 0 => don't know yet
vector<vector<unsigned char> > _m[2];
bool _isKnown(int i, int j) {
bool neg = (i < 0);
int ai = (1 - 2 * neg) * i;
return ai < _m[neg].size() && j < _m[neg][ai].size() && _m[neg][ai][j] != 0;
}
// Get the answer as a bool from _m[][][]. Assumes _isKnown(i, j) == true.
bool _gm(int i, int j) {
bool neg = (i < 0);
int ai = (1 - 2 * neg) * i;
return static_cast<bool>(_m[neg][ai][j] - 1);
}
// Set the answer in _m[][][], stretching the vector(s) if necessary.
void _sm(int i, int j, bool x) {
bool neg = (i < 0);
int ai = (1 - 2 * neg) * i;
// We may need to grow the vector(s)
if (ai >= _m[neg].size()) {
_m[neg].resize(ai + 1); // New values init to 0 ("don't know")
}
if (j >= _m[neg][ai].size()) {
_m[neg][ai].resize(j + 1); // New values init to 0 ("don't know")
}
_m[neg][ai][j] = static_cast<int>(x) + 1;
}
// Can we compute i using some subset of the first j ops?
bool canReach(int i, int j) {
if (i == 0) {
return true;
}
if (j == 0) {
return false;
}
if (!_isKnown(i, j)) {
// Compute the new value
int invResult = invOp(i, j);
_sm(i, j, canReach(i, j - 1) || (invResult != UNDEF && canReach(invResult, j - 1)));
}
return _gm(i, j);
}
int main(int argc, char **argv) {
// target = atoi(argv[1]);
// for (int i = 2; i < argc; ++i) {
// ops.push_back(make_pair(argv[i][0], atoi(argv[i] + 1)));
// }
cin >> target;
string s;
while (cin >> s) {
ops.push_back(make_pair(s[0], atoi(s.c_str() + 1)));
}
// Multiply all values that appear as the operand of a division
int d = 1;
for (int i = 0; i < ops.size(); ++i) {
if (ops[i].first == '/') {
d *= abs(ops[i].second);
}
}
cout << "Target is " << target << ". " << ops.size() << " operations to try.\n";
// Adjust all input values accordingly
target *= d;
for (int i = 0; i < ops.size(); ++i) {
if (ops[i].first == '+' || ops[i].first == '-') {
ops[i].second *= d;
}
}
// Look for the target. We can stop looking when d == target, since
// then applying no operations gives 0.
int nearest;
for (int i = 0; i < target; ++i) {
if (canReach(target + i, ops.size())) {
nearest = target + i;
break;
}
if (canReach(target - i, ops.size())) {
nearest = target - i;
break;
}
}
cout << "Nearest value that we can reach is " << (static_cast<double>(nearest) / d) << ".\n";
return 0;
}