<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
   
  </head>

  <body class="solver">
    <div id="solver">
		<div class="table">
			<div class="r0">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r1">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r2">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r3">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r4">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r5">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r6">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r7">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
			<div class="r8">
				<div>
					<input type="text" class="0" maxlength="1">
				</div>
				<div>
					<input type="text" class="1" maxlength="1">
				</div>
				<div>
					<input type="text" class="2" maxlength="1">
				</div>
				<div>
					<input type="text" class="3" maxlength="1">
				</div>
				<div>
					<input type="text" class="4" maxlength="1">
				</div>
				<div>
					<input type="text" class="5" maxlength="1">
				</div>
				<div>
					<input type="text" class="6" maxlength="1">
				</div>
				<div>
					<input type="text" class="7" maxlength="1">
				</div>
				<div>
					<input type="text" class="8" maxlength="1">
				</div>
			</div>
		</div>
		<div class="right_pannel">
			<p class="msg">Stand by</p>
			<div>
				<textarea class="initVal">
				</textarea>
				<div class="buttons">
					<button onclick="javascirpt:exe();" style="width: 50px;">Solve</button>
					<button onclick="javascirpt:set();" style="width: 36px;">Set</button>
					<button onclick="javascirpt:load();" style="width: 45px;">Load</button>
					<button onclick="javascirpt:clr();" style="width: 48px;">Clear</button>
				</div>
				<div>
					<label><input type="checkbox" name="show" value="on" class="chk_show">Show
						process(slow)</label>
				</div>
			</div>
		</div>
	</div>
     <script src="script.js"></script>
  </body>

</html>
/****************스도쿠 함수 시작*****************/
/****************스도쿠 함수 시작*****************/
/****************스도쿠 함수 시작*****************/

var r = new Array(9);
var c = new Array(9);
var s = new Array(9);
for (var i = 0; i < 9; i++) {
	r[i] = new Array(9);
	c[i] = new Array(9);
	s[i] = new Array(9);
}
var Set = function(rn, cn) {
	this.rn = rn;
	this.cn = cn;
	this.num = [ true, true, true, true, true, true, true, true, true ];
};

function init() {
	for (var i = 0; i < 9; i++)
		for (var j = 0; j < 9; j++)
			c[j][i] = r[i][j] = {	v : 0	};
	for (var rn = 0; rn < 9; rn += 3)
		for (var cn = 0; cn < 9; cn += 3)
			for (var i = 0; i < 3; i++)
				for (var j = 0; j < 3; j++)
					s[rn + parseInt(cn / 3)][i * 3 + j] = r[rn + i][cn + j];
}

function sizeofNumset(set) { // 가능한 숫자 개수 카운터
	var n = set.num;
	return n[0] + n[1] + n[2] + n[3] + n[4] + n[5] + n[6] + n[7] + n[8];
}

function findAblNum(rn, cn) { // 해당 칸의 가능한 숫자 세트 탐색
	var nums = new Set(rn, cn);
	var sn = parseInt(rn / 3) * 3 + parseInt(cn / 3); // 섹터 번호 구함
	for (var i = 0; i < 9; i++) {
		// 행(r),열(c),섹터(s) 탐색
		if (r[rn][i].v > 0) // 채워져 있으면
			nums.num[r[rn][i].v - 1] = false; // 마킹
		if (c[cn][i].v > 0)
			nums.num[c[cn][i].v - 1] = false;
		if (s[sn][i].v > 0)
			nums.num[s[sn][i].v - 1] = false;
	}
	return nums;
}

function findMinPossible() { // 가장 경우의 수가 적은칸의 세트 리턴
	var size = 10;
	var minset = null;
	for (var i = 0; i < 9; i++) {
		for (var j = 0; j < 9; j++) {
			if (r[i][j].v > 0) continue; // 채워진칸 무시
			var temp = findAblNum(i, j);
			var nsize = sizeofNumset(temp);
			if (!nsize) // 빈칸인데 가능한 숫자가 없으면
				return new Set(10, 10); // 오답 표시 리턴
			else if (nsize === 1) // 가능한 숫자가 하나일 경우 바로 리턴
				return temp;
			else if (nsize < size) {
				size = nsize;
				minset = temp;
			}
		}
	}
	return minset;
}

function solve() {
	var set = findMinPossible(); // 가장 경우의 수가 적은 칸 탐색
	if (set === null) // 더 이상 빈칸이 없음을 뜻함.
		return true; // 풀린것!
	if (set.rn > 9) // 불가능한 칸이 있음을 뜻함
		return false;
	for (var i = 1; i <= 9; i++) { // 숫자 1~9를 채우는 부분
		if (!set.num[i - 1])
			continue; // 불가능한 숫자는 스킵
		r[set.rn][set.cn].v = i; // 가능한 숫자를 채움
		if (solve()) // 채운걸 풀어봄
			return true; // 그게 풀렸으면 탈출
	}
	// 채울 수 있는 숫자가 없거나 다 채워봤는데 안된거니까
	r[set.rn][set.cn].v = 0; // 지우고
	return false; // 오답 리턴
}

(function main() {
	init();
})();

/*************여기까지 스도쿠 함수 끝*************/
/*************여기까지 스도쿠 함수 끝*************/
/*************여기까지 스도쿠 함수 끝*************/
















/* 중요하지 않은 html UI 상호 작용 함수 함수 */
var delay = 1;
function fill(rn, cn, val) {
	if(val>0)
		cnt++;
	setTimeout(function() {
		grd[rn][cn].value = val > 0 ? val : "";
	}, cnt * delay);
}

function display() {
	for (var i = 0; i < 9; i++)
		for (var j = 0; j < 9; j++)
			grd[i][j].value = r[i][j].v > 0 ? r[i][j].v : "";
}
function solve2() { // solve 함수에 풀이 상황 표시 추가
	var set = findMinPossible();
	if (set === null)
		return true;
	if (set.rn > 9)
		return false;
	for (var i = 1; i <= 9; i++) {
		if (!set.num[i - 1])
			continue;
		r[set.rn][set.cn].v = i;
		fill(set.rn, set.cn, i); // 이것만 추가
		if (solve2())
			return true;
	}
	r[set.rn][set.cn].v = 0;
	fill(set.rn, set.cn, 0); // 이것만 추가
	return false;
}

function set() {
	clr();
	var input = initVal.value.replace(/[^0-9\.]/g, "");
	for (var i = 0; i < 9; i++)
		for (var j = 0; j < 9; j++)
			grd[i][j].value = /[1-9]/.test(input[i * 9 + j]) ? input[i * 9 + j]
					: "";
}
function load() {
	var output = "";
	for (var i = 0; i < 9; i++) {
		for (var j = 0; j < 9; j++)
			output += /[1-9]/.test(grd[i][j].value) ? grd[i][j].value : 0;
		output += '\n';
	}
	initVal.value = output;
}
function clr() {
	msg.textContent = "Stand by";
	var inputs = table.getElementsByTagName('input');
	for (var i = 0; i < inputs.length; i++)
		inputs[i].value = inputs[i].className = "";
}
function exe() {
	msg.textContent = "Initializing";
	for (var i = 0; i < button.length; i++)
		button[i].disabled = true;
	for (var i = 0; i < 9; i++) {
		for (var j = 0; j < 9; j++) {
			if (/[1-9]/.test(grd[i][j].value))
				r[i][j].v = parseInt(grd[i][j].value);
			else {
				r[i][j].v = 0;
				grd[i][j].className = "unstatic";
			}
		}
	}
	msg.textContent = "Running";
	setTimeout(function() {
		var flag = false;
		cnt = 1;
		flag = chk_show.checked ? solve2() : solve();
		setTimeout(function() {
			for (var i = 0; i < button.length; i++)
				button[i].disabled = false;
			msg.textContent = flag ? "Solved" : "No Solution";
			display();
		}, chk_show.checked ? cnt * delay : 0);
	}, 1);
}
var grd = new Array(9);
var msg, button, initVal, solver, table, chk_show;
for (var i = 0; i < 9; i++)
	grd[i] = new Array(9);
(function() {
	// 요소 참조
	solver = document.getElementById("solver");
	chk_show = solver.getElementsByClassName('chk_show')[0];
	msg = solver.getElementsByClassName('msg')[0];
	table = solver.getElementsByClassName('table')[0];
	button = solver.getElementsByTagName('button');
	initVal = solver.getElementsByClassName('initVal')[0];
	for (var i = 0; i < 9; i++) {
		var row = solver.getElementsByClassName('r' + i)[0]
				.getElementsByTagName('input');
		for (var j = 0; j < 9; j++)
			grd[i][j] = row[j];
	}

	initVal.value = '800000000\n003600000\n070090200\n050007000\n000045700\n000100030\n001000068\n008500010\n090000400';
	set();
	// 그리드 css
	for (var i = 0; i < 9; i++)
		for (var j = 0; j < 9; j++) {
			var sn = parseInt(i / 3) * 3 + parseInt(j / 3);
			grd[i][j].parentNode.className = sn % 2 ? "even" : "odd";
		}
	
	chk_show.addEventListener("click", function() {
		if(!chk_show.checked)
			return;
		var choice = prompt("Set delay per action(ms)\ndefalut: 1ms\n1~200ms recommended", delay);
		if(choice === null)
			return;
		delay = parseInt(choice) || 1;
		delay = delay < 1 ? 1 : delay;
	});
})();
#solver,.solver{
  width: 745px;
  margin: 0 auto;
}
 
#solver .table input {
  width: 55px;
  height: 55px;
  font-size: 33pt;
  text-align: center;
  vertical-align: middle;
  color: #2B75E4;
  border: none;
  box-shadow: 0px 0px 1px #000000;
  background-color: transparent;
}

#solver .msg {
  font-size: 38pt;
  color: #2B75E4;
  height: 70px;
  width: 180px;
  white-space: nowrap;
}

#solver p {
  margin: 0px 0px;
}

#solver .table input.unstatic {
  color: #696969;
}

#solver .table>div {
  display: table;
}

#solver .table>div>div {
  display: table-cell;
}

#solver .table {
  background-color: white;
  display: table;
  border: 3pt solid black;
  float: left;
}

.right_pannel {
  float: left;
  margin-left: 20px;
}

.initVal {
  -webkit-box-sizing: border-box;
  /* Safari/Chrome, other WebKit */
  -moz-box-sizing: border-box;
  /* Firefox, other Gecko */
  box-sizing: border-box;
  /* Opera/IE 8+ */
  height: 220px;
  width: 196px;
}

#solver .table>div:nth-child(3),
#solver .table>div:nth-child(6) {
  border-bottom: 3pt solid black;
}

#solver .table>div>div:nth-child(3),
#solver .table>div>div:nth-child(6) {
  border-right: 3pt solid black;
}

.buttons button {
  font-size: 10pt;
  line-height: 20px;
}

.even {
  background-color: rgba(0, 0, 0, 0.09);
}