#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 注意:如果修改了SUDOKU_SIZE的定义值,需要检查一下squareCheck函数的代码是否正确
const int SUDOKU_SIZE = 9; // 最好定义一个常量,而不是使用魔数(Magic Number)

const int SUDOKU_MAXNUM = 9;
const int SUDOKU_MINNUM = 1;

// 数组检查
// 不重复不遗漏且无规定外数字时返回true
// 否则返回false
bool arrCheck(const int arr[SUDOKU_SIZE])
{
	int countArray[SUDOKU_SIZE] = {0}; // 初始化计数数组的所有元素为0
	for (int ii = 0; ii < SUDOKU_SIZE; ii++)
	{
		if(SUDOKU_MINNUM <= arr[ii] && arr[ii] <= SUDOKU_MAXNUM) // 如果所有的数据都在1至9之间
		{
			countArray[arr[ii]-1]++; // 相应的计数加一
		} else {
			return false; // 存在规定数字以外的情况
		}
	}

	for (int ii = 0; ii < SUDOKU_SIZE; ii++)
	{
		if(countArray[ii] != 1) // 如果计数结果不是一
		{
			return false; // 相当于违反了【不重复不遗漏的规则】
		}
	}

	return true;
}

void printArray(const int arr[SUDOKU_SIZE])
{
	for (int ii = 0; ii < SUDOKU_SIZE; ii++)
	{
		printf("%d", arr[ii]);
	}
	printf("\n");
}

// 行检查
bool rowCheck(const int arr[SUDOKU_SIZE][SUDOKU_SIZE])
{
	for (int rr = 0; rr < SUDOKU_SIZE; rr++)
	{
		int checkArray[SUDOKU_SIZE] = {0};
		for ( int cc = 0; cc < SUDOKU_SIZE; cc++)
		{
			checkArray[cc] = arr[rr][cc];
		}
		printArray(checkArray);
		if (!arrCheck(checkArray))
		{
			return false;
		}
	}

	return true;
}

// 列检查
bool colCheck(const int arr[SUDOKU_SIZE][SUDOKU_SIZE])
{
	for (int cc = 0; cc < SUDOKU_SIZE; cc++)
	{
		int checkArray[SUDOKU_SIZE] = {0};
		for ( int rr = 0; rr < SUDOKU_SIZE; rr++)
		{
			checkArray[rr] = arr[rr][cc];
		}
		printArray(checkArray);
		if (!arrCheck(checkArray))
		{
			return false;
		}
	}

	return true;
}

// 方格检查
bool squareCheck(const int arr[SUDOKU_SIZE][SUDOKU_SIZE])
{
	for (int rr = 0; rr < SUDOKU_SIZE; rr += SUDOKU_SIZE/3)
	{
		int checkArray[SUDOKU_SIZE] = {0};
		for ( int cc = 0; cc < SUDOKU_SIZE; cc += SUDOKU_SIZE/3)
		{
			checkArray[0] = arr[rr  ][cc  ];
			checkArray[1] = arr[rr  ][cc+1];
			checkArray[2] = arr[rr  ][cc+2];
			checkArray[3] = arr[rr+1][cc  ];
			checkArray[4] = arr[rr+1][cc+1];
			checkArray[5] = arr[rr+1][cc+2];
			checkArray[6] = arr[rr+2][cc  ];
			checkArray[7] = arr[rr+2][cc+1];
			checkArray[8] = arr[rr+2][cc+2];

			printArray(checkArray);
			if (!arrCheck(checkArray))
			{
				return false;
			}
		}		
	}

	return true;
}

// 主程序
int main(void)
{// 注意花括号的对齐

	int arr[SUDOKU_SIZE][SUDOKU_SIZE]; // 一般的编程规范会要求一行代码仅声明一个变量

	// 用rr和cc来代表行和列更好,便于理解以及检索;for循环用变量一般在for语句中定义
	for ( int rr = 0; rr < SUDOKU_SIZE; rr++) // 注意使用空格,提高代码的可读性
	{
		for ( int cc = 0; cc < SUDOKU_SIZE; cc++)
		{
			scanf("%d", &arr[rr][cc]);
		}
	}

	printf("Row Check:  %s\n", rowCheck(arr)?"OK":"NG"); // 行检查
	printf("Col Check:  %s\n", colCheck(arr)?"OK":"NG"); // 列检查
	printf("Square Check:  %s\n", squareCheck(arr)?"OK":"NG"); // 方格检查
}