Created
December 16, 2016 12:42
-
-
Save geekskick/bc0d1d5a43aa6555edb557fbf86f03b6 to your computer and use it in GitHub Desktop.
Apprentice Lab
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Use the numbers 1-9 in that order to find all the ways of getting 100. | |
* You can't miss any of the numbers out and only use + and - operations | |
* No functions or classes allowed either! | |
* | |
* eg | |
* 1+2+3+4+5+6+7+8+9 = 100? Then show | |
* 123+456-789 = 100? Then Show | |
* | |
*/ | |
#include <iostream> | |
#include <vector> | |
using namespace std; | |
/* Each number can either have a plus, a minus or a join to another letter after it | |
* | |
*/ | |
typedef enum { PLUS = 0, MINUS, JOIN, COUNT }operations_t; | |
// Temporary storage | |
typedef struct{ | |
string sEquation; // The string showing the equation | |
long long llResult; // What the equation evaluates to | |
}tempstore_t; | |
int main (void) | |
{ | |
const vector<int> ivNUMBERS = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // The numbers I must use | |
const int iTARGET = 100; // The target result | |
const vector<char> cvOPERATORS = { '+', '-' }; // The order of these must match the enum | |
vector<tempstore_t> vxTempEquations; // as it's a bit like a recursive function this is where my previous calculation is going to go at each stage | |
string strEquation = ""; // As I'm building the equation up it's going to go in here | |
long long llTemporaryResult = 0; // As I perform operations I'm going to store it here. As I'm starting with 1 then I can start here. This might be a really big/little ßnumber, so long long | |
int iNumberOfMatches = 0; // the total number of equations found | |
int iFirst; // starting at -1/+1 | |
int iNum = 0; // Used in the equation algorithm | |
string sNum; // Used in the equation algorithm | |
long long llLastUndone; // Used in the equation algorithm | |
long long llToJoin; // Used in the equation algorithm | |
int idx; // Used in the equation algorithm | |
//--------------------- | |
// INIT THE PREVIOUS CALCULATIONS STORAGE | |
for(int i = 0; i < ivNUMBERS.size(); i += 1) | |
{ | |
//always append but it doesn't really matter where it goes cause it's empty anyway | |
vxTempEquations.push_back(tempstore_t()); | |
vxTempEquations[i].llResult = 0; | |
vxTempEquations[i].sEquation = ""; | |
} | |
/* Do a ternary (3 options) count etc | |
* 0 0 0 0 0 1 0 0 Like this truth table but it'll go on for 8^2 + 1 options (513) and it will be complicated to do | |
* 0 0 0 1 0 1 0 1 so dont do it in one for loop, do it in a for loop for each option - will be 8 for loops nested with 3 | |
* 0 0 0 2 0 1 0 2 iterations on each | |
* 0 0 1 0 0 1 1 0 | |
* 0 0 1 1 0 1 1 1 | |
* 0 0 1 2 0 1 1 2 | |
* 0 0 2 0 0 1 2 0 | |
* 0 0 2 1 0 1 2 1 | |
* 0 0 2 2 0 1 2 2 | |
*/ | |
//------------------------------ DEAL WITH THE 1 ------------------------------------------------- | |
/* | |
* Either -ve or +ve | |
*/ | |
for(int xOp0 = PLUS; xOp0 < JOIN; xOp0 += 1) | |
{ | |
iFirst = xOp0 == PLUS ? 1 : -1; | |
//------------------------------ DEAL WITH THE 2 ------------------------------------------------- | |
for ( int xOp1 = PLUS; xOp1 < COUNT; xOp1 += 1 ) | |
{ | |
// This is the number two, which in the ivNUMBERS vector is the 2nd element along | |
const int iTHIS_OPERATOR = 1; | |
strEquation = to_string(iFirst); | |
llTemporaryResult = iFirst; | |
switch ( xOp1 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is foundß | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + ((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] : ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp1 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp1]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//------------------------------ DEAL WITH 3 -------------------------------------------------- | |
for ( int xOp2 = PLUS; xOp2 < COUNT; xOp2 += 1 ) | |
{ | |
// Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 2; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp2 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is foundß | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + ((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] : ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:cout << "[ERROR]: Defaulting on operator [" << __LINE__ << "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp2 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp2]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 4---------------------------------------------- | |
for ( int xOp3 = PLUS; xOp3 < COUNT; xOp3 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 3; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp3 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = | |
(iNum * 10) + ((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] : ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:cout << "[ERROR]: Defaulting on operator [" << __LINE__ << "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp3 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp3]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 5---------------------------------------------- | |
for ( int xOp4 = PLUS; xOp4 < COUNT; xOp4 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 4; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp4 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = | |
(iNum * 10) + | |
((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] : ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:cout << "[ERROR]: Defaulting on operator [" << __LINE__ << "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp4 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp4]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 6---------------------------------------------- | |
for ( int xOp5 = PLUS; xOp5 < COUNT; xOp5 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 5; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp5 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && | |
idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + | |
((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] : ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:cout << "[ERROR]: Defaulting on operator [" << __LINE__ << "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp5 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp5]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 7---------------------------------------------- | |
for ( int xOp6 = PLUS; xOp6 < COUNT; xOp6 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 6; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp6 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && strEquation.c_str()[idx] != '+' && | |
idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + | |
((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] | |
: ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default: | |
cout << "[ERROR]: Defaulting on operator " << xOp6 << " [" << __LINE__ << "]" | |
<< endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp6 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp6]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 8---------------------------------------------- | |
for ( int xOp7 = PLUS; xOp7 < COUNT; xOp7 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 7; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp7 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
int idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && | |
strEquation.c_str()[idx] != '+' && | |
idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + ((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] | |
: ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default:cout << "[ERROR]: Defaulting on operator [" << __LINE__ << "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp7 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp7]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
//----------------------------------DEAL WITH 9---------------------------------------------- | |
for ( int xOp8 = PLUS; xOp8 < COUNT; xOp8 += 1 ) | |
{ | |
//Local scope means that it takes precedence over the ones before | |
const int iTHIS_OPERATOR = 8; | |
// get the previous string and the result out of the storage | |
strEquation = vxTempEquations[iTHIS_OPERATOR - 1].sEquation; | |
llTemporaryResult = vxTempEquations[iTHIS_OPERATOR - 1].llResult; | |
switch ( xOp8 ) | |
{ | |
case PLUS:llTemporaryResult += ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case MINUS:llTemporaryResult -= ivNUMBERS[iTHIS_OPERATOR]; | |
break; | |
case JOIN: | |
{ | |
/* Since the equation can be 123+45-67 etc we need to find the last used operator from the end and | |
* undo it's work! This is done by iterating from the end to find it. Also, if there is a case where the | |
* number is 1234, for example, we need to ensure that we stop before we roll past the start | |
* | |
* Once the last part is found the number is split into different parts eg: | |
* Previous string: 1+2+3 | |
* expected result: 1+2+34 | |
* Step 1: do the opposite of the last operation, in this case subtract 3 | |
* Step 2: turn the 3 into 34 by 10*lastDigit + nextDigit | |
* NB: This is actually done by using the last VALUE so if it's a minus it's | |
* -3 * 10, then -4 instead of plus. | |
* Step 3: add it to the 'undone' operation | |
*/ | |
// work backwards | |
idx = ( int ) strEquation.length(); | |
// In the case where there are no operators we need to use the result | |
iNum = ( int ) llTemporaryResult; | |
while ( strEquation.c_str()[idx] != '-' && | |
strEquation.c_str()[idx] != '+' && idx >= 0 ) | |
{ | |
idx -= 1; | |
} | |
//At this point either an operator has been found or it's at the start of the equation | |
if ( idx > 0 ) | |
{ | |
// If the operator is found | |
// get the last part out, eg if the equation is 1+2+34+5, sNum will be +5. | |
sNum = strEquation.substr(( unsigned long long ) idx); | |
iNum = stoi(sNum); | |
} | |
// Undo the last thing (STEP 1) | |
llLastUndone = llTemporaryResult - iNum; | |
// STEP 2 | |
llToJoin = (iNum * 10) + ((iNum < 0) ? -ivNUMBERS[iTHIS_OPERATOR] | |
: ivNUMBERS[iTHIS_OPERATOR]); | |
// STEP 3 | |
llTemporaryResult = llLastUndone + llToJoin; | |
} | |
break; | |
default: | |
cout << "[ERROR]: Defaulting on operator" << xOp8 << " [" << __LINE__ | |
<< "]" << endl; | |
break; | |
} | |
/* For displaying to the user we need to handle the case when we don't want to have an operator | |
* not only will it create an out of range exception on the cvOPERATORS vector but it's easy to skip | |
*/ | |
if ( xOp8 != JOIN ) | |
{ | |
strEquation += cvOPERATORS[xOp8]; | |
} | |
strEquation += to_string(ivNUMBERS[iTHIS_OPERATOR]); | |
// store it so that the next number can use it as a tarting point | |
vxTempEquations[iTHIS_OPERATOR].sEquation = strEquation; | |
vxTempEquations[iTHIS_OPERATOR].llResult = llTemporaryResult; | |
// Test for success | |
if ( llTemporaryResult == iTARGET ) | |
{ | |
iNumberOfMatches += 1; | |
cout << "[RESULT " << iNumberOfMatches << "]: " << strEquation << " = " | |
<< iTARGET << endl; | |
} | |
else | |
{ | |
//cout << "[INFO]:" << strEquation << " = " << llTemporaryResult << endl; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
cout << "Done" << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment