public boolean solve() {
		Util.dprint("Solving process started");
		Util.dprint("Starting grid:");
		sudoku.print();
		
		int pass = 0;
		int numHits;
		
		do {
			numHits = 0;
			for (int index = 0; index < 9*9; index++) { // loop over all slots
				if (sudoku.get(index) != 0) // find empty slots
					continue;
				int row = Util.getRow(index);
				int col = Util.getCol(index);
				int[] block_holder = Util.getBlock(row, col);
				int x = block_holder[0];
				int y = block_holder[1];
				
				// find numbers missing in this row/col/block
				ArrayList<Integer> missingRow = missingNumbersRow(row);
				ArrayList<Integer> missingCol = missingNumbersCol(col);
				ArrayList<Integer> missingBlock = missingNumbersBlock(x, y);
				
				ArrayList<Integer> hits = new ArrayList<Integer>(); //numbers that occur in all three
				for (Integer i : missingRow) {
					if (missingCol.contains(i) && missingBlock.contains(i)) {
						hits.add(i);
					}
				}
				if (hits.size() == 1) {
					sudoku.set(index, hits.get(0));
					Util.dprint("Found: row=" + row + ", col=" + col + ", value=" + hits.get(0));
					numHits++;
				} else if (hits.size() > 1) {
					for (Integer i : hits)
						Util.dprint("Maybe: row=" + row + ", col=" + col + ", value=" + i);
				}
			}
			pass++;
			Util.dprint("pass " + pass);
		} while (numHits != 0);
		
		sureHits = sudoku;
		
		Util.dprint("Final product:");
		sudoku.print();
		return sudoku.validateField();
	}