Login:
Username:
Password:
Remember login

Create new account


Submission ID: 211071
Problem ID: 110104
Code:

#include <vector>
#include <string>
#include <map>
#include <iostream>

class InputProcessor
{
public:

	//  break type
	enum BREAK_CONDITION
	{
		BREAK_EOF = 0,
		BREAK_ENTER,
		BREAK_ZERO,

		BREAK_TOTAL
	};

	// »ý¼ºÀÚ / ¼Ò¸êÀÚ
	InputProcessor(BREAK_CONDITION _eBreak)	{ eBreakCondition_ = _eBreak; }
	virtual ~InputProcessor()				{}

	// ÀÎÅÍÆäÀ̽º
	virtual void							process()				= 0;
	virtual int								getDataIndexCount()			= 0;
	virtual const std::vector<int>*			getDigits(int _nIndex)	= 0;
	virtual const std::vector<std::string>*	getChars(int _nIndex)	= 0;

	// Test¸¦ À§ÇÑ ÇÔ¼ö
	virtual void							addTestInput(const char* pSzTestData) = 0;

protected:

	// break condition
	BREAK_CONDITION		eBreakCondition_;

	// data manipulator
	// ·ÎÄà ÅÛÇø´ Ŭ·¡½º´Â ¸í½ÃÀû Ưȭ°¡ Çã¿ëµÇÁö ¾Ê°í ºÎºÐƯȭ¸¸ Çã¿ëµÈ´Ù. ±×¿¡ ´ëÇÑ ²Ç¼ö
	// cf. ºñÁÖ¾ó½ºÆ©µð¿À È®ÀåÀ¸·Î ·ÎÄÃŬ·¡½ºÀÇ ¸í½ÃÀû Ưȭ°¡ Çã¿ëµÈ´Ù.
	template< typename T, typename PartialSpecialization = bool >
	struct SDataManipulator{};
	template< typename PartialSpecialization >
	struct SDataManipulator< int, PartialSpecialization >
	{
		static int convertData(char* _pSzData){ return atoi( _pSzData ); }
		static const int getZero(){return 0;}
		static const std::vector<int>* getDigits(std::vector< std::vector<int>* >& _refVecData, int _nIndex)
		{
			return _refVecData[ _nIndex ];
		}
		static const std::vector<std::string>*	getChars(std::vector< std::vector<int>* >& _refVecData, int _nIndex)
		{
			return 0;
		}
	};
	template< typename PartialSpecialization >
	struct SDataManipulator< std::string, PartialSpecialization >
	{
		static char* convertData(char* _pSzData){ return _pSzData; }
		static const char* getZero(){ return "0";}
		static const std::vector<int>* getDigits(std::vector< std::vector<std::string>* >& _refVecData, int _nIndex)
		{
			return 0;
		}
		static const std::vector<std::string>*	getChars(std::vector< std::vector<std::string>* >& _refVecData, int _nIndex)
		{
			return _refVecData[ _nIndex ];
		}
	};

	// multiline data
	template< typename T >
	struct SInputData
	{
		// data container
		std::vector< std::vector<T>* > aVecVecData;

		// get data
		void processData(BREAK_CONDITION _eBreak, const char* _pSzManualData )
		{
			char buf[512];
			bool bLoop = true;
			while( bLoop )
			{
				if( _pSzManualData == 0 )
				{
					// ¶óÀÎÀ¸·Î ÀԷ¹ޱâ
					if( gets( buf ) == 0 )
						return;
				}
				else
				{
					strcpy(buf, _pSzManualData);
					bLoop = false;
				}

				std::vector<T>*  pVector = new std::vector<T>;
				char* pSzEach = strtok(buf, " ");
				while (pSzEach!= 0)
				{
					pVector->push_back( SDataManipulator<T>::convertData( pSzEach ) );
					pSzEach = strtok(0, " ");
				}

				// Zero Break
				if( _eBreak == BREAK_ZERO && pVector->size() == 2 )
				{
					if( (*pVector)[0] == SDataManipulator<T>::getZero() && (*pVector)[1] == SDataManipulator<T>::getZero() )
					{
						delete pVector;
						return;
					}
				}

				aVecVecData.push_back( pVector );

				// Enter Break
				if( _eBreak == BREAK_ENTER )
					return;
			}
		}

		// clear data
		void clearData()
		{
			int nSize = (int)aVecVecData.size();
			for( int i = 0; i < nSize; ++i)
			{
				delete aVecVecData[i];
			}
			aVecVecData.clear();
		}
	};

};

template< typename T >
class InputProcessorImpl : public InputProcessor
{
public:
	InputProcessorImpl(BREAK_CONDITION _eBreak) : InputProcessor(_eBreak) {}
	virtual ~InputProcessorImpl(){ aData_.clearData(); }

	virtual void process()
	{
		if( aData_.aVecVecData.empty() == false )
				aData_.clearData();
		aData_.processData( eBreakCondition_, 0);
	}

	virtual const std::vector<int>* getDigits(int _nIndex)
	{
		if( _nIndex < 0 || aData_.aVecVecData.empty() || _nIndex >= getDataIndexCount() )
			return 0;

		return InputProcessor::SDataManipulator<T>::getDigits(aData_.aVecVecData, _nIndex);
	}

	virtual const std::vector<std::string>*	getChars(int _nIndex)
	{
		if( _nIndex < 0 || aData_.aVecVecData.empty() || _nIndex >= getDataIndexCount() )
			return 0;

		return InputProcessor::SDataManipulator<T>::getChars(aData_.aVecVecData, _nIndex);
	}

	virtual int getDataIndexCount()
	{
		return (int)aData_.aVecVecData.size();
	}

	virtual void addTestInput(const char* pSzTestData)
	{
		aData_.processData(InputProcessor::BREAK_EOF, pSzTestData );
	}

private:
	InputProcessor::SInputData< T > aData_;
};


//////////////////////////////////////////////////////////////////////
//
// Code Dojo Interface
//
//////////////////////////////////////////////////////////////////////

class CodeDojo
{
public:
	CodeDojo()			{}
	virtual ~CodeDojo()	{}

	virtual void solveTheProblem( InputProcessor* _pInput ) = 0;
};

class CodeDojoLCDDisplay : public CodeDojo
{
private:
	struct DISPLAY_DIGIT
	{
		DISPLAY_DIGIT(int _nNumber)
		{
			switch( _nNumber )
			{
			case 0:
				{
					m_bTOPHori = true;
					m_bMiddleHori = false;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = true;
					m_bSecondVerticalRight = true;
				}
				break;
			case 1:
				{
					m_bTOPHori = false;
					m_bMiddleHori = false;
					m_bBottomHori = false;

					m_bFirstVerticalLeft = false;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			case 2:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = false;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = true;
					m_bSecondVerticalRight = false;
				}
				break;
			case 3:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = false;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			case 4:
				{
					m_bTOPHori = false;
					m_bMiddleHori = true;
					m_bBottomHori = false;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			case 5:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = false;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			case 6:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = false;

					m_bSecondVerticalLeft = true;
					m_bSecondVerticalRight = true;
				}
				break;
			case 7:
				{
					m_bTOPHori = true;
					m_bMiddleHori = false;
					m_bBottomHori = false;

					m_bFirstVerticalLeft = false;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			case 8:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = true;
					m_bSecondVerticalRight = true;
				}
				break;
			case 9:
				{
					m_bTOPHori = true;
					m_bMiddleHori = true;
					m_bBottomHori = true;

					m_bFirstVerticalLeft = true;
					m_bFirstVerticalRight = true;

					m_bSecondVerticalLeft = false;
					m_bSecondVerticalRight = true;
				}
				break;
			}
		}

		bool m_bTOPHori;
		bool m_bMiddleHori;
		bool m_bBottomHori;

		bool m_bFirstVerticalLeft;
		bool m_bFirstVerticalRight;

		bool m_bSecondVerticalLeft;
		bool m_bSecondVerticalRight;
	};

public:
	virtual void solveTheProblem( InputProcessor* _pInput )
	{
		_pInput->process();

		int nLineCount = _pInput->getDataIndexCount();
		for(int i = 0; i < nLineCount; ++i)
		{
			// check input
			const std::vector<int>* pInputDigits = _pInput->getDigits(i);
			if(pInputDigits->size() != 2)
			{
				printf("Invalid Input");
				return;
			}

			// element for display : size, number, dispaly letter.
			int nSizeToDisplay = pInputDigits->at(0);
			int nNumberToDisplay = pInputDigits->at(1);
			std::vector<DISPLAY_DIGIT> displayDigits;

			// check input
			if( (nNumberToDisplay > 99999999 || nNumberToDisplay < 0) ||
				(nSizeToDisplay > 10 || nSizeToDisplay < 1) )
			{
				printf("Invalid Input");
				return;
			}

			// build dispaly-digits from input number
			buildDisplayDigits_(nNumberToDisplay, displayDigits);

			// display
			display_(nSizeToDisplay, displayDigits);

			printf("\n\n");
		}
	}

private:
	void buildDisplayDigits_(int _nNumber, std::vector<DISPLAY_DIGIT>& _vecDispalyDigits )
	{
		char szBuf[10];
		sprintf( szBuf, "%d", _nNumber );
		std::string strNumber = szBuf;

		int nCount = (int)strNumber.size();
		for(int i = 0; i < nCount; ++i)
		{
			_vecDispalyDigits.push_back( DISPLAY_DIGIT(strNumber[i] - '0') );
		}
	}

	void display_(int _nSize, const std::vector<DISPLAY_DIGIT>& _vecDispalyDigits)
	{
		int nDisplayLoopCount = calcDisplayLoopCount_(_nSize);
		for( int i = 0; i < nDisplayLoopCount; ++i )
		{
			DISPLAY_POS ePos = calcDisplayPos_(_nSize, nDisplayLoopCount, i);
			char* pBuff = makeDipslayBuffFromPos_(ePos, _nSize, _vecDispalyDigits);
			printf(pBuff);
			delete pBuff;

			if( i < nDisplayLoopCount-1 )
				printf("\n");
		}
	}

	enum DISPLAY_POS
	{
		E_TOP = 0,
		E_TOP_MIDDLE,
		E_MIDDLE,
		E_MIDDLE_BOTTOM,
		E_BOTTOM
	};

	int calcDisplayLoopCount_(int _nDisplaySize)
	{
		// óÀ½ - Áß°£ - ³¡ ÀÌ 3°³ µé¾î°¡°í
		// °¡¿îµ¥ µÎ°³ µé¾î°¡´Â°ÍÀº ÀÔ·ÂµÈ »çÀÌÁîÀÇ µÎ¹è
		//    --   --        -- 
		// |    |    | |  | |   
		// |    |    | |  | |   
		//    --   --   --   -- 
		// | |       |    |    |
		// | |       |    |    |
		//    --   --        -- 
		return _nDisplaySize*2 + 3;
	}

	DISPLAY_POS	calcDisplayPos_(int _nDisplaySize, int _nDisplayLoopCount, int _nCurrnetIndex)
	{
		DISPLAY_POS ePos;
		if( _nCurrnetIndex == 0 )
		{
			ePos = E_TOP;
		}
		else if( _nCurrnetIndex == _nDisplaySize + 1 )
		{
			ePos = E_MIDDLE;
		}
		else if( _nCurrnetIndex == _nDisplayLoopCount - 1 )
		{
			ePos = E_BOTTOM;
		}
		else if( _nCurrnetIndex < _nDisplaySize + 1 )
		{
			ePos = E_TOP_MIDDLE;
		}
		else
		{
			ePos = E_MIDDLE_BOTTOM;
		}

		return ePos;
	}

	char* makeDipslayBuffFromPos_(DISPLAY_POS _ePos, int _nDisplaySize, const std::vector<DISPLAY_DIGIT>& _vecDispalyDigits)
	{
		int nCount = (int)_vecDispalyDigits.size();

		int nBufSize = nCount * (_nDisplaySize + 2) + (nCount - 1);
		char* pSzBuf;
		pSzBuf = new char[nBufSize + 1];
		memset(pSzBuf, ' ', nBufSize);
		pSzBuf[nBufSize] = '\0';

		for(int i = 0; i < nCount; ++i)
		{
			const DISPLAY_DIGIT& digit = _vecDispalyDigits[i];
			int nStartIndex = i * (_nDisplaySize + 2) + i;
			switch( _ePos )
			{
			case E_TOP:
				{
					if(digit.m_bTOPHori)
					{
						nStartIndex += 1;
						for( int j = 0; j < _nDisplaySize; ++j )
						{
							pSzBuf[j+nStartIndex] = '-';
						}
					}
				}
				break;
			case E_TOP_MIDDLE:
				{
					if(digit.m_bFirstVerticalLeft)
					{
						pSzBuf[nStartIndex] = '|';
					}

					if(digit.m_bFirstVerticalRight)
					{
						pSzBuf[nStartIndex + _nDisplaySize + 1] = '|';
					}
				}
				break;
			case E_MIDDLE:
				{
					if(digit.m_bMiddleHori)
					{
						nStartIndex += 1;
						for( int j = 0; j < _nDisplaySize; ++j )
						{
							pSzBuf[j+nStartIndex] = '-';
						}
					}
				}
				break;
			case E_MIDDLE_BOTTOM:
				{
					if(digit.m_bSecondVerticalLeft)
					{
						pSzBuf[nStartIndex] = '|';
					}

					if(digit.m_bSecondVerticalRight)
					{
						pSzBuf[nStartIndex + _nDisplaySize + 1] = '|';
					}
				}
				break;
			case E_BOTTOM:
				{
					if(digit.m_bBottomHori)
					{
						nStartIndex += 1;
						for( int j = 0; j < _nDisplaySize; ++j )
						{
							pSzBuf[j+nStartIndex] = '-';
						}
					}
				}
				break;
			}
		}

		return pSzBuf;
	}
};

int main()
{
	InputProcessor* pInput = new InputProcessorImpl<int>(InputProcessor::BREAK_ZERO);
	CodeDojo* pCodeDojo = new CodeDojoLCDDisplay;

	// ¹®Á¦ Ç®±â
	pCodeDojo->solveTheProblem( pInput );

	delete pCodeDojo;
	delete pInput;

	return 0;
}