All pastes #2092409 Raw Edit

Mine

public text v1 · immutable
#2092409 ·published 2011-10-22 04:01 UTC
rendered paste body
#include <vector>
#include <iostream>

using namespace std;

enum CellType
{
	blankCell,
	ruleCell,
	numberCell
};

class Cell
{
public:
	virtual CellType type(){return blankCell;};
};

class Rule;

class NumberCell : public Cell
{
public:
	int getNumber(){return number;};
	bool canPutNumber(int number);
	void setNumber(int number);

	virtual CellType type(){return numberCell;};

	Rule* rowRule;
	Rule* colRule;
private:
	int number;
};

class Rule
{
public:
	int sum;
	vector<NumberCell*> cells;
	int currentSum;
	int numberOfOccupiedCells;

	bool CanPutNumber(int number)
	{
		// Check that the number is unique
		for (int i = 0; i < cells.size(); i++)
		{
			if (cells[i]->getNumber() == number)
			{
				return false;
			}
		}

		// Make sure we don't overflow
		if (number + currentSum > sum ||
			(number + currentSum == sum && numberOfOccupiedCells < cells.size() - 1))
		{
			return false;
		}

		// And that if we are the last one, it has to sum up
		if (numberOfOccupiedCells == cells.size() - 1 &&
			number + currentSum != sum)
		{
			return false;
		}

		return true;
	}
};

bool NumberCell::canPutNumber(int number)
{
	return (rowRule->CanPutNumber(number) && rowRule->CanPutNumber(number));
}

void NumberCell::setNumber(int number)
{
	// If we had a previous number, remove from the rules current sums
	if (this->number != 0)
	{
		rowRule->currentSum -= this->number;
		rowRule->numberOfOccupiedCells--;
		colRule->currentSum -= this->number;
		rowRule->numberOfOccupiedCells--;
	}
	this->number = number;

	rowRule->currentSum += this->number;
	rowRule->numberOfOccupiedCells++;
	colRule->currentSum += this->number;
	rowRule->numberOfOccupiedCells++;
}

enum Direction
{
	down,
	right,
	both
};

class RuleCell : public Cell
{
public:
	virtual CellType type(){return ruleCell;};
	int sumDown;
	int sumRight;
	Direction direction;
};

bool VerticalRuleSetup(Cell* board[10][10], int x, int y, int N, int sum)
{
	int i = 1;
	Rule *rule = new Rule();
	rule->sum = sum;
	bool valid = true;

	while (valid)
	{
		int newPos = (y + i);
		
		// If we go out of bound, there's an error
		if (newPos >= N && i <= 2)
		{
			return false;
		}

		CellType type = board[newPos][x]->type();

		if (type == ruleCell || type == blankCell)
		{
			// If we only passed one or less cell, there's an error
			if (i <= 2)
			{
				return false;
			}
			// Else, everything is good
			return true;
		}

		if (type == numberCell)
		{
			NumberCell* cell = (NumberCell*)board[newPos][x];
			cell->colRule = rule;
		}

		i++;
	}

	return true;
}

void Validation (Cell* board[10][10], int N)
{
	for (int y = 0; y < N; y++)
	{
		for (int x = 0; x < N; x++)
		{
			switch (board[y][x]->type())
			{
			case blankCell :
				// If the cell next to a blank cell is a number, it is invalid
				if (board[y][x+1]->type() == numberCell)
				{
					goto validation_err;
				}
				break;
			case ruleCell :

				break;
			case numberCell :
				// We should only pass on number cell through a rule
				goto validation_err;
				break;
			}
		}
	}

	return;
validation_err:
	cout << "Invalid Puzzle Structure";
	exit(0);
}

Cell** LoadBoard()
{
	int N;
	cin >> N;

	Cell** board = new Cell*[N*N];

	for (int i = 0; i < N * N; i++)
	{
		int num1, num2;
		cin >> num1; cin >> num2;

		// if we have -1, we have a blank cell
		if (num1 == num2 == -1)
		{
			board[i] = new Cell();
		}
		if (num1 == num2 == 0)
		{
			board[i] = new NumberCell();
		}
	}

	return board;
}