Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Sudoku (Rekursion)

Ein Sudokuspiel besteht aus 9x9, also 81 Feldern im Quadrat angeordnet. Darin sind die neun 3x3 Kästchen ausgezeichnet (fett umrandet). In einigen dieser 81 Feldern sind Ziffern von 1 bis 9 vorgegeben. Gesucht sind die Ziffern von 1 bis 9 in allen übrigen Kästchen. Am Ende soll jede der neun Ziffern in jeder Zeile, jeder Spalte und in jedem der 3x3 Kästchen genau einmal vorkommen.

Ein möglicher rekursiver Algorithmus könnte wie folgt aussehen:

 

// Die Datenstruktur Sudoku ist in der Lage,
// ein ungelöstes oder auch ein bereits gelöstes
// Sudoku-Feld zu speichern:

loeseSudoku(s: Sudoku) 
{
  // Abbruch:
    if(unloesbar(s)) then return;
    if(geloest  (s)) then printLoesung(s); exit(); 
  // Rekursionsschritt:
    zeile := sucheErsteZeileMitLeereintraegen(s);
    unbenutzteZahl := 
          suche eine Zahl, die auf "zeile" nicht vorkommt
    Feld (Array) von sudokus :=
          Für jeden Leereintrag in "zeile" erzeuge ein neues
          Sudoku mit "unbenutzteZahl" an dieser Stelle.
    Für alle (iterativ) Sudokus im eben erzeugten Feld:
          loeseSudoku(sudokus[i])
}

 

1 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

Kommentare (1)

AndyFFW 17. März 2013 12:51   reply report
Aus meiner C++ Lösung ist jetzt ein einfaches Sudoku Spiel geworden mit Generator und Hilfe-Funktion

7 Lösung(en)

// Loesung: Daniel Huber / Credit Suisse / Santis Training
//////////////////////////////////////////////////////////

public class Main {

	public static void main(String[] args) {

		new SudokuLoeser(new Sudoku());

	}

}

//////////////////////////////////////////////////////////


public class SudokuLoeser {

	

	public SudokuLoeser(Sudoku s) {

		System.out.println("löse jetzt..");

		int durchgang = 1;

		loeseSudoku(s, durchgang);

	}



	public void loeseSudoku(Sudoku s, int durchgang) {

		System.out.println("Durchgang:"+durchgang);

		if(inkonsistent(s)) {

			System.out.println("Inkonsistent");

			return;

		}

		if(solved(s)) {

			System.out.println("Jupii");

			System.out.println(s);

			Ausgabe a = new Ausgabe(s);

		}

		int nullZeile = ersteNullZeile(s);

		int anzahlNullern = getAnzahlNullern(s, nullZeile);

		int kleinsteZahl = kleinsteNichtverwendeteZahl(s, nullZeile);

		Sudoku[] neueSudokus = new Sudoku[anzahlNullern];

		macheNeueSudokus(s, neueSudokus, nullZeile, kleinsteZahl);

		System.out.println("neue Berechnung..");

		for(Sudoku ns : neueSudokus) {

			loeseSudoku(ns, durchgang+1);

			

		}

		

	}



	private void macheNeueSudokus(Sudoku s, Sudoku[] neueSudokus, int nullZeile, int kleinsteZahl) {

		int sudokuNummer = 0;

		for (int i = 0; i < 9; i++) {

			if(s.struktur[nullZeile][i] == 0) {

				neueSudokus[sudokuNummer] = kopiereSudoku(s);

				neueSudokus[sudokuNummer].struktur[nullZeile][i] = kleinsteZahl;

				sudokuNummer++;

			}

		}

	}



	private Sudoku kopiereSudoku(Sudoku s) {

		Sudoku ns = new Sudoku();

		for(int i=0; i<9; i++) {

			for(int ii=0; ii<9; ii++) {

				ns.struktur[i][ii] = s.struktur[i][ii];

			}

		}

		return ns;

	}



	private int getAnzahlNullern(Sudoku s, int nullZeile) {

		int cnt = 0;

		for(int i=1; i<10; i++)

			if(s.struktur[nullZeile][i-1] == 0) cnt++;

		return cnt;

	}



	private int kleinsteNichtverwendeteZahl(Sudoku s, int nullZeile) {

		int[] counter = {0,0,0,0,0,0,0,0,0};

		int cnt = 0;

		for(int z=1; z<10; z++) {

			for(int i=0; i<9; i++)

				if(s.struktur[nullZeile][i] == z) counter[z-1] = 1;

		}

		for(int i1=0; i1<9; i1++) {

			if(counter[i1] == 0) {

				cnt=i1+1;

				break;

			}

		}

		return cnt;

	}



	private int ersteNullZeile(Sudoku s) {

		for(int i=0; i<9; i++)

			for(int j=0; j<9; j++)

				if(s.struktur[i][j] == 0) return i;

		return 0;

	}



	private boolean inkonsistent(Sudoku s) {

		for(int i=0; i<9; i++) {

			if(inkonsistenteZeile(s, i)) {

				return true;

			}

			if(inkonsistenteSpalte(s, i)) {

				return true;

			}

		}

		if(inkonsistentesQuadrat(s)) return true;

		

		return false;

	}

	

	private boolean inkonsistentesQuadrat(Sudoku s) {

		return checkQuadrat(s, 0, 0) || checkQuadrat(s, 0, 3) || checkQuadrat(s, 0, 6)

			|| checkQuadrat(s, 3, 0) || checkQuadrat(s, 3, 3)

			|| checkQuadrat(s, 3, 6) || checkQuadrat(s, 6, 0)

			|| checkQuadrat(s, 6, 3) || checkQuadrat(s, 6, 6);

	}



	private boolean inkonsistenteZeile(Sudoku s, int y) {

		System.out.println("Zeile");

		int counter = 0;

		for(int z=1; z<10; z++) {

			for(int j=0; j<9; j++) {

				if(s.struktur[j][y] == z) counter++;

//				System.out.println("(y: "+y+"), (x: "+j+"), (c: "+counter+"), ZAHL:"+z);

			}

			if(counter <= 1) counter = 0;

			else return true;

		}

		return false;

	}



	private boolean inkonsistenteSpalte(Sudoku s, int x) {

		System.out.println("Spalte");

		int counter = 0;

		for(int z=1; z<10; z++) {

			for(int j=0; j<9; j++) {

				if(s.struktur[x][j] == z) counter++;

//				System.out.println("(y: "+j+"), (x: "+x+"), (c: "+counter+"), ZAHL:"+z);

			}

			if(counter <= 1) counter = 0;

			else return true;

		}

		return false;

	}

	

	private boolean checkQuadrat(Sudoku s, int a, int b) {

		int c = a + 3;

		int d = b + 3;

		for (int x = 1; x < 10; x++) {

			int count = 0;

			for (int i = a; i < c; i++) {

				for (int j = b; j < d; j++)

					if (s.struktur[i][j] == x)

						count++;

			}

			if (count > 1)

				return true;

		}

		return false;

	}



	private boolean solved(Sudoku s) {

		for (int x=0; x<9; x++) {

			for (int y=0; y<9; y++) {

				if(s.struktur[x][y] == 0) return false;

			}

		}

		return true;

	}

	

}

//////////////////////////////////////////////////////////


public class Sudoku {



	// inhalte: 0 = leer; 1-9 = zahl;



	int[][] struktur = {

		{ 0,6,5, 0,0,0, 3,9,0 },

		{ 3,0,0, 9,0,7, 0,0,6 },

		{ 7,0,4, 0,0,0, 8,0,1 },

		

		{ 0,3,0, 0,7,0, 0,2,0 },

		{ 0,0,0, 5,0,8, 0,0,0 },

		{ 0,5,0, 0,2,0, 0,8,0 },

		

		{ 6,0,2, 0,0,0, 7,0,9 },

		{ 5,0,0, 1,0,9, 0,0,2 },

		{ 0,4,1, 0,0,0, 5,3,0 }

	};

	/*int[][] struktur = {

		{ 2,6,5, 8,1,4, 3,9,7 },

		{ 3,1,8, 9,5,7, 2,4,6 },

		{ 7,9,4, 2,3,6, 8,5,1 },

		

		{ 8,3,9, 0,7,1, 6,2,5 },

		{ 4,2,6, 5,9,8, 1,7,3 },

		{ 1,5,7, 6,2,3, 9,8,4 },

		

		{ 6,0,2, 3,4,5, 0,0,9 },

		{ 5,7,3, 1,8,9, 4,6,2 },

		{ 9,4,1, 7,6,2, 5,3,8 }

	};*/

	

	public String toString() {

		String ret = "+-------------------------------------------------+\n";

		int cnt = 1, cntV = 1;

		for(int[] i : struktur) {

			for(int ii : i) {

				ret += "Š "+ii+" Š";

				ret += cnt==3||cnt==6?"   ":cnt==9?"\n":"";

				cnt = cnt==9?cnt=1:cnt+1;

			}

			ret += cntV==3||cntV==6||cntV==9?"+-------------------------------------------------+\n":"";

			cntV++;

		}

		return ret;

	}

}

//////////////////////////////////////////////////////////

import java.awt.Color;

import java.awt.GridLayout;



import javax.swing.*;



public class Ausgabe extends JFrame {



	private static final long serialVersionUID = 1L;

	

	JLabel[][] lbl = new JLabel[9][9];

	JPanel pnl = new JPanel(new GridLayout(9,9));

	JPanel[][] pnl2 = new JPanel[3][3];

	

	public Ausgabe(Sudoku s) {

		initLbls(s);

		getContentPane().add(pnl);

		setDefaultCloseOperation(EXIT_ON_CLOSE);

		setSize(380,380);

		setVisible(true);

	}



	private void initLbls(Sudoku s) {

		for(int i=0; i<9; i++) {

			for(int ii=0; ii<9; ii++) {

				lbl[i][ii] = new JLabel();

				lbl[i][ii].setText(""+s.struktur[i][ii]);

				lbl[i][ii].setSize(40,40);

				lbl[i][ii].setBorder(BorderFactory.createLineBorder(Color.black));

				pnl.add(lbl[i][ii]);

			}

		}

	}

}

                
/**
 * sudoku (JavaScript)
 * Autor: phi@gressly.ch 
 * Kurs: Siemens Modul 307: April 2010
 */

function startSudoku() {
  var sudoku = initialisiereSudoku();
  loeseSudoku(sudoku);
}

function initialisiereSudoku() {
  sudoku = new Array(9); // 9 Spalten
  sudoku[0] = new Array(0, 8, 1, 0, 0, 0, 7, 3, 0);
  sudoku[1] = new Array(9, 0, 0, 2, 0, 8, 0, 0, 4);
  sudoku[2] = new Array(6, 0, 0, 0, 0, 0, 0, 0, 8);
  sudoku[3] = new Array(0, 3, 0, 7, 0, 1, 0, 2, 0);
  sudoku[4] = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
  sudoku[5] = new Array(0, 9, 0, 5, 0, 2, 0, 1, 0);
  sudoku[6] = new Array(8, 0, 0, 0, 0, 0, 0, 0, 7);
  sudoku[7] = new Array(7, 0, 0, 3, 0, 6, 0, 0, 1);
  sudoku[8] = new Array(0, 4, 5, 0, 0, 0, 6, 9, 0);
  return sudoku;
}

function loeseSudoku(sudoku) {
  if(istRegelVerletzt(sudoku)) { 
    return;
  }
  if(istVoll(sudoku)) {
    ausgabe(sudoku);
    return;
  }
  loeseRekursiv(sudoku);
}

/**
 * Erstelle neue einfachere Sudokus und löse diese mit obigem
 * "Algorithmus".
 */
function loeseRekursiv(sudoku) {
  var zeile  = findeErsteZeileMitLeereintraegen(sudoku);
  var ziffer = findeKleinsteUnbenutzteZifferInZeile(sudoku, zeile);
  var sudokus = erzeugeNeueSudokus(sudoku, zeile, ziffer);
  for(var i = 0; i < sudokus.length; i++) {
    loeseSudoku(sudokus[i]);
  }
}

/**
 * Ist eine der drei Sudoku-Reglen (zeile, spalte, block)
 * verletzt?
 */
function istRegelVerletzt(sudoku) {
  return istEineZeileVerletzt(sudoku)   ||
         istEineSpalteVerletzt(sudoku)  ||
         istEinBlockVerletzt(sudoku);
}

function istEineZeileVerletzt(sudoku) {
  for(var zeile = 0; zeile < 9; zeile++) {
    if(istZeileVerletzt(sudoku, zeile)) {
      return true;
    }
  }
  return false;
}

function istEineSpalteVerletzt(sudoku) {
  for(var spalte = 0; spalte < 9; spalte ++) {
    if(istSpalteVerletzt(sudoku, spalte)) {
      return true;
    }
  }
  return false;
}

function istEinBlockVerletzt(sudoku) {
  for(var xb = 0; xb <= 6; xb = xb + 3) {
    for(var yb = 0; yb <= 6; yb = yb + 3) {
      if(istBlockVerletzt(sudoku, xb, yb)) {
        return true;
      }
    }
  }
  return false;
}

function istZeileVerletzt(sudoku, zeile) {
  for(ziffer = 1; ziffer <= 9; ziffer ++) {
    if(vorkommenEinerZifferInZeile(sudoku, ziffer, zeile) > 1) {
      return true;
    }
  }
  return false;
}

/**
 * Wie oft kommt "ziffer" auf "zeile" vor?
 */
function vorkommenEinerZifferInZeile(sudoku, ziffer, zeile) {
  var vk = 0;
  for(var spalte = 0; spalte <= 8; spalte ++) {
    if(sudoku[spalte][zeile] == ziffer) {
      vk = vk + 1;
    }
  }
  return vk;
}

function istSpalteVerletzt(sudoku, spalte) {
  for(ziffer = 1; ziffer <= 9; ziffer ++) {
    if(vorkommenEinerZifferInSpalte(sudoku, ziffer, spalte) > 1) {
      return true;
    }
  }
  return false;
}

/**
 * Wie oft kommt "ziffer" in "spalte" vor?
 */
function vorkommenEinerZifferInSpalte(sudoku, ziffer, spalte) {
  var vk = 0;
  for(var zeile = 0; zeile <= 8; zeile ++) {
    if(sudoku[spalte][zeile] == ziffer) {
      vk = vk + 1;
    }
  }
  return vk;
}

function istBlockVerletzt(sudoku, xb, yb) {
  for(var ziffer = 1; ziffer <= 9; ziffer ++) {
    if(vorkommenInBlock(sudoku, xb, yb, ziffer) > 1) {
      return true;
    }
  }
  return false;
}

/**
 * Wie oft kommt "ziffer" im 3x3 Kästchen ab (xb, yb) vor?
 */
function vorkommenInBlock(sudoku, xb, yb, ziffer) {
  var vk = 0;
  for(var x = xb; x < xb + 3; x ++) {
    for(var y = yb; y < yb + 3; y++) {
      if(ziffer == sudoku[y][x]) {
        vk = vk + 1;
      }
    }
  }
  return vk;
}

/**
 * Sind alle Felder besetzt? 
 */
function istVoll(sudoku) {
  var total = 0;
  for(var zeile = 0; zeile <= 8; zeile ++) {
    for(var spalte = 0; spalte <= 8; spalte ++) {
      if(sudoku[spalte][zeile] > 0) {
        total = total + 1;
      }
    }
  }
  return 81 == total;
}

function ausgabe(sudoku) {
  var para = document.getElementById("ausgabe");
  var ausgabeString = "";
  for(var zeile = 0; zeile <= 8; zeile ++) {
    for(var spalte = 0; spalte <= 7; spalte ++) {
      ausgabeString += sudoku[spalte][zeile] + " | ";
      if(0 == (spalte + 1) % 3) {
        ausgabeString += "| ";
      }
    }
    ausgabeString += sudoku[8][zeile] + "<br />";
    if(0 == (zeile + 1) % 3) {
      ausgabeString += "---------------------------------------------<br />";
    }
  }
  para.innerHTML = ausgabeString;
}

/**
 * Suche die oberste Zeile, die noch nicht voll besetzt ist.
 */
function findeErsteZeileMitLeereintraegen(sudoku) {
  for(var zeile = 0; zeile <= 8; zeile++) {
    if(hatLeerEintragAufZeile(sudoku, zeile)) {
      return zeile;
    }
  }
}

function hatLeerEintragAufZeile(sudoku, zeile) {
  for(var spalte = 0; spalte <= 8; spalte ++) {
    if(0 == sudoku[spalte][zeile]) {
      return true;
    }
  }
}

function findeKleinsteUnbenutzteZifferInZeile(sudoku, zeile) {
  for(ziffer = 1; ziffer <= 9; ziffer++) {
    if(!kommtZifferAufZeileVor(sudoku, ziffer, zeile)) {
      return ziffer;
    }
  }
}

function kommtZifferAufZeileVor(sudoku, ziffer, zeile) {
  for(var spalte = 0; spalte <= 8; spalte ++) {
    if(ziffer == sudoku[<script type="text/javascript" src="http://edit.programmieraufgaben.ch/js/tiny_mce/themes/advanced/langs/de.js"></script><script type="text/javascript" src="http://edit.programmieraufgaben.ch/js/tiny_mce/plugins/syntaxhighlight/langs/de.js"></script>spalte][zeile]) {
      return true;
    }
  }
  return false;
}

/**
 * Erzeuge für jedes freie Feld auf "zeile" ein neues
 * Sudoku mit "ziffer" anstelle des freien Feldes.
 */
function erzeugeNeueSudokus(sudoku, zeile, ziffer) {
  var plaetze = findeAnzahlFreiePlaetze(sudoku, zeile);
  var sudokus = new Array(plaetze);
  var pos = 0;
  for(var spalte = 0; spalte <= 8; spalte ++) {
    if(0 == sudoku[spalte][zeile]) {
      sudokus[pos++] = neuesSudoku(sudoku, zeile, spalte, ziffer);
    }
  }
  return sudokus;
}

/**
 * Wie viele Felder sind auf "zeile" noch frei?
 */
function findeAnzahlFreiePlaetze(sudoku, zeile) {
  var anz = 0;
  for(var spalte = 0; spalte <= 8; spalte++) {
    if(0 == sudoku[spalte][zeile]) {
      anz++;
    }
  }
  return anz;
}

/**
 * Erzeuge aus "sudoku" ein neues (Kopie), das an der Stelle
 * [spalte][zeile] die "ziffer" eingefüllt hat.
 * Alle anderen Werte werden einfach aus "sudoku" kopiert.
 */
function neuesSudoku(sudoku, zeile, spalte, ziffer) {
  var neuesSudoku = new Array(9);
  for(var sp = 0; sp <= 8; sp ++) {
    neuesSudoku[sp] = new Array(9);
    for(var ze = 0; ze <= 8; ze ++) {
      neuesSudoku[sp][ze] = sudoku[sp][ze];
    }
  }
  neuesSudoku[spalte][zeile] = ziffer;
  return neuesSudoku;
}

                
// Loese Sudoku durch Kombination von einfachem direkten Loeser und Back-Track Prinzip

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;

import java.util. ArrayDeque;

 
public class SudokuV2{

private static final int BOX_SIZE = 3;
private static final int SIZE = BOX_SIZE  * BOX_SIZE;
private static int[][] matrix = new int[SIZE][SIZE];
private static boolean[][] row = new boolean [SIZE][SIZE];  
private static boolean[][] col = new boolean[SIZE][SIZE];  
private static boolean[][] box = new boolean[SIZE][SIZE];  

private static ArrayDeque <Entry> q= new ArrayDeque<Entry>();

private static int rec_tries=0;

/**
 * Liest die Eingabedatei, wobei ein korrekter  Aufbau vorausgesetzt wird. 
 * Fuellt dabei die Sudoku-Matrix mit den spezifizierten Eingabewerten.
 * 
 * @param file
 *            Textdatei mit  Ziffertripeln
 *  
 */
private static void parseInput(File file) {
  try {
    BufferedReader reader = new BufferedReader(new FileReader(file));
    String sudokuLine = new String(reader.readLine());
    StringTokenizer tokenizer = new StringTokenizer(sudokuLine, " ");

    while (tokenizer.hasMoreTokens()) {
      String token = tokenizer.nextToken();
      try {
        int i = Integer.parseInt(token.substring(0,1));
        int j = Integer.parseInt(token.substring(1,2));
        int val = Integer.parseInt(token.substring(2,3));
        matrix[i][j] = val;
      } 
      catch (NumberFormatException n) {
        return;
      }
    } // end while
  } 
  catch (FileNotFoundException e) {
    System.out.println("ERROR: File not found");
  } 
  catch (IOException e) {
    System.out.println("ERROR: IOException in parseSudoku(...)");
  }

} // end parseInput

/**
* Ueberprueft ob die Sudoku-Randbedingungen fuer das Vorkommen von Ziffern 
* erfuellt sind.  Fuellt gleichzeitig  die Hilfsdatenstrukturen 
* row, col und box
* @return true, falls matrix ein gueltiges Sudoku enthaelt, sonst false.
*/
private static boolean verifySudoku() {
  int value;
  for (int val=1; val<= SIZE; val++){
     for (int i=0; i<SIZE; i++){
        for (int j=0; j<SIZE; j++){
          markValue(i,j,val,false);
        }
     }
  }               
  for (int i = 0; i < SIZE; i++) {
    for (int j = 0; j <SIZE; j++) {
      value = matrix[i][j];
      if (value != 0) {
        if (valueNotSet(i,j,value))
           markValue(i,j,value,true);
        else
          return false;
      }
    }
  }
  return true;
} // end verifySudoku


/** 
* Prueft ob der Wert val bereits vorkommt
*
*/

private static boolean valueNotSet(int i, int j, int val) {
  return (row[i][val-1]==false) &&
         (col[j][val-1]==false) &&
         (box[i/BOX_SIZE * BOX_SIZE + j/BOX_SIZE][val-1] == false);
} // end valueNotSet

/** 
* Markiert den Wert val in den Hilfsdatenstrukturen
*/

private static void markValue(int i, int j, int val, boolean state) {
  row[i][val-1] = state;
  col[j][val-1] = state;
  box[i/BOX_SIZE * BOX_SIZE + j/BOX_SIZE][val-1] = state;
} // end markValue

/** 
* Setzt einen Matrixwert
*/

private static void setValue(int i, int j, int val) {
   matrix[i][j]=val;
} // end setValue

/**
 * Loest Sudoku
 * 
 * @return true, falls das Sudoku geloest wurde, sonst false
 */

private static boolean solveSudoku() {
  Entry e;
  int i,j;
  int count; // zaehler fuer m?gliche Eintraege
  int val_to_use=0;
  int max_iter;
  int iter=0;
  boolean monitor=true;

  System.out.println("Start mit direktem Loesen");
  
  // Die zu setzenden Ziffern als Auftraege in Schlange setzen
  
   
  for (i = 0; i < SIZE; i++) {
    for (j = 0; j <SIZE; j++) {
      if (matrix[i][j]==0) {
         q.offer(new Entry(i,j));
      }
    }
  }
  
  if ( q.size() ==0) return true;  
  
  max_iter=q.size();
  if (monitor){
     System.out.println("Inhalt der Schlange:");
     System.out.println("Zeile Spalte #Kand Wert");
  }
  while (!q.isEmpty()){ 
    e=q.poll();
    i=e.getRow();
    j=e.getCol();
    count=0;
    // wir pruefen und zaehlen die moeglichen Werte
    for (int val = 1; val <= SIZE; val++){
      if (valueNotSet(i,j,val)){ 
        count++; val_to_use=val;
      }
    }
    if(monitor)System.out.print("  " + i + "      " + j + "     " + count);
    if (count==1){ // nur 1 Zahl passt: nutze sie
      if(monitor) System.out.print("    " + val_to_use);
      setValue(i,j,val_to_use);
      markValue(i,j,val_to_use,true);
      
    }
    else
      q.offer(e); // wieder in Schlange aufnehmen, da mehrere Kandidaten
    if(monitor) System.out.println();
    
    iter++; // Abarbeitung der Elemente zaehlen
    if (iter==max_iter){  // kompletter Durchgang durch Schlange erfolgt
      if (max_iter==q.size()){ // kein Eintrag ist verschwunden
        System.out.println("Wechsel in Backtrack-Modus");
        e=q.poll();
        return solveBacktrack(e.getRow(), e.getCol());
      }
      else
      if (q.size() > 0){
        if (monitor) System.out.println("Naechste Serie");
        iter=0; 
        max_iter=q.size();
      }
    }
  }
  return true;

} // end solveSudoku

  private static boolean solveBacktrack(int i, int j) {
  int val;
  Entry e;
  rec_tries++;
  for (val = 1; val <= SIZE; val++) {
    if (valueNotSet(i,j,val)) {
      setValue(i,j,val);
      markValue(i,j,val,true);
      if (!q.isEmpty()){
        e=q.poll(); // naechsten Index aus Schlange holen
        if (solveBacktrack(e.getRow(),e.getCol())) 
          return true;
        else{
            setValue(i,j,0);
            markValue(i,j,val,false);
            q.offerFirst(e); // zurueck in  die Schlange
        }       
      }
      else return true;
    }
  }
  
  return false;
} // end solveBacktrack

 

/** 
* Ausdruck eines Sudoku das in matrix gespeichert ist
*/

private static void printSudoku() {
  for (int i = 0; i <SIZE; i++) {
    for (int j = 0; j < SIZE; j++) 
        System.out.print((matrix[i][j] == 0 ? " ": matrix[i][j])+" ");
    System.out.println();
  }
} //end printSudoku

public static void main(String[] args) {
  boolean result;
  if (args.length == 1) {
    File file = new File(args[0]);
    parseInput(file);
    System.out.println("Eingabe des Sudoku-Problems:");
    printSudoku();
    System.out.println();
    if (verifySudoku()){
      System.out.println("ist korrekt");
    }
    else{
     System.out.println("ist fehlerhaft");
     return;
    }
                  
    start = getTime();
    result= solveSudoku();
    end = getTime(); 

    if (result){
      System.out.println("Loesung des Sudoku:");
      printSudoku();
      System.out.println("wurde" + (verifySudoku()? " ": " nicht ")+ 
         "erfolgreich ueberprueft");
      System.out.println("Funktionsaufrufe: " + rec_tries);
      printTiming();
    } 
    else{
      System.out.println("Fehlerhaftes Programm");
    }
     
  }
} // end main

// Routinen fuer Zeitmessung

private static long getTime(){
  return System.nanoTime();
}

private static void printTiming(){
  double fMilliSeconds = (end - start) / 1000000.0;
  System.out.printf("Sudoku geloest nach  %5.1f ms", fMilliSeconds);
}
private static long start;
private static long end;
}

                
# Copyright Peter J.A. Cock, 2006
# All rights reserved.
# 
# You may choose to be bound by either:
#
# (a) Licenced free for personal non-commerial use.
#      May not be redistributed without prior permission.
#
# Or:
# (b) The GPL version 2, see http://www.gnu.org/licenses/gpl.html

RUN_BUILT_IN_TESTS=True
RUN_TEST_FILES=True

TRIPLETS = [[0,1,2],[3,4,5],[6,7,8]]

#Row/Col/3x3 iteration list, each is nine lists of nine (row,col) pairs
ROW_ITER = [[(row,col) for col in range(0,9)] for row in range(0,9)]
COL_ITER = [[(row,col) for row in range(0,9)] for col in range(0,9)]
TxT_ITER = [[(row,col) for row in rows for col in cols] for rows in TRIPLETS for cols in TRIPLETS]

class sudoku:
    def __init__(self, start_grid=None) :
        #Setup list of lists (the rows), each row is a list of 9 cells, which are each a list of integers 1-9 inclusive.
        self.squares =[ [range(1,10)  for col in range(0,9)] for row in range(0,9)]
        
        if start_grid is not None:
            if len(start_grid)==81 :
                for row in range(0,9) :
                    self.set_row(row, start_grid[(row*9):((row+1)*9)])
            else :
                assert len(start_grid)==9, "Bad input!"
                for row in range(0,9) :
                    self.set_row(row, start_grid[row])
                
        #self.check()
        self._changed=False

    def solved(self) :
        for row in range(0,9) :
            for col in range(0,9) :
                if len(self.squares[row][col]) > 1 :
                    return False
        return True

    def copy(self) :
        sudoku_copy = sudoku(None)
        for row in range(0,9) :
            for col in range(0,9) :
                sudoku_copy.squares[row][col] = self.squares[row][col][:] #copy!
        sudoku_copy._changed=False
        return sudoku_copy
    
    def set_row(self,row, x_list) :
        assert len(x_list)==9
        for col in range(0,9) :
            try :
                x = int(x_list[col])
            except :
                x = 0
            #self.set_cell(row,col,x)
            self.set_cell(row,col,x)

    def set_cell(self,row,col,x):
        if self.squares[row][col] == [x] :
            #Already done!
            pass
        elif x not in range(1,9+1) :
            #Set to unknown
            pass
        else:
            assert x in self.squares[row][col], \
            "Told to set square (%i,%i) to an impossible entry, %i" % (row,col,x)
            
            self.squares[row][col] = [x]
            self.update_neighbours(row,col,x)
            self._changed=True
            
    def cell_exclude(self, row,col,x) :
        assert x in range(1,9+1)
        if x in self.squares[row][col] :
            #Remove it...
            self.squares[row][col].remove(x)
            #Should be one or more entries left...
            assert len(self.squares[row][col]) > 0, \
            "Removed last possible entry for square (%i,%i) which was %i" \
            % (row, col, x)
            #Now, has this confirmed the value for this square?
            if len(self.squares[row][col]) == 1 :
                #This cell is now definate..
                #Need to update its friends...
                #print "After exluding %i, square (%i,%i) must be %i" \
                #% (x, self.row, self.col, self[0])
                self._changed=True
                self.update_neighbours(row,col,self.squares[row][col][0])
        else :
            #Don't need to remove this, already done!
            pass
        return

    def row_exclude(self, row, x) :
        assert x in range(1,9+1)
        for col in range(0,9) :
            self.cell_exclude(row,col,x)

    def col_exclude(self, col, x) :
        assert x in range(1,9+1)
        for row in range(0,9) :
            self.cell_exclude(row,col,x)

    def update_neighbours(self,set_row,set_col,x) :
        """Call this when the square is set to x, either directly,
        or as a side effect of an exclude leaving only one entry"""
        #print "Updating (%i,%i) to be %i..."  % (self.row, self.col, x)
        #Update the possibilies in this row...
        for row in range(0,9) :
            if row <> set_row :
                self.cell_exclude(row,set_col,x)
        #Update the possibilies in this col...
        for col in range(0,9) :
            if col <> set_col :
                self.cell_exclude(set_row,col,x)
        #Update the possibilies in this 3x3 square...
        for triplet in TRIPLETS :
            if set_row in triplet : rows = triplet[:]
            if set_col in triplet : cols = triplet[:]
        #Only need to do four of the eight possibles (well, 9 if you count the cell itself)
        #as did two on the row, and two on the col
        rows.remove(set_row)
        cols.remove(set_col)
        for row in rows :
            for col in cols :
                assert row <> set_row or col <> set_col 
                #print "Updating (%i,%i) to be %i, excluding %i from (%i, %i)" \
                #% (self.row, self.col, x, x, row, col)
                self.cell_exclude(row,col,x)
            
    def get_cell_int(self,row,col) :
        if len(self.squares[row][col])==1 :
            return int(self.squares[row][col][0])
        else :
            return 0

    def get_cell_str(self,row,col) :
        if len(self.squares[row][col])==1 :
            return "(%i,%i) = %i" % (row, col, self.squares[row][col][0])
        else :
            return ("(%i,%i) = " % (row, col)) + ",".join([str(x) for x in self.squares[row][col]]) 

    def get_cell_digit_str(self,row,col) :
        if len(self.squares[row][col])==1 :
            return str(self.squares[row][col][0])
        else :
            return "0"
            
    def as_test_81(self) :
        """Return a string of 81 digits"""
        return  "".join(self.as_test_list())
            
    def simple_text(self) :
        return  "\n".join(self.as_test_list())
        
    def as_test_list(self) :
        return  [  ("".join( [self.get_cell_digit_str(row,col) for col in range(0,9)]))  for row in range(0,9) ]
        """
        answer=[]
        for row in range(0,9) :
            line=""
            for col in range(0,9) :
                line = line + self.get_cell_digit_str(row,col)
            answer.append(line)
        return answer
        """

    def __repr__(self):
        answer="[" + ",".join([ \
            ("[" + ",".join( [self.get_cell_digit_str(row,col) for col in range(0,9)]) + "]") \
            for row in range(0,9) ])
        return answer

    def __str__(self):
        answer = "   123   456   789\n"
        for row in range(0,9) :
            answer = answer + str(row+1) \
                        +   " [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(0,3)]) \
                        + "] [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(3,6)]) \
                        + "] [" + "".join([self.get_cell_digit_str(row,col).replace("0","?") for col in range(6,9)]) \
                        + "]\n"
            if row+1 in [3,6] : 
              answer = answer + "   ---   ---   ---\n"
        return answer
                    
    def check(self, level=0) :
        self._changed=True
        while self._changed:
            #print "checking..."
            self._changed=False
            self.check_for_single_occurances()
            self.check_for_last_in_row_col_3x3()
            if level >= 1 :
                self.overlapping_3x3_and_row_or_col() #(aka slicing and dicing)
            if level >= 2 :
                self.one_level_supposition()
            if level >= 3 :
                self.two_level_supposition()
            
            #If nothing happened, then self.changed==False (still)
            #and we break the loop
        return
        
    def check_for_single_occurances(self):
        #Want to see if x only occurs once in this row/col/3x3...
        for check_type in [ROW_ITER, COL_ITER, TxT_ITER]:
            for check_list in check_type :
                for x in range(1,9+1) : #1 to 9 inclusive
                    x_in_list = []
                    for (row,col) in check_list :
                        if x in self.squares[row][col] :
                            x_in_list.append((row,col))
                    if len(x_in_list)==1 :
                        (row,col) = x_in_list[0]
                        #This position MUST be be x
                        if len(self.squares[row][col]) > 1 :
                            self.set_cell(row,col,x)

    def check_for_last_in_row_col_3x3(self):
        #Now, for each row/col/3x3 want to see if there is a single
        #unknown entry...
        for (type_name, check_type) in [("Row",ROW_ITER),("Col",COL_ITER),("3x3",TxT_ITER)]:
            for check_list in check_type :
                unknown_entries = []
                unassigned_values = range(1,9+1) #1-9 inclusive
                known_values = []
                for (row,col) in check_list :
                    if len(self.squares[row][col]) == 1 :
                        assert self.squares[row][col][0] not in known_values, \
                        "Already have %i (%i,%i) in known list [%s] for %s" % (self.squares[row][col][0],row,col, ",".join(map(str,known_values)), type_name)

                        known_values.append(self.squares[row][col][0])

                        assert self.squares[row][col][0] in unassigned_values, \
                        "Expected %i (%i,%i) in list [%s] for %s" % (self.squares[row][col][0],row,col, ",".join(map(str,unassigned_values)), type_name)

                        unassigned_values.remove(self.squares[row][col][0])
                    else :
                        unknown_entries.append((row,col))
                assert len(unknown_entries) + len(known_values) == 9
                assert len(unknown_entries) == len(unassigned_values)
                if len(unknown_entries) == 1 :
                    #This cell must be the only number 1-9 not in known_values
                    x = unassigned_values[0]
                    (row,col) = unknown_entries[0]
                    
                    #assert x not in known_values

                    #print "Because its the last cell in its row/col/3x3 entry (%i,%i) must be %i" \
                    #% (row,col,x)
                    self.set_cell(row,col,x)
        """
        for row in range(0,9) : self.check_row(row)
        for col in range(0,9) : self.check_col(col)
        #Check the 3x3 squares...
        for rows in TRIPLETS :
            for cols in TRIPLETS :
                for x in range(0,9) :
                    x_in_location=[]
                    for row in rows:
                        for col in cols :
                            if x in self.squares[row][col] :
                                x_in_location.append((row,col))
                    if len(x_in_location)==1 :
                        (row,col) = x_in_location[0]
                        #This position MUST be be x
                        if len(self.squares[row][col]) > 1 :
                            self.set_cell(row,col,x)
        """
        return
        
    def diagnosis(self) :
        answer=""
        df = long(1)
        for row in range(0,9) :
            for col in range(0,9):
                if len(self.squares[row][col]) > 1 :
                    answer = answer + str(self.squares[row][col]) + "\n"
                    df = df * len(self.squares[row][col])
        answer = answer + "Degrees of freedom: %i" % df
        return answer

    def overlapping_3x3_and_row_or_col(self):
        """Block and Column / Row Interactions (name from Simon Armstrong)

        http://www.simes.clara.co.uk/programs/sudokutechnique3.htm

        Also known as 'slicing and dicing'
        """
        #For a given 3x3, and a given digit, want to see if
        #all the remaining candidates are in a single row or column..
        #Want to see if x only occurs once in this row/col/3x3...
        for check_list in TxT_ITER :
            for x in range(1,9+1) : #1 to 9 inclusive
                #print "Checking %i in 3x3" % x, check_list
                rows_for_x = []
                cols_for_x = []
                for (row,col) in check_list :
                    if x in self.squares[row][col] :
                        #print "Found possible %i at (%i,%i)" % (x, row, col)
                        if row not in rows_for_x : rows_for_x.append(row)
                        if col not in cols_for_x : cols_for_x.append(col)
                #Are they all in the same row?
                if len(rows_for_x)==1 and len(cols_for_x) > 1 :
                    #print "%i must be in row %i using cols %s" % (x, rows_for_x[0]+1, ",".join(map(lambda i : str(i+1),cols_for_x)))
                    #print self
                    #This means, we can remove X from all the rest of the row...
                    row = rows_for_x[0]
                    for col in range(0,9) :
                        if col not in cols_for_x :
                            self.cell_exclude(row,col,x)
                    #We can also remove x from all the rest of this 3x3...
                    for (row,col) in check_list :
                        if col not in cols_for_x :
                            if row not in rows_for_x :
                                self.cell_exclude(row,col,x)
                #Are they all in the same col?
                if len(cols_for_x)==1 and len(rows_for_x) > 1 :
                    #print "%i must be in col %i using rows %s" % (x, cols_for_x[0]+1, ",".join(map(lambda i : str(i+1),rows_for_x)))
                    #print self
                    #This means, we can remove X from all the rest of the row...
                    col = cols_for_x[0]
                    for row in range(0,9) :
                        if row not in rows_for_x :
                            self.cell_exclude(row,col,x)
                    #We can also remove x from all the rest of this 3x3...
                    for (row,col) in check_list :
                        if col not in cols_for_x :
                            if row not in rows_for_x :
                                self.cell_exclude(row,col,x)

    def one_level_supposition(self):
        """Probably what is known as 'Nishio', try a number and see if it leads to a dead end.
        
        For all the ambigous squares, try each possible each entry and see
        if its OK, or if it leads to a contradiction.  In the case of a contradiction
        we can remove it as a possibility...
        
        Two level suppositions (two guess) may be required for extreme puzzles..."""
        progress=True
        while progress :
            progress=False
            #print "Doing one level supposition..."
            for row in range(0,9) :
                for col in range(0,9):
                    if len(self.squares[row][col]) > 1 :
                        bad_x = []
                        for x in self.squares[row][col] :
                            #print "/-- Trying setting (%i,%i) to %i" % (row,col,x)
                            sudoku_copy = self.copy()
                            try:
                                sudoku_copy.set_cell(row,col,x)
                                sudoku_copy.check(level=1)
                            except AssertionError, e :
                                #Leads to an error :)
                                #This means that this square cannot be x
                                #print e
                                #print "%s cannot be %i" % (str(self.squares[row][col]), x)
                                bad_x.append(x)
                            del sudoku_copy
                            #print "\-- End of exp"
                        if len(bad_x) == 0 :
                            pass
                        elif len(bad_x) < len(self.squares[row][col]) :
                            for x in bad_x :
                                self.cell_exclude(row,col,x)
                                self.check() 
                            progress=True
                        else :
                            assert False, "Bugger! All possible values for square (%i,%i) fail" \
                            % (row,col)
        #print "One level supposition done"
        
    def two_level_supposition(self) :
        progress=True
        while progress :
            progress=False
            #print "Doing two level supposition..."
            for row in range(0,9) :
                for col in range(0,9):
                    if len(self.squares[row][col]) > 1 :
                        bad_x = []
                        for x in self.squares[row][col] :
                            #print "/-- Trying setting (%i,%i) to %i" % (row,col,x)
                            sudoku_copy = self.copy()
                            try:
                                sudoku_copy.set_cell(row,col,x)
                                #sudoku_copy.check()
                                #sudoku_copy.one_level_supposition()
                                sudoku_copy.check(level=2)
                            except AssertionError, e :
                                #Leads to an error :)
                                #This means that this square cannot be x
                                #print e
                                #print "%s cannot be %i" % (str(self.squares[row][col]), x)
                                bad_x.append(x)
                            del sudoku_copy
                            #print "\-- End of exp"
                        if len(bad_x) == 0 :
                            pass
                        elif len(bad_x) < len(self.squares[row][col]) :
                            for x in bad_x :
                                self.cell_exclude(row,col,x)
                                self.check() 
                            progress=True
                        else :
                            assert False, "Bugger! All possible values for square (%i,%i) fail" \
                            % (row,col)
        #print "Two level supposition done"

if __name__ == "__main__" and RUN_BUILT_IN_TESTS :
    print "Running built in tests..."
    
    tests = []
    
    tests.append(
       ("Easy example from Warwick The Magazine",
       ['081074900', '004019307', '379085014', '007831000', '238456179', '006927400', '843562791', '762198543', '005743862'],
       ['681374925', '524619387', '379285614', '497831256', '238456179', '156927438', '843562791', '762198543', '915743862'],
       None,
       None,
       None))
    tests.append(
       ("Easy example from http://www.sudoku.com/",
       ['060104050', '008305600', '200609001', '800437006', '006852300', '700961004', '500703002', '007206900', '642598173'],
       ['963174258', '178325649', '254689731', '821437596', '496852317', '735961824', '589713462', '317246985', '642598173'],
       None,
       None,
       None))
    tests.append(
       ("Novemeber 2005 contest from http://www.sudoku.com/",
       ['000342000', '540070080', '002005406', '060200000', '308000204', '000008070', '609120500', '030080019', '000539000'],
       ['816342957', '543976182', '792815436', '467253891', '358791264', '921468375', '689127543', '235684719', '174539628'],
       None,
       None,
       None))
    tests.append(
       ("No. One from http://sudokublog.typepad.com/sudokublog/2005/08/two_and_three_i.html",
       ['000538400', '800007000', '437962851', '900605340', '700803005', '053004009', '004759160', '000001003', '001386000'],
       ['219538476', '865147932', '437962851', '982615347', '746893215', '153274689', '324759168', '678421593', '591386724'],
       None,
       None,
       None))
    tests.append(
       ("No. Two from http://sudokublog.typepad.com/sudokublog/2005/08/two_and_three_i.html",
       ['000004000', '000027486', '400803050', '009278300', '700030009', '003469800', '030702008', '248350000', '000900000'],
       ['800604000', '391527486', '400803050', '009278300', '784135009', '023469800', '930742008', '248350000', '000980000'],
       ['800604000', '391527486', '400803050', '009278300', '784135009', '023469800', '930742008', '248351007', '000986000'],
       ['852614793', '391527486', '467893152', '619278345', '784135629', '523469871', '936742518', '248351967', '175986234'],
       None))
    tests.append(
       ("No. Three from http://sudokublog.typepad.com/sudokublog/2005/08/two_and_three_i.html",
       ['508073190', '901600408', '000908035', '070000060', '002000900', '010000080', '190306000', '203007009', '687190304'],
       ['528473196', '931600478', '700918235', '070000560', '002700940', '010000780', '190306807', '203007619', '687190304'],
       ['528473196', '931600478', '700918235', '070000560', '002700940', '010000780', '190306807', '203007619', '687190304'],
       ['528473196', '931625478', '764918235', '379284561', '852761943', '416539782', '195346827', '243857619', '687192354'],
       None))
    tests.append(
       ("X-wings from http://sudokublog.typepad.com/sudokublog/2005/08/xwings.html",
       ['096047080', '000006000', '274108003', '560081207', '007002800', '428079031', '642813759', '000964328', '080725416'],
       ['196347582', '835296174', '274158963', '563481297', '917632845', '428579631', '642813759', '751964328', '389725416'],
       None,
       None,
       None))
    tests.append(
       ("http://blogs.sun.com/roller/page/danrice?entry=wednesday_sudoku_puzzle",
       ['006008070', '100600400', '004210003', '001080090', '260030184', '080060300', '600045700', '005001006', '010900500'],
       ['006408071', '170603400', '004217063', '001780690', '267539184', '089160307', '600045710', '005001006', '010906500'],
       ['006458071', '170693400', '004217063', '001780690', '267539184', '089160307', '600045710', '005001006', '010906500'],
       ['936458271', '172693458', '854217963', '341782695', '267539184', '589164327', '623845719', '795321846', '418976532'],
       None))
    tests.append(
       ("Hard or even impossible from http://langabi.name/blog/2005/07/15/soduku-solver",
       ['000010700', '000030005', '000890000', '320000500', '006000200', '008000090', '000020000', '900070001', '001460070'],
       ['000010700', '000030005', '000890000', '320000500', '006000200', '008000090', '000020000', '900070001', '001460070'],
       ['000010700', '000030005', '000890000', '320000500', '006000200', '008000090', '000020000', '900070001', '001460070'],
       None,
       None)) #Don't try second level supposition - it takes forever and may not work
    tests.append(
       ("Interlocking Triples Zero from http://sudokublog.typepad.com/sudokublog/2005/08/interlocking_tr.html",
       ['006809010', '000003600', '003207085', '290371000', '350624079', '000985032', '180006300', '005008000', '030702500'],
       ['506849013', '800153600', '013267085', '290371056', '350624079', '000985032', '180596300', '005438001', '030712508'],
       ['526849713', '879153624', '413267985', '298371456', '351624879', '647985132', '182596347', '765438291', '934712568'],
       None,
       None))
    tests.append(
       ("Interlocking Triples One from http://sudokublog.typepad.com/sudokublog/2005/08/interlocking_tr.html",
       ['051003040', '006051038', '380700520', '018000005', '000010000', '500000410', '067004153', '143675289', '020100674'],
       ['051003046', '006051038', '380700521', '018000305', '030510800', '500300410', '067004153', '143675289', '025130674'],
       ['051003046', '006051038', '380700521', '018000305', '030510800', '500300410', '067004153', '143675289', '025130674'],
       ['251983746', '476251938', '389746521', '718492365', '634517892', '592368417', '967824153', '143675289', '825139674'],
       None))
    tests.append(
       ("Interlocking Triples Two from http://sudokublog.typepad.com/sudokublog/2005/08/interlocking_tr.html",
       ['500830027', '700600100', '308004006', '180000002', '430070019', '900000074', '600100708', '804007001', '270086000'],
       ['500830427', '740600183', '308704006', '187000002', '430070019', '900000074', '603100708', '804307261', '271086005'],
       ['500830427', '740600183', '308704006', '187000002', '430070019', '900000074', '603100708', '804307261', '271086005'],
       ['569831427', '742695183', '318724956', '187469532', '435278619', '926513874', '653142798', '894357261', '271986345'],
       None))
    tests.append(
       ("A 'very hard Sudoku' from http://www.saidwhat.co.uk/sudokus/index.php",
       ['100802030', '700000020', '000560070', '008000900', '005217403', '004000700', '030089000', '020000008', '080004006'],
       ['159872634', '763001825', '842563179', '278000901', '695217483', '314008702', '030089207', '020000008', '080024006'],
       ['159872634', '763941825', '842563179', '278435961', '695217483', '314698752', '536189247', '421756398', '987324516'],
       None,
       None))
    tests.append(
       ("A 'Fiendish Sudoku' from http://www.saidwhat.co.uk/sudokus/index.php",
       ['030000014', '200500680', '900300000', '050010030', '080030070', '060020090', '000008002', '003004001', '570000000'],
       ['635782914', '247591683', '918346527', '752619438', '189435276', '364827195', '496178352', '823954761', '571263849'],
       None,
       None,
       None))
    tests.append(
       ("Angus Johnson",
       ['040300070', '800061000', '000087003', '006040010', '420010095', '010050600', '700630000', '000570001', '050004060'],
       ['140305876', '800061000', '000087103', '506040010', '420016095', '010050600', '701630000', '004570001', '050104060'],
       ['140305876', '800061000', '000087103', '506040010', '420016095', '010050600', '701630000', '004570001', '050104060'],
       ['149325876', '873461529', '265987143', '536849217', '428716395', '917253684', '791638452', '684572931', '352194768'],
       None))
    tests.append(
       ("http://sudoku.com/forums/viewtopic.php?t=1057",
       ['681735942', '592841637', '700000581', '006080203', '000000100', '009050470', '300000769', '917563824', '268479315'],
       ['681735942', '592841637', '700000581', '006080203', '000000100', '009050470', '300218769', '917563824', '268479315'],
       ['681735942', '592841637', '700000581', '006080203', '000000100', '009050470', '300218769', '917563824', '268479315'],
       ['681735942', '592841637', '734692581', '456187293', '873924156', '129356478', '345218769', '917563824', '268479315'],
       None))
    tests.append(
       ("Gallery: really tough puzzles, no 142. from http://www.paulspages.co.uk/sudoku/",
       ['850100000', '900000080', '600004003', '700000002', '308500100', '400090006', '200700004', '530000001', '100002070'],
       ['853169427', '914273685', '672854913', '795641832', '368527149', '421398756', '289715364', '537486291', '146932578'],
       None,
       None,
       None))
    tests.append(
       ("Gallery: outlaw puzzles, no 129. from http://www.paulspages.co.uk/sudoku/",
       ['900002600', '004000005', '007001000', '035080900', '600000004', '001007020', '000300800', '500000700', '002600001'],
       ['900002600', '004000005', '007001000', '035080900', '600000004', '001007020', '000300800', '500000700', '002600001'],
       ['900002600', '004000005', '007001000', '035080900', '600000004', '001007020', '000300800', '500000700', '002600001'],
       ['953742618', '124896375', '867531249', '235184967', '679253184', '481967523', '746315892', '518429736', '392678451'],
       None))
    tests.append(
       ("Gallery: outlaw puzzles, no 112. from http://www.paulspages.co.uk/sudoku/",
       ['800000600', '040500100', '070090000', '030020007', '600008004', '500000090', '000030020', '001006050', '004000003'],
       ['800000600', '040500100', '170090000', '430020007', '600008004', '500000090', '000030020', '301006050', '004000003'],
       ['800000600', '040500100', '170090000', '430020007', '600008004', '500000090', '000030020', '301006058', '004000003'],
       ['852314679', '943567182', '176892345', '438129567', '619758234', '527643891', '785431926', '391276458', '264985713'],
       None))
    tests.append(
       ("19-cell '#1' from Brain of Britain, http://sudoku.sourceforge.net/brain.htm#3x3",
       ['000040030', '980601000', '000000200', '000000001', '004050700', '600000000', '005000000', '000908076', '070030000'],
       ['000040030', '983621457', '000000200', '000000001', '004050700', '600000005', '005000000', '002918576', '070030000'],
       ['000040030', '983621457', '000000200', '000000001', '004050700', '600000005', '005000000', '002918576', '070030000'],
       ['267549138', '983621457', '541783269', '758392641', '314856792', '629174385', '195467823', '432918576', '876235914'],
       None))
    tests.append(
       ("19-cell '#4' - Hardest 3x3 ever - from Brain of Britain, http://sudoku.sourceforge.net/brain.htm#3x3",
       ['020000000', '000600003', '074080000', '000003002', '080040010', '600500000', '000010780', '500009000', '000000040'],
       ['026000000', '000600003', '074080000', '000003002', '080040010', '600500000', '000010780', '500009000', '000000040'],
       ['026000000', '000600003', '074080000', '000003002', '080040010', '600500000', '000010780', '500009000', '000000040'],
       ['126437958', '895621473', '374985126', '457193862', '983246517', '612578394', '269314785', '548769231', '731852649'],
       None))
    tests.append(
       ("Hard from Arjen Lentz for MySQL, http://forums.mysql.com/read.php?98,51406",
       #['043080250',  '600000000', '000001094', '900004070', '000608000', '010200003', '820500000', '000000005', '034090710'],
       ['043080250', '600000000', '000001094', '900004070', '000608000', '010200003', '820500000', '000000005', '534890710'],
       ['043980250', '600425000', '200001094', '900004070', '300608000', '410209003', '820500000', '000000005', '534890710'],
       ['043980250', '600425000', '200001094', '900004070', '300608000', '410209003', '820500000', '000000005', '534890710'],
       ['143986257', '679425381', '285731694', '962354178', '357618942', '418279563', '821567439', '796143825', '534892716'],
       None))
    tests.append(
       ("Ambiguous from Arjen Lentz for MySQL, http://forums.mysql.com/read.php?98,51406",
       #['043080250', '600000000', '000001094', '900004070', '000608000', '010200003', '020500000', '000000005', '034090710'],
       ['043080250', '600000000', '000001094', '900004070', '000608000', '010200003', '020500000', '000000005', '534890710'],
       ['043980250', '600425000', '200001094', '900004070', '300608000', '410209003', '020500000', '000000005', '534890710'],
       ['043980250', '600425000', '200001094', '900004070', '300608000', '410209003', '020500000', '000000005', '534890710'],
       ['043986250', '600425000', '200731694', '900304070', '300608040', '410209063', '020500000', '000100025', '534892716'],
       None))
    tests.append(
        ("top95 = 48.3............71.2.......7.5....6....2..8.............1.76...3.....4......5....",
        ['480300000','000000071','020000000','705000060','000200800','000000000','001076000','300000400','000050000'],
        ['480300000','000000071','120000000','705000060','000200800','000000000','001076000','300000400','000053000'],
        ['480300000','000000071','120000000','705000060','000200800','000000000','001076000','300000400','000053000'],
        ['487312695','593684271','126597384','735849162','914265837','268731549','851476923','379128456','642953718'],
        None))

    for test in tests :
        name = test[0]
        print "Running test: " + name

        x = sudoku(test[1])

        assert x.as_test_list() == test[1], "Load failed"
        
        x.check()
        assert x.as_test_list() == test[2], "Simple check failed"

        if test[3] is not None and not x.solved() :
            if test[3] <> test[2]: print "Overlapping (aka slicing and dicing) should helps"
            x.overlapping_3x3_and_row_or_col()
            #x.check()
            assert x.as_test_list() == test[3], "Overlapping failed"
        
        if test[4] is not None and not x.solved() :
            if test[4] <> test[3]: print "One level supposition helps"
            x.one_level_supposition()
            #x.check()
            assert x.as_test_list() == test[4], "One level supposition failed"

        if test[5] is not None and not x.solved() :
            if test[5] <> test[4]: print "Two level supposition helps"
            x.two_level_supposition()
            #x.check()
            assert x.as_test_list() == test[5], "Two level supposition failed"
    print "Builtin tests passed"
    
if __name__ == "__main__" and RUN_TEST_FILES :
    print "Running test files"
    #Using only check() and one_level_suposition(), completes 82 out of 95 in this test file, http://magictour.free.fr/top95
    import os
    import time
    for test_file in ["top95.txt","top91.txt","top100.txt","msk_009.txt","top870.txt"] :
        if not os.path.isfile(test_file) :
            #Try without the extension...
            test_file = test_file[:-4]
        if os.path.isfile(test_file) :
            print "Running tests from file %s" % test_file
            input_file = open(test_file, "r")
            score = 0
            count = 0
            start_time = time.time()
            while True :
                line = input_file.readline()
                if not line : 
                    break
                if len(line)==0 :
                    break
                if line[-1] == "\n" :
                    line = line[:-1]
                if line[-1] =="\r" :
                    line = line[:-1]
                if len(line)==81 :
                    count=count+1
                    print "%i - [%s]" % (count, line),
                    x = sudoku(line)
                    x.check(level=2)
                    #x.overlapping_3x3_and_row_or_col()
                    #x.check()
                    #x.one_level_supposition()
                    #x.check()
                    if not x.solved() :
                        print "Trying level two",
                        #x.two_level_supposition()
                        x.check(level=3)
                    if x.solved() :
                        print " - Done"
                        score=score+1
                    else :
                        print "- Failed"
                        print x.as_test_list()
                else :
                    print "Bad line:\n%s" % line
            job_time = time.time()-start_time
            input_file.close()
            print "Score %i / %i in %0.2f seconds" % (score,count,job_time)
        else :
            print "Could not find test file " + test_file
    
if __name__ == "__main__" :
    print "Running demonstration..."
    
    t = sudoku(["800500930",
                   "050000000",
                   "000200100",
                   "007020000",
                   "600190008",
                   "400300069",
                   "000000450",
                   "104080000",
                   "000406007"])
                   
    print "Before:"
    #print t.as_test_list()
    print t

    print "Check:"
    t.check()
    print t

    print "overlapping_3x3_and_row_or_col:"
    t.check(level=1)
    print t

    print "supposition:"
    t.check(level=2)
    #print t.as_test_list()
    print t

                

/**
 * Löse Sudoku rekursiv.
 * 
 * @author Philipp Gressly (phi AT gressly DOT ch)
 * Dez. 2010.
 */
public class Sudoku {
    public static void main(String[] args) {
        new Sudoku().top();
    }

    // Die Datenstruktur Sudoku ist in der Lage,
    // ein ungelöstes oder auch ein bereits gelöstes
    // Sudoku-Feld zu speichern.
    // 0-Einträge bezeichnen noch leere Felder.
    int[][] feld = { 
            { 0, 8, 1, 0, 0, 0, 7, 3, 0 },
            { 9, 0, 0, 2, 0, 8, 0, 0, 4 },
            { 6, 0, 0, 0, 0, 0, 0, 0, 8 },
            { 0, 3, 0, 7, 0, 1, 0, 2, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 9, 0, 5, 0, 2, 0, 1, 0 },
            { 8, 0, 0, 0, 0, 0, 0, 0, 7 },
            { 7, 0, 0, 3, 0, 6, 0, 0, 1 },
            { 0, 4, 5, 0, 0, 0, 6, 9, 0 } };

    void top() {
        loeseSudoku(this);
    }

    // Algorithmus aus "www.programmieraufgaben.ch"
    void loeseSudoku(Sudoku s) {
        // Abbruch:
        if (unloesbar(s)) {
            return;
        }
        if (geloest(s)) {
            printLoesung(s);
            System.exit(0);
        }
        // Rekursionsschritt:
        int zeile = sucheErsteZeileMitLeereintraegen(s);
        int unbenutzteZahl = sucheZahlDieAufZeileNichtVorkommt(s, zeile);
        Sudoku[] sudokus = erzeugeSudokus(s, zeile, unbenutzteZahl);

        for (Sudoku temp : sudokus) {
            loeseSudoku(temp);
        }
    }

    Sudoku[] erzeugeSudokus(Sudoku s, int zeile, int unbenutzteZahl) {
        int nullerAnzahl = anzahlNullerAufZeile(s, zeile);
        Sudoku[] sudokus = new Sudoku[nullerAnzahl];
        int i = 0;
        while (i < nullerAnzahl) {
            sudokus[i] = neuesSudoku(s, zeile, unbenutzteZahl, i);
            i = i + 1;
        }
        return sudokus;
    }
  /**
   * @param pos bezeichnet die Null, die durch die
   *        "unbenutzteZahl" ersetzt werden muss.
   *        Dabei handelt es sich nicht um die Spaltenposition, sondern
   *        um das Auftreten der 0.
   *        Kommt die Null z. B. an den stellen 0, 3, 4 und 7 vor,
   *        so ist pos = 0, 1, 2, oder 3 und bezeichnet Spalte 0, 3, 4 bzw. 7.
   */
    Sudoku neuesSudoku(Sudoku s, int zeile, int unbenutzteZahl, int pos) {
        Sudoku sud = new Sudoku();
        sud.feld = kopiere(s.feld);
        int nr = -1;
        int spalte = 0;
        while (spalte < 9) {
            if (0 == sud.feld[zeile][spalte]) {
                nr = nr + 1;
                if (nr == pos) {
                    sud.feld[zeile][spalte] = unbenutzteZahl;
                    return sud;
                }
            }
            spalte = spalte + 1;
        }
        System.out.println("Fehler in pos: sud!");
        System.exit(1);
        return sud;
    }

    int[][] kopiere(int[][] f) {
        int[][] kopie = new int[9][9];
        int zeile, spalte;
        zeile = 0;
        while (zeile < 9) {
            spalte = 0;
            while (spalte < 9) {
                kopie[zeile][spalte] = f[zeile][spalte];
                spalte = spalte + 1;
            }
            zeile = zeile + 1;
        }
        return kopie;
    }

    int anzahlNullerAufZeile(Sudoku s, int zeile) {
        int anz = 0;
        int spalte = 0;
        while (spalte < 9) {
            if (0 == s.feld[zeile][spalte]) {
                anz = anz + 1;
            }
            spalte = spalte + 1;
        }
        return anz;
    }

    int sucheZahlDieAufZeileNichtVorkommt(Sudoku s, int zeile) {
        int zahl = 1;
        while (zahl <= 9) {
            int spalte = 0;
            boolean kommtVor = false;
            while (spalte < 9) {
                if (zahl == s.feld[zeile][spalte]) {
                    kommtVor = true;
                }
                spalte = spalte + 1;
            }
            if (!kommtVor) {
                return zahl;
            }
            zahl = zahl + 1;
        }
        return 10; // kommt nie vor!
    }

    int sucheErsteZeileMitLeereintraegen(Sudoku s) {
        int zeile = 0;
        while (zeile < 9) {
            int spalte = 0;
            while (spalte < 9) {
                if (0 == s.feld[zeile][spalte]) {
                    return zeile;
                }
                spalte = spalte + 1;
            }
            zeile = zeile + 1;
        }
        System.out.println("Fehler -1!!");
        return -1; //kommt nur vor, wenn unlösbar!
    }

    void printLoesung(Sudoku s) {
        int x = 0;
        while (x < 9) {
            int y = 0;
            while (y < 9) {
                System.out.print(""+ s.feld[x][y] + ' ');
                y = y + 1;
            }
            System.out.println();
            x = x + 1;
        }
    }

    /**
     * Keine 0 kommt mehr vor
     * 
     */
    boolean geloest(Sudoku s) {
        int x = 0;
        while (x < 9) {
            int y = 0;
            while (y < 9) {
                if (0 == s.feld[x][y]) {
                    return false;
                }
                y = y + 1;
            }
            x = x + 1;
        }
        return true;
    }

    boolean unloesbar(Sudoku s) {
        int i = 0;
        while (i < 9) {
            if (unloesbarWegenZeile(s, i)) {
                return true;
            }
            if (unloesbarWegenSpalte(s, i)) {
                return true;
            }
            if (unloesbarWegenBlock(s, i)) {
                return true;
            }
            i = i + 1;
        }
        return false;
    }

    boolean unloesbarWegenZeile(Sudoku s, int i) {
        int zahl = 1;
        while (zahl <= 9) {
            int vorkommen = 0;
            int pos = 0;
            while (pos < 9) {
                if (s.feld[i][pos] == zahl) {
                    vorkommen = vorkommen + 1;
                }
                pos = pos + 1;
            }
            if (vorkommen > 1) {
                return true;
            }
            zahl = zahl + 1;
        }
        return false;
    }

    boolean unloesbarWegenBlock(Sudoku s, int i) {
        int zahl = 1;
        while (zahl <= 9) {
            int vorkommen = 0;
            int posX = (i / 3) * 3; // int 0, 3 oder 6
            int posY = 3 * (i % 3); // int 0, 3 oder 6
            int x = 0;
            while (x < 3) {
                int y = 0;
                while (y < 3) {
                    if (s.feld[posY + y][posX + x] == zahl) {
                        vorkommen = vorkommen + 1;
                    }
                    y = y + 1;
                }
                x = x + 1;
            }
            if (vorkommen > 1) {
                return true;
            }
            zahl = zahl + 1;
        }
        return false;
    }

    boolean unloesbarWegenSpalte(Sudoku s, int i) {
        int zahl = 1;
        while (zahl <= 9) {
            int vorkommen = 0;
            int pos = 0;
            while (pos < 9) {
                if (s.feld[pos][i] == zahl) {
                    vorkommen = vorkommen + 1;
                }
                pos = pos + 1;
            }
            if (vorkommen > 1) {
                return true;
            }
            zahl = zahl + 1;
        }
        return false;
    }

} // end of class Sudoku
                
namespace SudokuLoesen
{
    class Program
    {
        static int[,] feld = new int[9, 9];
        static void Main(string[] args)
        {
            einlesen();
            if (ausfuellen(0))
            {
                Console.WriteLine("Fertig");
                ausgeben();
            }
            else Console.WriteLine("Keine Lösung gefunden");
            Console.ReadLine();
        }
        static void einlesen()
        {
            string sstring;
            int a = 0;
            Console.WriteLine("Geben Sie das Sudoku zeilenweise ein.\nLeerstellen mit Nullen füllen.");
            do
            {
                Console.Write((a + 1) + ". Zeile");
                sstring = Console.ReadLine();
                if (sstring.Length == 9)
                {
                    for (int b = 0; b < 9; b++)
                        feld[a, b] = Convert.ToByte(sstring.Substring(b, 1));
                    a += 1;
                }
                else
                    Console.WriteLine("Neun Zahlen pro Zeile");
            }
            while (a<9);
        }
        static bool ausfuellen(int zaehler2)
        {
            int zaehler=1;
            if (zaehler2 == 81)
                return true;
            else
            {
                if (feld[zaehler2 / 9, zaehler2 % 9] != 0)
                {
                    if (ausfuellen(zaehler2 + 1))
                        return true;
                    else return false;
                }
                else
                {
                    do
                    {
                        feld[zaehler2 / 9, zaehler2 % 9] = zaehler;
                        if (pruefen(zaehler, (zaehler2 / 9),( zaehler2 % 9)) == true)
                            if (ausfuellen(zaehler2 + 1) == true)
                                return true;
                            else zaehler += 1;                            
                        else  zaehler += 1; 
                    }
                    while (zaehler < 10);
                    feld[zaehler2 / 9, zaehler2 % 9] = 0;
                    return false;
                }
            }
        }
        static bool pruefen(int wert, int zind, int spind)
        {
            for (int count = 0; count < 9; count++)
            {
                if (count == spind)
                    continue;
                if (feld[zind, count] == wert)
                    return false;
            }
            for (int count = 0; count < 9; count++)
            {
                if (count == zind)
                    continue;
                if (feld[count, spind] == wert)
                    return false;
            }
            for (int z1=(zind/3)* 3; z1 < ((zind/3) * 3 + 3); z1++)
            {
                if (z1 == zind)
                    continue;
                for(int z2=(spind/3)*3;z2<((spind/3)*3+3);z2++)
                {
                    if (z2==spind)
                        continue;
                    if (feld[z1, z2] == wert)
                        return false;
                }
            }
            return true;
        }
        static void ausgeben()
        {
            for(byte a=0;a<9;a++)
            {
                Console.WriteLine();
                for(byte b=0;b<9;b++)
                    Console.Write(feld[a,b]+" ");
            }

        }
    }
}
                

Lösung von: Name nicht veröffentlicht

// Autor:				Andy Großhennig
// Solution for task:	Sudoku (Rekursion)
#include <iostream>
#include <Windows.h>
#include <vector>
#include <string>
#include <cstdlib>

using namespace std;

// Function: Show the sudoku on the console
void showSudoku(short sh_arrSudoku[9][9])
{
	system("cls");

	COORD cur={0,0};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cur);

	printf("X  1   2   3   4   5   6   7   8   9\nY\n\n");

	// Loop: Go through the sudoku
	for(short shAxisY = 0;shAxisY < 9;shAxisY++)
	{
		printf("%i ", (shAxisY + 1));

		for(short shAxisX = 0;shAxisX < 9;shAxisX++)
		{
			if(shAxisX == 2 || shAxisX == 5)
				if(sh_arrSudoku[shAxisY][shAxisX] != 0)
					printf(" %i |", sh_arrSudoku[shAxisY][shAxisX]);
				else
					printf("   |");
			else
				if(sh_arrSudoku[shAxisY][shAxisX] != 0)
					printf(" %i  ", sh_arrSudoku[shAxisY][shAxisX]);
				else
					printf("    ");
		}
		if(shAxisY < 8)
		{
			if(shAxisY == 2 || shAxisY == 5)
				printf("\n   ----------|-----------|----------\n");
			else
				printf("\n             |           |\n");
		}
	}
}

// Function: Calculate free lines
inline void fillSquares(short sh_arrSudokuFinish[9][9], short *sh_pAxisY, short *sh_pAxisX, short shSquare, short shNumber, bool *bSudokuSuccessfully)
{
	srand(GetTickCount());
	vector<short>sh_vecFreeFields; //Vector for remaining free fields in a square
	short shField; //Random field from the vector

	// Switch: Calculate free field accordingly of the rules of sudoku
	switch(shSquare)
	{
		case 1:	for(short shAxisY = 0;shAxisY < 3;shAxisY++)
				{
					for(short shAxisX = 0;shAxisX < 3;shAxisX++)
					{
						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0) //Check whether the field is empty
						{
							switch(shAxisY)
							{
								case 0:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 1:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 2:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 2:	for(short shAxisY = 0;shAxisY < 3;shAxisY++)
				{
					for(short shAxisX = 3;shAxisX < 6;shAxisX++)
					{
						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 0:	if(sh_arrSudokuFinish[0][0] == shNumber || sh_arrSudokuFinish[0][1] == shNumber  || sh_arrSudokuFinish[0][2] == shNumber)
										continue;
									break;
							case 1:	if(sh_arrSudokuFinish[1][0] == shNumber || sh_arrSudokuFinish[1][1] == shNumber || sh_arrSudokuFinish[1][2] == shNumber)
										continue;
									break;
							case 2:	if(sh_arrSudokuFinish[2][0] == shNumber || sh_arrSudokuFinish[2][1] == shNumber || sh_arrSudokuFinish[2][2] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 0:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 1:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 2:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 3:	for(short shAxisY = 0;shAxisY < 3;shAxisY++)
				{
					for(short shAxisX = 6;shAxisX < 9;shAxisX++)
					{
						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 0:	if(sh_arrSudokuFinish[0][0] == shNumber || sh_arrSudokuFinish[0][1] == shNumber || sh_arrSudokuFinish[0][2] == shNumber || sh_arrSudokuFinish[0][3] == shNumber || sh_arrSudokuFinish[0][4] == shNumber || sh_arrSudokuFinish[0][5] == shNumber)
										continue;
									break;
							case 1:	if(sh_arrSudokuFinish[1][0] == shNumber || sh_arrSudokuFinish[1][1] == shNumber || sh_arrSudokuFinish[1][2] == shNumber || sh_arrSudokuFinish[1][3] == shNumber || sh_arrSudokuFinish[1][4] == shNumber || sh_arrSudokuFinish[1][5] == shNumber)
										continue;
									break;
							case 2:	if(sh_arrSudokuFinish[2][0] == shNumber || sh_arrSudokuFinish[2][1] == shNumber || sh_arrSudokuFinish[2][2] == shNumber || sh_arrSudokuFinish[2][3] == shNumber || sh_arrSudokuFinish[2][4] == shNumber || sh_arrSudokuFinish[2][5] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 0:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										
										break;

								case 1:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
									
										break;

								case 2:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 4:	for(short shAxisY = 3;shAxisY < 6;shAxisY++)
				{
					for(short shAxisX = 0;shAxisX < 3;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 0:	if(sh_arrSudokuFinish[0][0] == shNumber || sh_arrSudokuFinish[1][0] == shNumber || sh_arrSudokuFinish[2][0] == shNumber)
										continue;
									break;
							case 1:	if(sh_arrSudokuFinish[0][1] == shNumber || sh_arrSudokuFinish[1][1] == shNumber || sh_arrSudokuFinish[2][1] == shNumber)
										continue;
									break;
							case 2:	if(sh_arrSudokuFinish[0][2] == shNumber || sh_arrSudokuFinish[1][2] == shNumber || sh_arrSudokuFinish[2][2] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 3:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);;
										break;

								case 4:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);;
										break;

								case 5:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 5:	for(short shAxisY = 3;shAxisY < 6;shAxisY++)
				{
					for(short shAxisX = 3;shAxisX < 6;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 3:	if(sh_arrSudokuFinish[0][3] == shNumber || sh_arrSudokuFinish[1][3] == shNumber || sh_arrSudokuFinish[2][3] == shNumber)
										continue;
									break;
							case 4:	if(sh_arrSudokuFinish[0][4] == shNumber || sh_arrSudokuFinish[1][4] == shNumber || sh_arrSudokuFinish[2][4] == shNumber)
										continue;
									break;
							case 5:	if(sh_arrSudokuFinish[0][5] == shNumber || sh_arrSudokuFinish[1][5] == shNumber || sh_arrSudokuFinish[2][5] == shNumber)
										continue;
						}

						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 3:	if(sh_arrSudokuFinish[3][0] == shNumber || sh_arrSudokuFinish[3][1] == shNumber  || sh_arrSudokuFinish[3][2] == shNumber)
										continue;
									break;
							case 4:	if(sh_arrSudokuFinish[4][0] == shNumber || sh_arrSudokuFinish[4][1] == shNumber  || sh_arrSudokuFinish[4][2] == shNumber)
										continue;
									break;
							case 5:	if(sh_arrSudokuFinish[5][0] == shNumber || sh_arrSudokuFinish[5][1] == shNumber  || sh_arrSudokuFinish[5][2] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 3:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 4:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 5:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 6:	for(short shAxisY = 3;shAxisY < 6;shAxisY++)
				{
					for(short shAxisX = 6;shAxisX < 9;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 6:	if(sh_arrSudokuFinish[0][6] == shNumber || sh_arrSudokuFinish[1][6] == shNumber || sh_arrSudokuFinish[2][6] == shNumber)
										continue;
									break;
							case 7:	if(sh_arrSudokuFinish[0][7] == shNumber || sh_arrSudokuFinish[1][7] == shNumber || sh_arrSudokuFinish[2][7] == shNumber)
										continue;
									break;
							case 8:	if(sh_arrSudokuFinish[0][8] == shNumber || sh_arrSudokuFinish[1][8] == shNumber || sh_arrSudokuFinish[2][8] == shNumber)
										continue;
						}

						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 3:	if(sh_arrSudokuFinish[3][0] == shNumber || sh_arrSudokuFinish[3][1] == shNumber || sh_arrSudokuFinish[3][2] == shNumber || sh_arrSudokuFinish[3][3] == shNumber || sh_arrSudokuFinish[3][4] == shNumber || sh_arrSudokuFinish[3][5] == shNumber)
										continue;
									break;
							case 4:	if(sh_arrSudokuFinish[4][0] == shNumber || sh_arrSudokuFinish[4][1] == shNumber || sh_arrSudokuFinish[4][2] == shNumber || sh_arrSudokuFinish[4][3] == shNumber || sh_arrSudokuFinish[4][4] == shNumber || sh_arrSudokuFinish[4][5] == shNumber)
										continue;
									break;
							case 5:	if(sh_arrSudokuFinish[5][0] == shNumber || sh_arrSudokuFinish[5][1] == shNumber || sh_arrSudokuFinish[5][2] == shNumber || sh_arrSudokuFinish[5][3] == shNumber || sh_arrSudokuFinish[5][4] == shNumber || sh_arrSudokuFinish[5][5] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 3:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 4:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 5:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 7:	for(short shAxisY = 6;shAxisY < 9;shAxisY++)
				{
					for(short shAxisX = 0;shAxisX < 3;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 0:	if(sh_arrSudokuFinish[0][0] == shNumber || sh_arrSudokuFinish[1][0] == shNumber || sh_arrSudokuFinish[2][0] == shNumber || sh_arrSudokuFinish[3][0] == shNumber || sh_arrSudokuFinish[4][0] == shNumber || sh_arrSudokuFinish[5][0] == shNumber)
										continue;
									break;
							case 1:	if(sh_arrSudokuFinish[0][1] == shNumber || sh_arrSudokuFinish[1][1] == shNumber || sh_arrSudokuFinish[2][1] == shNumber || sh_arrSudokuFinish[3][1] == shNumber || sh_arrSudokuFinish[4][1] == shNumber || sh_arrSudokuFinish[5][1] == shNumber)
										continue;
									break;
							case 2:	if(sh_arrSudokuFinish[0][2] == shNumber || sh_arrSudokuFinish[1][2] == shNumber || sh_arrSudokuFinish[2][2] == shNumber || sh_arrSudokuFinish[3][2] == shNumber || sh_arrSudokuFinish[4][2] == shNumber || sh_arrSudokuFinish[5][2] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 6:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 7:	if(shAxisX == 0)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 8: if(shAxisX == 0)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 1)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 8:	for(short shAxisY = 6;shAxisY < 9;shAxisY++)
				{
					for(short shAxisX = 3;shAxisX < 6;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 3:	if(sh_arrSudokuFinish[0][3] == shNumber || sh_arrSudokuFinish[1][3] == shNumber || sh_arrSudokuFinish[2][3] == shNumber || sh_arrSudokuFinish[3][3] == shNumber || sh_arrSudokuFinish[4][3] == shNumber || sh_arrSudokuFinish[5][3] == shNumber)
										continue;
									break;
							case 4:	if(sh_arrSudokuFinish[0][4] == shNumber || sh_arrSudokuFinish[1][4] == shNumber || sh_arrSudokuFinish[2][4] == shNumber || sh_arrSudokuFinish[3][4] == shNumber || sh_arrSudokuFinish[4][4] == shNumber || sh_arrSudokuFinish[5][4] == shNumber)
										continue;
									break;
							case 5:	if(sh_arrSudokuFinish[0][5] == shNumber || sh_arrSudokuFinish[1][5] == shNumber || sh_arrSudokuFinish[2][5] == shNumber || sh_arrSudokuFinish[3][5] == shNumber || sh_arrSudokuFinish[4][5] == shNumber || sh_arrSudokuFinish[5][5] == shNumber)
										continue;
						}

						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 6:	if(sh_arrSudokuFinish[6][0] == shNumber || sh_arrSudokuFinish[6][1] == shNumber  || sh_arrSudokuFinish[6][2] == shNumber)
										continue;
									break;
							case 7:	if(sh_arrSudokuFinish[7][0] == shNumber || sh_arrSudokuFinish[7][1] == shNumber  || sh_arrSudokuFinish[7][2] == shNumber)
										continue;
									break;
							case 8:	if(sh_arrSudokuFinish[8][0] == shNumber || sh_arrSudokuFinish[8][1] == shNumber  || sh_arrSudokuFinish[8][2] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 6:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 7:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 8:	if(shAxisX == 3)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 4)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
				break;

		case 9:	for(short shAxisY = 6;shAxisY < 9;shAxisY++)
				{
					for(short shAxisX = 6;shAxisX < 9;shAxisX++)
					{
						// Switch: Check the Y-Axis
						switch(shAxisX)
						{
							case 6:	if(sh_arrSudokuFinish[0][6] == shNumber || sh_arrSudokuFinish[1][6] == shNumber || sh_arrSudokuFinish[2][6] == shNumber || sh_arrSudokuFinish[3][6] == shNumber || sh_arrSudokuFinish[4][6] == shNumber || sh_arrSudokuFinish[5][6] == shNumber)
										continue;
									break;
							case 7:	if(sh_arrSudokuFinish[0][7] == shNumber || sh_arrSudokuFinish[1][7] == shNumber || sh_arrSudokuFinish[2][7] == shNumber || sh_arrSudokuFinish[3][7] == shNumber || sh_arrSudokuFinish[4][7] == shNumber || sh_arrSudokuFinish[5][7] == shNumber)
										continue;
									break;
							case 8:	if(sh_arrSudokuFinish[0][8] == shNumber || sh_arrSudokuFinish[1][8] == shNumber || sh_arrSudokuFinish[2][8] == shNumber || sh_arrSudokuFinish[3][8] == shNumber || sh_arrSudokuFinish[4][8] == shNumber || sh_arrSudokuFinish[5][8] == shNumber)
										continue;
						}

						// Switch: Check the X-Axis
						switch(shAxisY)
						{
							case 6:	if(sh_arrSudokuFinish[6][0] == shNumber || sh_arrSudokuFinish[6][1] == shNumber || sh_arrSudokuFinish[6][2] == shNumber || sh_arrSudokuFinish[6][3] == shNumber || sh_arrSudokuFinish[6][4] == shNumber || sh_arrSudokuFinish[6][5] == shNumber)
										continue;
									break;
							case 7:	if(sh_arrSudokuFinish[7][0] == shNumber || sh_arrSudokuFinish[7][1] == shNumber || sh_arrSudokuFinish[7][2] == shNumber || sh_arrSudokuFinish[7][3] == shNumber || sh_arrSudokuFinish[7][4] == shNumber || sh_arrSudokuFinish[7][5] == shNumber)
										continue;
									break;
							case 8:	if(sh_arrSudokuFinish[8][0] == shNumber || sh_arrSudokuFinish[8][1] == shNumber || sh_arrSudokuFinish[8][2] == shNumber || sh_arrSudokuFinish[8][3] == shNumber || sh_arrSudokuFinish[8][4] == shNumber || sh_arrSudokuFinish[8][5] == shNumber)
										continue;
						}

						if(sh_arrSudokuFinish[shAxisY][shAxisX] == 0)
						{
							switch(shAxisY)
							{
								case 6:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(1);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(2);
										else
											sh_vecFreeFields.push_back(3);
										;
										break;

								case 7:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(4);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(5);
										else
											sh_vecFreeFields.push_back(6);
										;
										break;

								case 8:	if(shAxisX == 6)
											sh_vecFreeFields.push_back(7);
										else if(shAxisX == 7)
											sh_vecFreeFields.push_back(8);
										else
											sh_vecFreeFields.push_back(9);
										;
										break;
							}
						}
						else
							continue;
					}
				};
	}

	if(sh_vecFreeFields.size() > 0)
		shField = sh_vecFreeFields.at(rand() % sh_vecFreeFields.size());
	else
	{
		*bSudokuSuccessfully = false;
		return;
	}
		
	// Switch: Choose a random field and calculate the coordinates
	switch(shSquare)
	{
		case 1: switch(shField)
				{
					case 1:	*sh_pAxisY = 0; *sh_pAxisX = 0;
							break;
					case 2: *sh_pAxisY = 0; *sh_pAxisX = 1;
							break;
					case 3: *sh_pAxisY = 0; *sh_pAxisX = 2;
							break;
					case 4: *sh_pAxisY = 1; *sh_pAxisX = 0;
							break;
					case 5:	*sh_pAxisY = 1; *sh_pAxisX = 1;
							break;
					case 6: *sh_pAxisY = 1; *sh_pAxisX = 2;
							break;
					case 7: *sh_pAxisY = 2; *sh_pAxisX = 0;
							break;
					case 8: *sh_pAxisY = 2; *sh_pAxisX = 1;
							break;
					case 9: *sh_pAxisY = 2; *sh_pAxisX = 2;
				};
				break;

		case 2:	switch(shField)
				{
					case 1:	*sh_pAxisY = 0; *sh_pAxisX = 3;
							break;
					case 2: *sh_pAxisY = 0; *sh_pAxisX = 4;
							break;
					case 3: *sh_pAxisY = 0; *sh_pAxisX = 5;
							break;
					case 4: *sh_pAxisY = 1; *sh_pAxisX = 3;
							break;
					case 5:	*sh_pAxisY = 1; *sh_pAxisX = 4;
							break;
					case 6: *sh_pAxisY = 1; *sh_pAxisX = 5;
							break;
					case 7: *sh_pAxisY = 2; *sh_pAxisX = 3;
							break;
					case 8: *sh_pAxisY = 2; *sh_pAxisX = 4;
							break;
					case 9: *sh_pAxisY = 2; *sh_pAxisX = 5;
				}
				break;

		case 3: switch(shField)
				{
					case 1:	*sh_pAxisY = 0; *sh_pAxisX = 6;
							break;
					case 2: *sh_pAxisY = 0; *sh_pAxisX = 7;
							break;
					case 3: *sh_pAxisY = 0; *sh_pAxisX = 8;
							break;
					case 4: *sh_pAxisY = 1; *sh_pAxisX = 6;
							break;
					case 5:	*sh_pAxisY = 1; *sh_pAxisX = 7;
							break;
					case 6: *sh_pAxisY = 1; *sh_pAxisX = 8;
							break;
					case 7: *sh_pAxisY = 2; *sh_pAxisX = 6;
							break;
					case 8: *sh_pAxisY = 2; *sh_pAxisX = 7;
							break;
					case 9: *sh_pAxisY = 2; *sh_pAxisX = 8;
				};
				break;

		case 4:	switch(shField)
				{
					case 1:	*sh_pAxisY = 3; *sh_pAxisX = 0;
							break;
					case 2: *sh_pAxisY = 3; *sh_pAxisX = 1;
							break;
					case 3: *sh_pAxisY = 3; *sh_pAxisX = 2;
							break;
					case 4: *sh_pAxisY = 4; *sh_pAxisX = 0;
							break;
					case 5:	*sh_pAxisY = 4; *sh_pAxisX = 1;
							break;
					case 6: *sh_pAxisY = 4; *sh_pAxisX = 2;
							break;
					case 7: *sh_pAxisY = 5; *sh_pAxisX = 0;
							break;
					case 8: *sh_pAxisY = 5; *sh_pAxisX = 1;
							break;
					case 9: *sh_pAxisY = 5; *sh_pAxisX = 2;
				};
				break;

		case 5:	switch(shField)
				{
					case 1:	*sh_pAxisY = 3; *sh_pAxisX = 3;
							break;
					case 2: *sh_pAxisY = 3; *sh_pAxisX = 4;
							break;
					case 3: *sh_pAxisY = 3; *sh_pAxisX = 5;
							break;
					case 4: *sh_pAxisY = 4; *sh_pAxisX = 3;
							break;
					case 5:	*sh_pAxisY = 4; *sh_pAxisX = 4;
							break;
					case 6: *sh_pAxisY = 4; *sh_pAxisX = 5;
							break;
					case 7: *sh_pAxisY = 5; *sh_pAxisX = 3;
							break;
					case 8: *sh_pAxisY = 5; *sh_pAxisX = 4;
							break;
					case 9: *sh_pAxisY = 5; *sh_pAxisX = 5;
				};
				break;

		case 6: switch(shField)
				{
					case 1:	*sh_pAxisY = 3; *sh_pAxisX = 6;
							break;
					case 2: *sh_pAxisY = 3; *sh_pAxisX = 7;
							break;
					case 3: *sh_pAxisY = 3; *sh_pAxisX = 8;
							break;
					case 4: *sh_pAxisY = 4; *sh_pAxisX = 6;
							break;
					case 5:	*sh_pAxisY = 4; *sh_pAxisX = 7;
							break;
					case 6: *sh_pAxisY = 4; *sh_pAxisX = 8;
							break;
					case 7: *sh_pAxisY = 5; *sh_pAxisX = 6;
							break;
					case 8: *sh_pAxisY = 5; *sh_pAxisX = 7;
							break;
					case 9: *sh_pAxisY = 5; *sh_pAxisX = 8;
				};
				break;

		case 7:	switch(shField)
				{
					case 1:	*sh_pAxisY = 6; *sh_pAxisX = 0;
							break;
					case 2: *sh_pAxisY = 6; *sh_pAxisX = 1;
							break;
					case 3: *sh_pAxisY = 6; *sh_pAxisX = 2;
							break;
					case 4: *sh_pAxisY = 7; *sh_pAxisX = 0;
							break;
					case 5:	*sh_pAxisY = 7; *sh_pAxisX = 1;
							break;
					case 6: *sh_pAxisY = 7; *sh_pAxisX = 2;
							break;
					case 7: *sh_pAxisY = 8; *sh_pAxisX = 0;
							break;
					case 8: *sh_pAxisY = 8; *sh_pAxisX = 1;
							break;
					case 9: *sh_pAxisY = 8; *sh_pAxisX = 2;
				};
				break;

		case 8:	switch(shField)
				{
					case 1:	*sh_pAxisY = 6; *sh_pAxisX = 3;
							break;
					case 2: *sh_pAxisY = 6; *sh_pAxisX = 4;
							break;
					case 3: *sh_pAxisY = 6; *sh_pAxisX = 5;
							break;
					case 4: *sh_pAxisY = 7; *sh_pAxisX = 3;
							break;
					case 5:	*sh_pAxisY = 7; *sh_pAxisX = 4;
							break;
					case 6: *sh_pAxisY = 7; *sh_pAxisX = 5;
							break;
					case 7: *sh_pAxisY = 8; *sh_pAxisX = 3;
							break;
					case 8: *sh_pAxisY = 8; *sh_pAxisX = 4;
							break;
					case 9: *sh_pAxisY = 8; *sh_pAxisX = 5;
				};
				break;

		case 9: switch(shField)
				{
					case 1:	*sh_pAxisY = 6; *sh_pAxisX = 6;
							break;
					case 2: *sh_pAxisY = 6; *sh_pAxisX = 7;
							break;
					case 3: *sh_pAxisY = 6; *sh_pAxisX = 8;
							break;
					case 4: *sh_pAxisY = 7; *sh_pAxisX = 6;
							break;
					case 5:	*sh_pAxisY = 7; *sh_pAxisX = 7;
							break;
					case 6: *sh_pAxisY = 7; *sh_pAxisX = 8;
							break;
					case 7: *sh_pAxisY = 8; *sh_pAxisX = 6;
							break;
					case 8: *sh_pAxisY = 8; *sh_pAxisX = 7;
							break;
					case 9: *sh_pAxisY = 8; *sh_pAxisX = 8;
				};
				break;
	}
}

// Function: Create a new finished sudoku
void createSudokuFinish(short sh_arrSudokuFinish[9][9], bool *bSudokuSuccessfully)
{
	short shAxisY;
	short shAxisX;
	bool bIsSudokuFinished = false;

	*bSudokuSuccessfully = true;

	// Loop: Go through the sudoku and set all positions to zero
	for(shAxisY = 0;shAxisY < 9;shAxisY++)
	{
		for(shAxisX = 0;shAxisX < 9;shAxisX++)
		{
			sh_arrSudokuFinish[shAxisY][shAxisX] = 0;
		}
		shAxisX = 0;
	}

	// Loop: Provide the numbers
	for(short shFirst = 1;shFirst < 10;shFirst++)
	{		
		// Loop: Counts the amount of every number and fill the sudoku
		for(short shSecond = 1;shSecond < 10;shSecond++)
		{
			fillSquares(sh_arrSudokuFinish, &shAxisY, &shAxisX, shSecond, shFirst, bSudokuSuccessfully);

			if(*bSudokuSuccessfully == false)
				return;
				
			sh_arrSudokuFinish[shAxisY][shAxisX] = shFirst;
		}
	}
}

// Function: Remove a lot of numbers and create the sudoku to solve
void createSudoku(short sh_arrSudokuFinish[9][9], short sh_arrSudoku[9][9])
{
	srand(GetTickCount());
	short shCount = 0, shAxisY, shAxisX;

	for(short shFirst = 0;shFirst < 9;shFirst++)
	{
		for(short shSecond = 0;shSecond < 9;shSecond++)
		{
			sh_arrSudoku[shFirst][shSecond] = sh_arrSudokuFinish[shFirst][shSecond];
		}
	}
	
	while(shCount <= 50)
	{
		shAxisY = rand() % 9;
		shAxisX = rand() % 9;

		if(sh_arrSudoku[shAxisY][shAxisX] != 0)
		{
			sh_arrSudoku[shAxisY][shAxisX] = 0;
			shCount++;
		}
	}
}

// Function: Get the coordinates and the number
void getInput(short sh_arrInput[3], short sh_arrSudoku[9][9], char *cChoice)
{
	printf("\n\nEingabe: e, Hilfe: h, Aufloesen: a. ");
	cin >> *cChoice;

	if(*cChoice == 'h' || *cChoice == 'a')
		return;

	do
	{
		printf("X (1-9): ");
		cin >> sh_arrInput[0];

		printf("Y (1-9): ");
		cin >> sh_arrInput[1];

		printf("Number (1-9): ");
		cin >> sh_arrInput[2];
	}
	while(sh_arrInput[0] <= 0  || sh_arrInput[0] >= 10 || sh_arrInput[1] <= 0 || sh_arrInput[1] >= 9 || sh_arrInput[2] <= 0 || sh_arrInput[2] >= 9 || sh_arrSudoku[(sh_arrInput[1] - 1)][(sh_arrInput[0] - 1)] != 0);
}

// Function: Solve a number or the sudoku
void help(short sh_arrSudoku[9][9], short sh_arrSudokuFinish[9][9], char cChoice)
{
	if(cChoice == 'h')
	{	
		for(short shAxisY = 0;shAxisY < 9;shAxisY++)
		{
			for(short shAxisX = 0;shAxisX < 9;shAxisX++)
			{
				if(sh_arrSudoku[shAxisY][shAxisX] == 0)
				{
					sh_arrSudoku[shAxisY][shAxisX] = sh_arrSudokuFinish[shAxisY][shAxisX];
					return;
				}
			}
		}
	}
	else
	{
		for(short shAxisY = 0;shAxisY < 9;shAxisY++)
		{
			for(short shAxisX = 0;shAxisX < 9;shAxisX++)
			{
				sh_arrSudoku[shAxisY][shAxisX] = sh_arrSudokuFinish[shAxisY][shAxisX];
			}
		}
	}
}

// Function: Solve the sudoku by player input
void play(short sh_arrSudoku[9][9], short sh_arrSudokuFinish[9][9])
{
	short sh_arrInput[3]; // 1: X, 2: Y, 3: Number
	sh_arrInput[0] = 0;
	sh_arrInput[1] = 0;
	sh_arrInput[2] = 0;
	char cChoice = ' ';

	getInput(sh_arrInput, sh_arrSudoku, &cChoice);

	if(cChoice == 'h' || cChoice == 'a')
		help(sh_arrSudoku, sh_arrSudokuFinish, cChoice);
	else
		sh_arrSudoku[sh_arrInput[1] - 1][sh_arrInput[0] - 1] = sh_arrInput[2];
}

// Function: Manage sudoku
void sudoku()
{
	COORD cur={0,0};

	short sh_arrSudokuFinish[9][9]; //Finished sudoku
	short sh_arrSudoku[9][9]; //Sudoku to solve
	bool bSudokuSuccessfully = false;
	int iAttemps = 0;

	// Loop: Create a finished sudoku
	while(bSudokuSuccessfully == false)
	{
		switch(iAttemps % 3)
		{
			case 3:	printf("|");
					break;
			case 2:	printf("/");
					break;
			case 1:	printf("-");
					break;
			case 0:	printf("\\");
		};

		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cur);
		createSudokuFinish(sh_arrSudokuFinish, &bSudokuSuccessfully);
		iAttemps++;
	}

	createSudoku(sh_arrSudokuFinish, sh_arrSudoku);

	while(true)
	{
		showSudoku(sh_arrSudoku);
		play(sh_arrSudoku, sh_arrSudokuFinish);
	}
}

int main()
{
	sudoku();
	
	printf("\n\n");
	system("Pause");
	return 0;
}
                

Lösung von: Andy Großhennig (Bundeswehr)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 4-8
Schwierigkeit: k.A.
Webcode: w29j-mrgu
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen