I don't know how active these boards are, but either way...
Well I give up. I've tried submitting three consecutively easier to figure out versions of this program and time and again your computer gives me "Wrong Answer" as a result. Have no idea why, but hey, maybe someone here can figure that out?
My code is below, should be easy to copy/paste it into a file and build with g++. Here yah go:
Code: Select all
#include <exception>
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <memory>
#include <utility>
#include <fstream>
#define LCN_TOP 0
#define LCN_UP_LEFT 1
#define LCN_UP_RIGHT 2
#define LCN_MID 3
#define LCN_LOW_LEFT 4
#define LCN_LOW_RIGHT 5
#define LCN_BOTTOM 6
/* Everything here's function should be relatively obvious. I hope
there's no need to explain this stuff... */
class DigException : public std::exception
{
virtual const char* what() const throw()
{
return "DigException";
}
};
class Digit
{
bool locations[7];
/* 0 - TOP
1 - UPPER LEFT
2 - UPPER RIGHT
3 - MIDDLE
4 - LOWER LEFT
5 - LOWER RIGHT
6 - BOTTOM */
public:
Digit (const bool top, const bool ul, const bool ur,
const bool mid, const bool ll, const bool lr, const bool bot) throw()
{
locations[0] = top;
locations[1] = ul;
locations[2] = ur;
locations[3] = mid;
locations[4] = ll;
locations[5] = lr;
locations[6] = bot;
}
bool isSectionOn(const int sec) const throw()
{
if (sec < 0 || sec > 6)
{
std::cout << "Bad Request made to isSectionOn\nPlease Debug Application." << std::endl;
return false;
}
else return locations[sec];
}
};
class One : public Digit
{
public:
One () : Digit(false, false, true, false, false, true, false)
{
}
};
class Two : public Digit
{
public:
Two () : Digit(true, false, true, true, true, false, true)
{
}
};
class Three : public Digit
{
public:
Three () : Digit(true, false, true, true, false, true, true)
{
}
};
class Four : public Digit
{
public:
Four () : Digit(false, true, true, true, false, true, false)
{
}
};
class Five : public Digit
{
public:
Five () : Digit(true, true, false, true, false, true, true)
{
}
};
class Six : public Digit
{
public:
Six () : Digit(true, true, false, true, true, true, true)
{
}
};
class Seven : public Digit
{
public:
Seven () : Digit(true, false, true, false, false, true, false)
{
}
};
class Eight : public Digit
{
public:
Eight () : Digit(true, true, true, true, true, true, true)
{
}
};
class Nine : public Digit
{
public:
Nine () : Digit(true, true, true, true, false, true, true)
{
}
};
class Zero : public Digit
{
public:
Zero () : Digit(true, true, true, false, true, true, true)
{
}
};
class NumberFactory
{
public:
Digit* makeDigit(int dig) throw(std::bad_alloc)
{
switch (dig)
{
case 0:
return new Zero();
case 1:
return new One();
case 2:
return new Two();
case 3:
return new Three();
case 4:
return new Four();
case 5:
return new Five();
case 6:
return new Six();
case 7:
return new Seven();
case 8:
return new Eight();
case 9:
return new Nine();
default:
return NULL;
}
}
};
class Parser
{
std::string tempstring;
///////////////////////////////////////////////////////////////////////////////
//
// This function parses each vertical facing row, making sure that all the
// line breaks are parsed properly and there are sufficient rows. This does the
// "|" characters, as opposed to the "-" characters.
//
//=============================================================================
void verticalParser(bool* barray, int arraySize, int digitSize) throw(std::bad_alloc)
//=============================================================================
{
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for (int iii = 0; iii < digitSize; ++iii)
{
for (int jjj = 0; jjj < arraySize; ++jjj)
{
if (barray[jjj] == true)
{
tempstring.append("|");
}
else
{
tempstring.append(" ");
}
if (jjj % 2 == 0)
{
tempstring.append(digitSize, ' ');
}
else
{
if (jjj != arraySize - 1)
{
tempstring.append(" ");
}
}
}
tempstring.append("\n");
}
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::bad_alloc&)
{
std::cout << "Sent by horizontalParser..." << std::endl;
throw;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// This function parses each horizontally facing row in the LCD Numbers (all the
// rows made up of "-" characters, rather than "|" characters).
//
//=============================================================================
void horizontalParser(bool* barray, int arraySize, int digitSize) throw(std::bad_alloc)
//=============================================================================
{
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tempstring.append(" ");
for (int iii = 0; iii < arraySize; ++iii)
{
if (barray[iii] == true)
{
tempstring.append(digitSize, '-');
}
else
{
tempstring.append(digitSize, ' ');
}
if (iii != arraySize - 1)
{
tempstring.append(" ");
}
}
tempstring.append("\n");
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::bad_alloc&)
{
std::cout << "Sent by verticalParser..." << std::endl;
throw;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// This function just deletes the allocated memory from the Digit*s so that
// the auto_ptr vector can die in peace.
//
//=============================================================================
void clearVector(std::auto_ptr< std::vector< Digit* > > clrVec) throw(std::out_of_range)
//=============================================================================
{
for (int iii = clrVec->size() - 1; iii >= 0; --iii)
{
delete clrVec->at(iii);
}
}
public:
///////////////////////////////////////////////////////////////////////////////
//
// This function is the main organizer of the application. It takes on the
// responsibility of creating each string. It will only parse one command
// pair at a time.
//
//=============================================================================
std::auto_ptr< std::string > parse(std::auto_ptr< std::vector< Digit* > > mainVec, int size) throw()
//=============================================================================
{
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
std::auto_ptr< std::string > totalstring(new std::string);
bool* barray = new bool[mainVec->size() * 2];
for (int iii = 0; iii < 3; ++iii)
{
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for (unsigned int jjj = 0; jjj < mainVec->size(); ++jjj)
{
if (iii == 0)
{
barray[jjj] = (mainVec->at(jjj))->isSectionOn(LCN_TOP);
}
else if (iii == 1)
{
barray[jjj] = (mainVec->at(jjj))->isSectionOn(LCN_MID);
}
else
{
barray[jjj] = (mainVec->at(jjj))->isSectionOn(LCN_BOTTOM);
}
}
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::out_of_range&)
{
std::cout << "mainVec called out_of_range on first for loop in Parser::parse" << std::endl;
throw;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
horizontalParser(barray, mainVec->size(), size);
totalstring->append(tempstring);
tempstring.clear();
if (iii < 2)
{
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for (unsigned int jjj = 0; jjj < mainVec->size(); ++jjj)
{
/* I chose to use "jjj * 2" followed by "(jjj * 2) + 1" because of where
jjj starts, and the nature of the array I was using. I would need every
even number to be the left side of the Digit we were printing, and every
odd number to be the right side of the Digit. In order to do this, I had
to employ some funky mathematics. EXAMPLE: if jjj = 3: 3 * 2 = 6, so
location 6 would be LCN_XXX_LEFT and location 7 would be LCN_XXX_RIGHT,
then on the following iteration jjj would equal 4, and thus 4 * 2 = 8,
and so LCN_XXX_LEFT is 8 and LCN_XXX_RIGHT is 9, etc. */
if (iii == 0)
{
barray[jjj * 2] = (mainVec->at(jjj))->isSectionOn(LCN_UP_LEFT);
barray[(jjj * 2) + 1] = (mainVec->at(jjj))->isSectionOn(LCN_UP_RIGHT);
}
else
{
barray[jjj * 2] = (mainVec->at(jjj))->isSectionOn(LCN_LOW_LEFT);
barray[(jjj * 2) + 1] = (mainVec->at(jjj))->isSectionOn(LCN_LOW_RIGHT);
}
}
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::out_of_range&)
{
std::cout << "mainVec called out_of_range on second for loop in Parser::parse" << std::endl;
throw;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
verticalParser(barray, mainVec->size() * 2, size);
totalstring->append(tempstring);
tempstring.clear();
}
}
delete[] barray;
clearVector(mainVec);
return totalstring;
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::exception& e)
{
std::cout << "Caught exception in parse function: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
}
};
class Starter
{
protected:
std::vector< int > numberSet;
NumberFactory numFact;
Parser prs;
int size;
std::string progName;
void failInput() throw()
{
std::cout << "Please use proper command-line input.\nExample: " << progName << " 3 142\n"
"Produces three numbers size 3." << std::endl;
}
void setProgName(const char* fiName)
{
int lastSlash = 0;
for (int iii = 0; fiName[iii] != '\0'; ++iii)
{
if (fiName[iii] == '\\' || fiName[iii] == '/')
{
lastSlash = iii + 1;
}
}
progName.assign(&fiName[lastSlash]);
}
bool checkUserInput(const char* arg1, const char* arg2)
{
if (*arg1 == '0' && *arg2 == '0')
return true;
if (atoi(arg1) == 0 || (atoi(arg2) == 0 && *arg2 != '0'))
{
failInput();
return false;
}
if (atoi(arg1) < 1 || atoi(arg1) > 9)
{
std::cout << "Please use a size from 1 to 9, no other sizes are permitted.\n"
"Example: " << progName << " 3 142\n"
"Produces three numbers size 3." << std::endl;
return false;
}
return true;
}
int getLength(char* arg) throw()
{
int retval = 0;
for (int iii = 0; arg[iii] != '\0'; ++iii)
{
++retval;
}
return retval;
}
public:
Starter(int argc, char** argv) throw()
{
setProgName(argv[0]);
if (argc == 3 && checkUserInput(argv[1], argv[2]))
{
}
else
{
exit(EXIT_SUCCESS);
}
size = atoi(argv[1]);
int anum = getLength(argv[2]);
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for (int iii = 0; iii < anum; ++iii)
{
char* temp = new char(argv[2][iii]);
numberSet.push_back(atoi( (const char*) temp) );
delete temp;
}
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::bad_alloc&)
{
std::cout << "Exception thrown by Starter::Starter: bad_alloc" << std::endl;
exit(EXIT_FAILURE);
}
}
Starter() throw() {};
virtual ~Starter() throw() {};
char analyzeNumber(int anum)
{
if (anum < 0)
{
return 'n';
}
else if (anum > 9)
{
return 'l';
}
else
{
return 'p';
}
}
virtual void run() throw(std::bad_alloc)
{
std::auto_ptr< std::vector< Digit* > > digVect(new std::vector< Digit* >);
bool retry = false;
for (unsigned int iii = 0; iii < numberSet.size(); ++iii)
{
if (retry) --iii;
Digit* temp = numFact.makeDigit(numberSet.at(iii));
if (temp == NULL)
{
if (analyzeNumber(numberSet.at(iii)) == 'l')
{
// This shouldn't have happened, but something's going on to my input.
if (numberSet.at(iii + 1) == numberSet.at(iii) % 10)
{
numberSet.at(iii) = numberSet.at(iii) / 10;
}
else
{
std::vector<int>::iterator it = numberSet.begin() + iii;
numberSet.insert(it, numberSet.at(iii) % 10);
numberSet.at(iii) = numberSet.at(iii) / 10;
}
}
else if (analyzeNumber(numberSet.at(iii)) == 'n')
{
// Why the **** is it negative?
numberSet.at(iii) = abs(numberSet.at(iii));
}
retry = true;
continue;
}
digVect->push_back(numFact.makeDigit(numberSet.at(iii)));
}
std::auto_ptr< std::string > theString = prs.parse(digVect, size);
std::cout << *theString << std::endl;
}
};
class ComplexStarter : public Starter
{
bool fromFile;
std::streambuf *blackup;
std::ifstream *froFile;
std::vector< std::pair< char*, char* >* > commandSet;
void getUserInput()
{
std::string input;
char* test1, *test2;
while (true)
{
getline(std::cin, input);
if (input.at(1) != ' ')
{
failInput();
std::cout << "Or input '0 0' to print and exit." << std::endl;
continue;
}
test1 = new char(input.at(0));
test2 = new char[input.size() - 2];
for (unsigned int iii = 2; iii < input.size(); ++iii)
{
test2[iii - 2] = input.at(iii);
}
if (checkUserInput(test1, test2))
{
if (*test1 == '0' && *test2 == '0' && test2[1] == '\0')
{
delete test1;
delete[] test2;
break;
}
else
{
commandSet.push_back(new std::pair< char*, char* > (test1, test2));
}
}
else
{
failInput();
std::cout << "Or input '0 0' to print and exit." << std::endl;
delete test1;
delete[] test2;
test1 = NULL;
test2 = NULL;
continue;
}
}
}
public:
ComplexStarter(const char* prNm) : Starter(), fromFile(false)
{
setProgName(prNm);
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
try
{
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
getUserInput();
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
}
catch (std::exception& e)
{
std::cout << "Error occured during user input: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
}
ComplexStarter(const char* prNm, const char* fileLoad) : Starter(), fromFile(false)
{
setProgName(prNm);
froFile = new std::ifstream(fileLoad, std::ifstream::in);
if (*froFile != NULL)
{
fromFile = true;
blackup = std::cin.rdbuf();
std::cin.rdbuf(froFile->rdbuf());
getUserInput();
}
else
{
std::cout << "File not found or is corrupt." << std::endl;
exit(EXIT_SUCCESS);
}
}
~ComplexStarter() throw()
{
for (unsigned int iii = 0; iii < commandSet.size(); ++iii)
{
delete commandSet.at(iii)->first;
delete[] commandSet.at(iii)->second;
delete commandSet.at(iii);
}
if (fromFile)
{
froFile->close();
delete froFile;
std::cin.rdbuf(blackup);
}
}
void run() throw(std::bad_alloc)
{
int len = 0;
for (unsigned int iii = 0; iii < commandSet.size(); ++iii)
{
numberSet.clear();
len = getLength(commandSet.at(iii)->second);
for (int jjj = 0; jjj < len; ++jjj)
{
char* temp = new char(commandSet.at(iii)->second[jjj]);
numberSet.push_back(atoi( (const char*) temp) );
delete temp;
}
size = atoi(commandSet.at(iii)->first);
Starter::run();
}
}
};
int main(int argc, char* argv[])
{
Starter* start;
if (argc == 1)
{
start = new ComplexStarter(argv[0]);
}
else if (argc == 2)
{
start = new ComplexStarter(argv[0], argv[1]);
}
else
{
start = new Starter(argc, argv);
}
start->run();
delete start;
return 0;
}
I wish this submitter worked, I'd have fun with this stuff...