#include <iostream>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
struct Number
{
Number() {m_nSegments = m_nEnds = m_nRightBranches = m_nRightBranches = m_nUpBranches = m_nDownBranches = 0;}
int m_nSegments;
int m_nEnds;
int m_nRightBranches;
int m_nLeftBranches;
int m_nUpBranches;
int m_nDownBranches;
int m_bTopLeftEnd;
int toInt()
{
switch(m_nSegments)
{
case 2:
return 1;
case 3:
return 7;
case 4:
return 4;
case 5:
{
switch(m_nEnds)
{
case 2:
return (m_bTopLeftEnd ? 2 : 5);
case 3:
return 3;
default:
return -1;
}
break;
}
case 6:
{
return m_nEnds ? (m_nRightBranches == 1 ? 9 : 6) : 0;
}
case 7:
return 8;
default:
return -1;
}
}
};
void ParseNumber(vector<vector<char>> & _grid, int _row, int _col, Number & _result)
{
switch (_grid[_row][_col])
{
case ' ':
return;
case '-':
_grid[_row][_col] = ' ';
ParseNumber(_grid, _row, _col+1, _result);
ParseNumber(_grid, _row, _col-1, _result);
return;
case '|':
_grid[_row][_col] = ' ';
ParseNumber(_grid, _row+1, _col, _result);
ParseNumber(_grid, _row-1, _col, _result);
return;
case '+':
{
_grid[_row][_col] = ' ';
bool bEnd = true;
// Right?
if (_col < _grid[_row].size() - 1 && _grid[_row][_col+1] != ' ')
{
bEnd = false;
_result.m_nSegments++;
_result.m_nRightBranches++;
ParseNumber(_grid, _row, _col+1, _result);
}
// Left?
if (_col > 0 && _grid[_row][_col-1] != ' ')
{
bEnd = false;
_result.m_nSegments++;
_result.m_nLeftBranches++;
ParseNumber(_grid, _row, _col-1, _result);
}
// Down?
if (_row < _grid.size() - 1 && _grid[_row+1][_col] != ' ')
{
bEnd = false;
_result.m_nSegments++;
_result.m_nDownBranches++;
ParseNumber(_grid, _row+1, _col, _result);
}
// Up?
if (_row > 0 && _grid[_row-1][_col] != ' ')
{
bEnd = false;
_result.m_nSegments++;
_result.m_nUpBranches++;
ParseNumber(_grid, _row-1, _col, _result);
}
if (bEnd) _result.m_nEnds++;
return;
}
default:
cerr << "Invalid char " << _grid[_row][_col] << endl;
throw _grid[_row][_col];
}
}
vector<int> Parse(vector<vector<char>> _grid)
{
vector<int> ret;
for (int row = 0; row < _grid.size(); row++)
{
for (int col = 0; col < _grid[row].size(); col++)
{
if (_grid[row][col] != ' ')
{
// We found a number! Lets see what it is
bool bTopLeftEnd = (col == _grid[row].size() - 1) || _grid[row][col+1] == ' ' || _grid[row+1][col] == ' ';
Number num;
if (bTopLeftEnd) num.m_nEnds++; // Top left end isn't counted properly.
num.m_bTopLeftEnd = bTopLeftEnd;
ParseNumber(_grid, row, col, num);
ret.push_back(num.toInt());
}
}
}
return ret;
}
int main()
{
vector<vector<char>> grid;
ifstream ifp("c:\\numbergrid.txt");
string strLine;
while (getline(ifp, strLine))
{
grid.push_back(vector<char>(strLine.begin(), strLine.end()));
}
vector<int> nums = Parse(grid);
for (auto i = grid.begin(); i != grid.end(); i++)
{
for (auto j = i->begin(); j != i->end(); j++)
cout << *j;
cout << endl;
}
cout << endl << "Results: " << endl;
for (auto i = nums.begin(); i != nums.end(); i++)
cout << *i << " ";
cout << endl;
return 0;
}