<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Gelöst]Backtracking und Sudoku]]></title><description><![CDATA[<p>Hallo. Ich wollte mich auch mal am Backtracking-Algorithmus und Sudoku versuchen.<br />
Leider laufe ich momentan in eine Sackgasse.</p>
<p>1. Ich vermute den Fehler in Zeile 80. Wenn der Algorithmus in eine Sackgasse läuft, muß er den Weg zurück einlegen. Ich glaube das habe ich nicht richtig gelöst.</p>
<p>2. Ich frage mich auch, warum sich das Programm einfach in der 2. Zeile (Ausgabe Zeile 18) aufhört. Es sollte ja eigentlich weiter die Werte suchen. Vermutlich hängt das mit 1. zusammen.</p>
<p>Ich hoffe jemand kann mir da weiter helfen.</p>
<p>Grüsse Eddi</p>
<p>Quelltext:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;

const std::size_t ROW = 9;
const std::size_t COL = 9;

class Field {
public:
	Field();
	void printField();
    void searchSolution(std::size_t y, std::size_t x);
	bool isColumnOk(std::size_t y, char number);
    bool isRowOk(std::size_t x, char number);
    bool isBlockOk(std::size_t y, std::size_t x, char number);
private:
    std::array&lt;std::array&lt;char, ROW&gt;, COL&gt; field;
};

Field::Field()
{
    field = {' ', ' ', ' ',/*|*/ ' ', '1', ' ',/*|*/ ' ', '6', ' ',
             '7', '3', '6',/*|*/ '2', '8', '5',/*|*/ ' ', '9', ' ',
             ' ', ' ', ' ',/*|*/ ' ', '4', '9',/*|*/ ' ', '3', ' ',
             /****************************************************/
             ' ', '1', '3',/*|*/ '8', ' ', '7',/*|*/ ' ', '4', ' ',
             '6', '7', '5',/*|*/ ' ', ' ', ' ',/*|*/ '9', '8', '3',
             ' ', '8', ' ',/*|*/ '5', ' ', '6',/*|*/ '1', '2', ' ',
             /****************************************************/
             ' ', '2', ' ',/*|*/ '9', '5', ' ',/*|*/ ' ', ' ', ' ',
             ' ', '6', ' ',/*|*/ '4', '7', '8',/*|*/ '3', '5', '2',
             ' ', '4', ' ',/*|*/ ' ', '6', ' ',/*|*/ ' ', ' ', ' '
            };
}

void Field::printField()
{
    for (std::size_t y = 0; y &lt; COL; ++y) {
		if (y % 3 == 0) {
			std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
		}
        for (std::size_t x = 0; x &lt; ROW; ++x) {
			if (x % 3 == 0) {
				std::cout &lt;&lt; &quot;|&quot;;
			}
			std::cout &lt;&lt; field[y][x];
		}
		std::cout &lt;&lt; &quot;|\n&quot;;
	}
    std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
}

void Field::searchSolution(std::size_t y, std::size_t x)
{
	//Abbruchkriterium
    if (y &gt; COL) {
        return;
    }
    //Nächste Zeile bestimmen
    std::size_t yNext, xNext;
	//Zeile noch nicht voll?
    if (x &lt; ROW - 1) {
        yNext = y; //Zeile bleibt gleich
        xNext = x + 1; //Spalte ein weiter
	} else {
        //Wenn Zeile voll, in erste Spalte eine Zeile tiefer
        yNext = y + 1; //Zeile ein &quot;tiefer&quot;
        xNext = 0; //Spalte zurück auf 0
	}	
	//Suchen 
	if (field[y][x] != ' ') { //Feld ist Vorbelegt
		searchSolution(yNext, xNext); //Dann beim nächsten Index weitersuchen
    } else { //sonst alle Zahlen probieren
        for (char number = '1'; number &lt;= '9'; ++number) {
            if (isColumnOk(y, number)
                    &amp;&amp; isRowOk(x, number)
                    &amp;&amp; isBlockOk(y, x, number)) {
				field[y][x] = number; //gefundene Zahl eintragen
				searchSolution(yNext, xNext); //weitersuchen
            } 
        } //irgendwie das bisherige rückgängig machen, falls es eine Sackgasse ist. Nur wie?
        //field[y][x] = ' ';
    }
}

bool Field::isColumnOk(std::size_t y, char number)
{
    for (std::size_t x = 0; x &lt; COL; ++x) {
		if (field[y][x] == number) {
			return false;
		}
	}
	return true;
}

bool Field::isRowOk(std::size_t x, char number)
{
    for (std::size_t y = 0; y &lt; ROW; ++y) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isBlockOk(std::size_t y, std::size_t x, char number)
{
    std::size_t col = (y / 3) * 3;
    std::size_t row = (x / 3) * 3;

    for (std::size_t i = col; i &lt; col + 3; ++i) {
        for (std::size_t j = row; j &lt; row + 3; ++j) {
            if (field[i][j] == number) {
                return false;
            }
        }
    }
    return true;
}

int main()
{
	Field field;
	field.printField();
    field.searchSolution(0, 0); //beginne oben links
	field.printField();
}
</code></pre>
<p>Und die Ausgabe dabei:</p>
<pre><code>Vorgabe:
+---+---+---+
|   | 1 | 6 |
|736|285| 9 |
|   | 49| 3 |
+---+---+---+
| 13|8 7| 4 |
|675|   |983|
| 8 |5 6|12 |
+---+---+---+
| 2 |95 |   |
| 6 |478|352|
| 4 | 6 |   |
+---+---+---+
Gelöst:
+---+---+---+
|259|713|864|
|736|285| 9 |
|   | 49| 3 |
+---+---+---+
| 13|8 7| 4 |
|675|   |983|
| 8 |5 6|12 |
+---+---+---+
| 2 |95 |   |
| 6 |478|352|
| 4 | 6 |   |
+---+---+---+
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/317411/gelöst-backtracking-und-sudoku</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Jul 2026 22:03:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/317411.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 07 Jun 2013 13:10:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 13:02:04 GMT]]></title><description><![CDATA[<p>Hallo. Ich wollte mich auch mal am Backtracking-Algorithmus und Sudoku versuchen.<br />
Leider laufe ich momentan in eine Sackgasse.</p>
<p>1. Ich vermute den Fehler in Zeile 80. Wenn der Algorithmus in eine Sackgasse läuft, muß er den Weg zurück einlegen. Ich glaube das habe ich nicht richtig gelöst.</p>
<p>2. Ich frage mich auch, warum sich das Programm einfach in der 2. Zeile (Ausgabe Zeile 18) aufhört. Es sollte ja eigentlich weiter die Werte suchen. Vermutlich hängt das mit 1. zusammen.</p>
<p>Ich hoffe jemand kann mir da weiter helfen.</p>
<p>Grüsse Eddi</p>
<p>Quelltext:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;

const std::size_t ROW = 9;
const std::size_t COL = 9;

class Field {
public:
	Field();
	void printField();
    void searchSolution(std::size_t y, std::size_t x);
	bool isColumnOk(std::size_t y, char number);
    bool isRowOk(std::size_t x, char number);
    bool isBlockOk(std::size_t y, std::size_t x, char number);
private:
    std::array&lt;std::array&lt;char, ROW&gt;, COL&gt; field;
};

Field::Field()
{
    field = {' ', ' ', ' ',/*|*/ ' ', '1', ' ',/*|*/ ' ', '6', ' ',
             '7', '3', '6',/*|*/ '2', '8', '5',/*|*/ ' ', '9', ' ',
             ' ', ' ', ' ',/*|*/ ' ', '4', '9',/*|*/ ' ', '3', ' ',
             /****************************************************/
             ' ', '1', '3',/*|*/ '8', ' ', '7',/*|*/ ' ', '4', ' ',
             '6', '7', '5',/*|*/ ' ', ' ', ' ',/*|*/ '9', '8', '3',
             ' ', '8', ' ',/*|*/ '5', ' ', '6',/*|*/ '1', '2', ' ',
             /****************************************************/
             ' ', '2', ' ',/*|*/ '9', '5', ' ',/*|*/ ' ', ' ', ' ',
             ' ', '6', ' ',/*|*/ '4', '7', '8',/*|*/ '3', '5', '2',
             ' ', '4', ' ',/*|*/ ' ', '6', ' ',/*|*/ ' ', ' ', ' '
            };
}

void Field::printField()
{
    for (std::size_t y = 0; y &lt; COL; ++y) {
		if (y % 3 == 0) {
			std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
		}
        for (std::size_t x = 0; x &lt; ROW; ++x) {
			if (x % 3 == 0) {
				std::cout &lt;&lt; &quot;|&quot;;
			}
			std::cout &lt;&lt; field[y][x];
		}
		std::cout &lt;&lt; &quot;|\n&quot;;
	}
    std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
}

void Field::searchSolution(std::size_t y, std::size_t x)
{
	//Abbruchkriterium
    if (y &gt; COL) {
        return;
    }
    //Nächste Zeile bestimmen
    std::size_t yNext, xNext;
	//Zeile noch nicht voll?
    if (x &lt; ROW - 1) {
        yNext = y; //Zeile bleibt gleich
        xNext = x + 1; //Spalte ein weiter
	} else {
        //Wenn Zeile voll, in erste Spalte eine Zeile tiefer
        yNext = y + 1; //Zeile ein &quot;tiefer&quot;
        xNext = 0; //Spalte zurück auf 0
	}	
	//Suchen 
	if (field[y][x] != ' ') { //Feld ist Vorbelegt
		searchSolution(yNext, xNext); //Dann beim nächsten Index weitersuchen
    } else { //sonst alle Zahlen probieren
        for (char number = '1'; number &lt;= '9'; ++number) {
            if (isColumnOk(y, number)
                    &amp;&amp; isRowOk(x, number)
                    &amp;&amp; isBlockOk(y, x, number)) {
				field[y][x] = number; //gefundene Zahl eintragen
				searchSolution(yNext, xNext); //weitersuchen
            } 
        } //irgendwie das bisherige rückgängig machen, falls es eine Sackgasse ist. Nur wie?
        //field[y][x] = ' ';
    }
}

bool Field::isColumnOk(std::size_t y, char number)
{
    for (std::size_t x = 0; x &lt; COL; ++x) {
		if (field[y][x] == number) {
			return false;
		}
	}
	return true;
}

bool Field::isRowOk(std::size_t x, char number)
{
    for (std::size_t y = 0; y &lt; ROW; ++y) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isBlockOk(std::size_t y, std::size_t x, char number)
{
    std::size_t col = (y / 3) * 3;
    std::size_t row = (x / 3) * 3;

    for (std::size_t i = col; i &lt; col + 3; ++i) {
        for (std::size_t j = row; j &lt; row + 3; ++j) {
            if (field[i][j] == number) {
                return false;
            }
        }
    }
    return true;
}

int main()
{
	Field field;
	field.printField();
    field.searchSolution(0, 0); //beginne oben links
	field.printField();
}
</code></pre>
<p>Und die Ausgabe dabei:</p>
<pre><code>Vorgabe:
+---+---+---+
|   | 1 | 6 |
|736|285| 9 |
|   | 49| 3 |
+---+---+---+
| 13|8 7| 4 |
|675|   |983|
| 8 |5 6|12 |
+---+---+---+
| 2 |95 |   |
| 6 |478|352|
| 4 | 6 |   |
+---+---+---+
Gelöst:
+---+---+---+
|259|713|864|
|736|285| 9 |
|   | 49| 3 |
+---+---+---+
| 13|8 7| 4 |
|675|   |983|
| 8 |5 6|12 |
+---+---+---+
| 2 |95 |   |
| 6 |478|352|
| 4 | 6 |   |
+---+---+---+
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2329233</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329233</guid><dc:creator><![CDATA[eddi0815]]></dc:creator><pubDate>Mon, 10 Jun 2013 13:02:04 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Fri, 07 Jun 2013 14:19:50 GMT]]></title><description><![CDATA[<p>Woran erkennst du denn, ob eine Lösung gefunden wurde oder nicht? Also insbesondere, woran erkennst du, dass du backtracken musst?</p>
<p>Ich hab zwar noch keinen Sudoku-Löser implementiert, aber wenn ich es per Backtracking machen würde, würde ich searchSolution einen bool-Rückgabewert verpassen: true falls Lösung gefunden, false falls Sackgasse. Dann läuft der Algorithmus ungefähr so:</p>
<pre><code>if (aktuelles feld nicht frei)
  return false;
for (zahl = 1 bis 9) {
  if (kann zahl ins aktuelle Feld eintragen ohne Konflikte)
     trage zahl ein
     erfolg = searchSolution(nächstes Feld)
     if (erfolg)
       // cool!
       return true; // oder vielleicht versuchen ob es weitere Lösungen gibt?
     else
       mache das aktuelle Feld wieder frei
       // Schleife weiter laufen lassen
}
// Schleife erfolglos durchlaufen?
return false;
</code></pre>
<p>Das wäre jedenfalls erstmal die Variante mit den wenigsten Abweichungen von deiner, man kann das natürlich alles auch ganz anders machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329256</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329256</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Fri, 07 Jun 2013 14:19:50 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Fri, 07 Jun 2013 15:12:56 GMT]]></title><description><![CDATA[<p>habe kürzlich auch einen sudokusolver mit backtracking gebastelt(siehe thread). der quellcode ist aber ziemlich lang, nicht sehr elegant und der ansatz auch nicht der gleiche. aber das programm funktioniert. wenn du interesse hast kann ich den code hier posten</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329271</guid><dc:creator><![CDATA[dwtoni]]></dc:creator><pubDate>Fri, 07 Jun 2013 15:12:56 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Fri, 07 Jun 2013 15:32:38 GMT]]></title><description><![CDATA[<p><a href="http://norvig.com/sudoku.html" rel="nofollow">http://norvig.com/sudoku.html</a> irgendwo habe ich auch meine C++ Variante.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329275</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Fri, 07 Jun 2013 15:32:38 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 09:41:07 GMT]]></title><description><![CDATA[<p>Dein Why-Abschnitt lässt mich schmunzeln.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329346</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329346</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Sat, 08 Jun 2013 09:41:07 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 11:31:33 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Woran erkennst du denn, ob eine Lösung gefunden wurde oder nicht? Also insbesondere, woran erkennst du, dass du backtracken musst?</p>
<p>Ich hab zwar noch keinen Sudoku-Löser implementiert, aber wenn ich es per Backtracking machen würde, würde ich searchSolution einen bool-Rückgabewert verpassen: true falls Lösung gefunden, false falls Sackgasse. Dann läuft der Algorithmus ungefähr so:</p>
<pre><code>if (aktuelles feld nicht frei)
  return false;
for (zahl = 1 bis 9) {
  if (kann zahl ins aktuelle Feld eintragen ohne Konflikte)
     trage zahl ein
     erfolg = searchSolution(nächstes Feld)
     if (erfolg)
       // cool!
       return true; // oder vielleicht versuchen ob es weitere Lösungen gibt?
     else
       mache das aktuelle Feld wieder frei
       // Schleife weiter laufen lassen
}
// Schleife erfolglos durchlaufen?
return false;
</code></pre>
<p>Das wäre jedenfalls erstmal die Variante mit den wenigsten Abweichungen von deiner, man kann das natürlich alles auch ganz anders machen.</p>
</blockquote>
<p>Das sehe ich gar nicht so. Die erste oder alle Lösungen ausgeben geht sehr wohl mit void. Sogar besser, weil ich nicht glaube, daß man mit dem bool was sinnvolles macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329361</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329361</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 08 Jun 2013 11:31:33 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 11:35:30 GMT]]></title><description><![CDATA[<p>Geht das ein bisschen ausführlicher?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329363</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329363</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Sat, 08 Jun 2013 11:35:30 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 11:43:47 GMT]]></title><description><![CDATA[<p>eddi0815 schrieb:</p>
<blockquote>
<p>Quelltext:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;

const std::size_t ROW = 9;
const std::size_t COL = 9;

class Field {
public:
	Field();
	void printField();
    void searchSolution(std::size_t y, std::size_t x);
	bool isColumnOk(std::size_t y, char number);
    bool isRowOk(std::size_t x, char number);
    bool isBlockOk(std::size_t y, std::size_t x, char number);
private:
    std::array&lt;std::array&lt;char, ROW&gt;, COL&gt; field;
};

Field::Field()
{
    field = {' ', ' ', ' ',/*|*/ ' ', '1', ' ',/*|*/ ' ', '6', ' ',
             '7', '3', '6',/*|*/ '2', '8', '5',/*|*/ ' ', '9', ' ',
             ' ', ' ', ' ',/*|*/ ' ', '4', '9',/*|*/ ' ', '3', ' ',
             /****************************************************/
             ' ', '1', '3',/*|*/ '8', ' ', '7',/*|*/ ' ', '4', ' ',
             '6', '7', '5',/*|*/ ' ', ' ', ' ',/*|*/ '9', '8', '3',
             ' ', '8', ' ',/*|*/ '5', ' ', '6',/*|*/ '1', '2', ' ',
             /****************************************************/
             ' ', '2', ' ',/*|*/ '9', '5', ' ',/*|*/ ' ', ' ', ' ',
             ' ', '6', ' ',/*|*/ '4', '7', '8',/*|*/ '3', '5', '2',
             ' ', '4', ' ',/*|*/ ' ', '6', ' ',/*|*/ ' ', ' ', ' '
            };
}
</code></pre>
</blockquote>
<p>Zeile 21 compiliert beri mir nicht. Es gäbe keinen passenden operator=.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329365</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329365</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 08 Jun 2013 11:43:47 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 15:01:47 GMT]]></title><description><![CDATA[<p>Das geht hoffentlich:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;

const std::size_t ROW = 9;
const std::size_t COL = 9;

class Field {
public:
    Field();
    void printField();
    void searchSolution(std::size_t y, std::size_t x);
    bool isColumnOk(std::size_t y, char number);
    bool isRowOk(std::size_t x, char number);
    bool isBlockOk(std::size_t y, std::size_t x, char number);
private:
    std::array&lt;std::array&lt;char, ROW&gt;, COL&gt; field;
};

Field::Field()
{
    field = std::array&lt;std::array&lt;char, ROW&gt;, COL&gt;
             {' ', ' ', ' ',/*|*/ ' ', '1', ' ',/*|*/ ' ', '6', ' ',
             '7', '3', '6',/*|*/ '2', '8', '5',/*|*/ ' ', '9', ' ',
             ' ', ' ', ' ',/*|*/ ' ', '4', '9',/*|*/ ' ', '3', ' ',
             /****************************************************/
             ' ', '1', '3',/*|*/ '8', ' ', '7',/*|*/ ' ', '4', ' ',
             '6', '7', '5',/*|*/ ' ', ' ', ' ',/*|*/ '9', '8', '3',
             ' ', '8', ' ',/*|*/ '5', ' ', '6',/*|*/ '1', '2', ' ',
             /****************************************************/
             ' ', '2', ' ',/*|*/ '9', '5', ' ',/*|*/ ' ', ' ', ' ',
             ' ', '6', ' ',/*|*/ '4', '7', '8',/*|*/ '3', '5', '2',
             ' ', '4', ' ',/*|*/ ' ', '6', ' ',/*|*/ ' ', ' ', ' '
            };
}

void Field::printField()
{
    for (std::size_t y = 0; y &lt; COL; ++y) {
        if (y % 3 == 0) {
            std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
        }
        for (std::size_t x = 0; x &lt; ROW; ++x) {
            if (x % 3 == 0) {
                std::cout &lt;&lt; &quot;|&quot;;
            }
            std::cout &lt;&lt; field[y][x];
        }
        std::cout &lt;&lt; &quot;|\n&quot;;
    }
    std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
}

void Field::searchSolution(std::size_t y, std::size_t x)
{
    //Abbruchkriterium
    if (y &gt;= COL) {//geändert
        printField();//neu
        std::cout&lt;&lt;'\n';//neu
        return;
    }
    //Nächste Zeile bestimmen
    std::size_t yNext, xNext;
    //Zeile noch nicht voll?
    if (x &lt; ROW - 1) {
        yNext = y; //Zeile bleibt gleich
        xNext = x + 1; //Spalte ein weiter
    } else {
        //Wenn Zeile voll, in erste Spalte eine Zeile tiefer
        yNext = y + 1; //Zeile ein &quot;tiefer&quot;
        xNext = 0; //Spalte zurück auf 0
    }
    //Suchen
    if (field[y][x] != ' ') { //Feld ist Vorbelegt
        searchSolution(yNext, xNext); //Dann beim nächsten Index weitersuchen
    } else { //sonst alle Zahlen probieren
        for (char number = '1'; number &lt;= '9'; ++number) {
            if (isColumnOk(y, number)
                    &amp;&amp; isRowOk(x, number)
                    &amp;&amp; isBlockOk(y, x, number)) {
                field[y][x] = number; //gefundene Zahl eintragen
                searchSolution(yNext, xNext); //weitersuchen
            }
        } //irgendwie das bisherige rückgängig machen, falls es eine Sackgasse ist. Nur wie?
        field[y][x] = ' ';//genau!
    }
}

bool Field::isColumnOk(std::size_t y, char number)
{
    for (std::size_t x = 0; x &lt; COL; ++x) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isRowOk(std::size_t x, char number)
{
    for (std::size_t y = 0; y &lt; ROW; ++y) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isBlockOk(std::size_t y, std::size_t x, char number)
{
    std::size_t col = (y / 3) * 3;
    std::size_t row = (x / 3) * 3;

    for (std::size_t i = col; i &lt; col + 3; ++i) {
        for (std::size_t j = row; j &lt; row + 3; ++j) {
            if (field[i][j] == number) {
                return false;
            }
        }
    }
    return true;
}

int main()
{
    Field field;
    field.printField();
    field.searchSolution(0, 0); //beginne oben links
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2329406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329406</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 08 Jun 2013 15:01:47 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 16:00:39 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Geht das ein bisschen ausführlicher?</p>
</blockquote>
<p>Hast recht. bool ist gut, um abzubrechen, um nur eine Lösung auszugeben. Hab in Letzter Zeit immer alle Lösungen grbraucht, sorry.</p>
<p>Hab's ein wenig aufgemotzt, und gebe einen size_t zurück, die Anzahl der Lösungen.</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;array&gt;
#include &lt;cstdlib&gt;
#include &lt;ctime&gt;

const std::size_t ROW = 9;
const std::size_t COL = 9;

class Field {
public:
    Field();
    void printField();
    std::size_t searchSolution(std::size_t y, std::size_t x,bool show);
    bool isColumnOk(std::size_t y, char number);
    bool isRowOk(std::size_t x, char number);
    bool isBlockOk(std::size_t y, std::size_t x, char number);
    void harden();
private:
    std::array&lt;std::array&lt;char, ROW&gt;, COL&gt; field;
};

Field::Field()
{
    field = std::array&lt;std::array&lt;char, ROW&gt;, COL&gt;
             {' ', ' ', ' ',/*|*/ ' ', '1', ' ',/*|*/ ' ', '6', ' ',
             '7', '3', '6',/*|*/ '2', '8', '5',/*|*/ ' ', '9', ' ',
             ' ', ' ', ' ',/*|*/ ' ', '4', '9',/*|*/ ' ', '3', ' ',
             /****************************************************/
             ' ', '1', '3',/*|*/ '8', ' ', '7',/*|*/ ' ', '4', ' ',
             '6', '7', '5',/*|*/ ' ', ' ', ' ',/*|*/ '9', '8', '3',
             ' ', '8', ' ',/*|*/ '5', ' ', '6',/*|*/ '1', '2', ' ',
             /****************************************************/
             ' ', '2', ' ',/*|*/ '9', '5', ' ',/*|*/ ' ', ' ', ' ',
             ' ', '6', ' ',/*|*/ '4', '7', '8',/*|*/ '3', '5', '2',
             ' ', '4', ' ',/*|*/ ' ', '6', ' ',/*|*/ ' ', ' ', ' '
            };
}

void Field::printField()
{
    for (std::size_t y = 0; y &lt; COL; ++y) {
        if (y % 3 == 0) {
            std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
        }
        for (std::size_t x = 0; x &lt; ROW; ++x) {
            if (x % 3 == 0) {
                std::cout &lt;&lt; &quot;|&quot;;
            }
            std::cout &lt;&lt; field[y][x];
        }
        std::cout &lt;&lt; &quot;|\n&quot;;
    }
    std::cout &lt;&lt; &quot;+---+---+---+\n&quot;;
}

std::size_t Field::searchSolution(std::size_t y, std::size_t x,bool show)
{
    size_t result=0;
    //Abbruchkriterium
    if (y &gt;= COL) {//geändert
        if(show)
        {
            printField();//neu
            std::cout&lt;&lt;'\n';//neu
        }
        return 1;
    }
    //Nächste Zeile bestimmen
    std::size_t yNext, xNext;
    //Zeile noch nicht voll?
    if (x &lt; ROW - 1) {
        yNext = y; //Zeile bleibt gleich
        xNext = x + 1; //Spalte ein weiter
    } else {
        //Wenn Zeile voll, in erste Spalte eine Zeile tiefer
        yNext = y + 1; //Zeile ein &quot;tiefer&quot;
        xNext = 0; //Spalte zurück auf 0
    }
    //Suchen
    if (field[y][x] != ' ') { //Feld ist Vorbelegt
        result+=searchSolution(yNext, xNext,show); //Dann beim nächsten Index weitersuchen
    } else { //sonst alle Zahlen probieren
        for (char number = '1'; number &lt;= '9'; ++number) {
            if (isColumnOk(y, number)
                    &amp;&amp; isRowOk(x, number)
                    &amp;&amp; isBlockOk(y, x, number)) {
                field[y][x] = number; //gefundene Zahl eintragen
                result+=searchSolution(yNext, xNext,show); //weitersuchen
            }
        } //irgendwie das bisherige rückgängig machen, falls es eine Sackgasse ist. Nur wie?
        field[y][x] = ' ';//genau!
    }
    return result;
}

bool Field::isColumnOk(std::size_t y, char number)
{
    for (std::size_t x = 0; x &lt; COL; ++x) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isRowOk(std::size_t x, char number)
{
    for (std::size_t y = 0; y &lt; ROW; ++y) {
        if (field[y][x] == number) {
            return false;
        }
    }
    return true;
}

bool Field::isBlockOk(std::size_t y, std::size_t x, char number)
{
    std::size_t col = (y / 3) * 3;
    std::size_t row = (x / 3) * 3;

    for (std::size_t i = col; i &lt; col + 3; ++i) {
        for (std::size_t j = row; j &lt; row + 3; ++j) {
            if (field[i][j] == number) {
                return false;
            }
        }
    }
    return true;
}
void Field::harden()
{
    size_t left=100;
    while(left!=0){
        std::cout&lt;&lt;left&lt;&lt;&quot;   \r&quot;&lt;&lt;std::flush;
        size_t x=rand()%ROW;
        size_t y=rand()%COL;
        if(field[y][x]!=' '){
            char save=field[y][x];
            field[y][x]=' ';
            left--;
            if(searchSolution(0,0,false)==1)
            {
                //printField();
                left=100;
            }
            else
            {
                field[y][x]=save;
            }
        }
    }
}

int main()
{
    srand(time(0));
    Field field;

    std::cout&lt;&lt;&quot;The Field:\n&quot;;
    field.printField();

    std::cout&lt;&lt;&quot;The Solutions:\n&quot;;
    std::size_t solutionsCount=field.searchSolution(0, 0, true);
    if(solutionsCount!=1){
        std::cout&lt;&lt;&quot;Error: Invalid Field\n&quot;;
        return 1;
    }

    std::cout&lt;&lt;&quot;A harder Field:\n&quot;;
    field.harden();
    field.printField();
}
</code></pre>
<p>Ausgabe</p>
<pre><code>The Field:
+---+---+---+
|   | 1 | 6 |
|736|285| 9 |
|   | 49| 3 |
+---+---+---+
| 13|8 7| 4 |
|675|   |983|
| 8 |5 6|12 |
+---+---+---+
| 2 |95 |   |
| 6 |478|352|
| 4 | 6 |   |
+---+---+---+
The Solutions:
+---+---+---+
|894|713|265|
|736|285|491|
|152|649|738|
+---+---+---+
|213|897|546|
|675|124|983|
|489|536|127|
+---+---+---+
|328|951|674|
|961|478|352|
|547|362|819|
+---+---+---+

A harder Field:
+---+---+---+
|   | 1 | 6 |
|736|   | 9 |
|   | 4 | 3 |
+---+---+---+
|  3|  7| 4 |
|67 |   |98 |
| 8 |5  |1  |
+---+---+---+
|   |95 |   |
| 6 |  8|  2|
|   | 6 |   |
+---+---+---+
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2329421</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329421</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 08 Jun 2013 16:00:39 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Sat, 08 Jun 2013 16:05:15 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Bashar schrieb:</p>
<blockquote>
<p>Geht das ein bisschen ausführlicher?</p>
</blockquote>
<p>Hast recht. bool ist gut, um abzubrechen, um nur eine Lösung auszugeben. Hab in Letzter Zeit immer alle Lösungen grbraucht, sorry.</p>
</blockquote>
<p>Stimmt, wenn man den ganzen Baum abläuft und alle Blätter, die Lösungen sind, ausgibt, braucht man kein bool.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329423</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329423</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Sat, 08 Jun 2013 16:05:15 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 13:01:37 GMT]]></title><description><![CDATA[<p>Vielen Dank an Alle für die Hilfe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2329940</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2329940</guid><dc:creator><![CDATA[eddi0815]]></dc:creator><pubDate>Mon, 10 Jun 2013 13:01:37 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 16:37:18 GMT]]></title><description><![CDATA[<p>Es geht hier aber um Sudoku und da gibt es nur eine Lösung. Somit gilt die Ausrede für &quot;alle Lösungen&quot; nicht. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330026</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330026</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 10 Jun 2013 16:37:18 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 18:10:05 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Es geht hier aber um Sudoku und da gibt es nur eine Lösung.</p>
</blockquote>
<p>Das ist so offensichtlicher Unfug, dass es wahrscheinlich schon wieder richtig ist. Erklär doch mal, wie du das meinst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330052</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330052</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 10 Jun 2013 18:10:05 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 18:36:24 GMT]]></title><description><![CDATA[<p>Das ist in meinen Augen überhaupt kein Unfug und daher erst recht nicht offensichtlich. Leider sind die Quellen, die ich so fand, inkommensurabel, sodass ich Mal auf diese Zusammenfassung in einem Forum verweise:<br />
<a href="http://portableapps.com/node/20122#comment-124186" rel="nofollow">http://portableapps.com/node/20122#comment-124186</a> (nicht alle Quellen geprüft)</p>
<p>Die meisten Bücher und andere Quellen sagen also Eindeutigkeit aus. Da es aber offensichtlich Ausnahmen (ob Sudoko oder dann nicht mehr) gibt, sollte eine Software wohl damit klarkommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330058</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330058</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 10 Jun 2013 18:36:24 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 18:48:45 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Das ist in meinen Augen überhaupt kein Unfug und daher erst recht nicht offensichtlich.</p>
</blockquote>
<p>Doch, das leere Sudoku-Feld hat beispielsweise mehr als eine Lösung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330062</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 10 Jun 2013 18:48:45 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 18:53:59 GMT]]></title><description><![CDATA[<p>Und wer sagt Dir, dass man so etwas als Sudoku bezeichnet? Das Sudoko-Feld mit Kreisen statt Rechtecken, 200 Feldern, bei dem jedes Sudoku-Feld binäre Werte enthält, hat auch mehrere Lösungen.</p>
<p>Sudoku ist ein Puzzle. Ich werfe daher auch Mal eine Definition eines Puzzles in den Raum: <a href="http://en.wikipedia.org/wiki/Glossary_of_Sudoku#Puzzle_terms" rel="nofollow">http://en.wikipedia.org/wiki/Glossary_of_Sudoku#Puzzle_terms</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330063</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330063</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 10 Jun 2013 18:53:59 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 19:08:23 GMT]]></title><description><![CDATA[<p>Niemand sagt mir das. Wahrscheinlich hast du sogar Recht, und man nennt offiziell nur eindeutig lösbare sudokuartige Rätsel &quot;Sudoku&quot;. Diese willkürliche Benennung ist aber im Zusammenhang mit einem Sudokulöser reichlich irrelevant, schließlich kann man einem eventuell nicht- oder mehrdeutig lösbaren sudokuartigen Rätsel nicht ohne weiteres ansehen, ob es ein Sudoku ist. Man kann aber versuchen, es zu lösen, und so herausfinden, ob es überhaupt eine oder wenn ja, mehrere Lösungen besitzt. Und damit man nicht einen Sudokulöser und einen eventuell-nicht-oder-mehrdeutig-lösbare-sudokuartige-Rätselspiele-Löser nebeneinander programmieren muss, löst man sich sinnvollerweise von willkürlichen Festlegungen und betrachtet das Problem so, wie das ein Mathematiker oder Informatiker tun würde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330068</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 10 Jun 2013 19:08:23 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 19:11:51 GMT]]></title><description><![CDATA[<p>Also Sudokus aus der Rätselzeitschrift haben nur eine Lösung. Da wäre bool gut zum abbrechen.<br />
Der Löser scheint aber so schnell zu sein, daß es von der Laufzeit her überhaupt nicht drauf ankommt, ob man abbricht oder alle Lösungen ausgibt. Ich bin daran interessiert, ob es zufällig doch mehr als eine Lösung gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330070</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330070</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 10 Jun 2013 19:11:51 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst]Backtracking und Sudoku on Mon, 10 Jun 2013 21:56:45 GMT]]></title><description><![CDATA[<blockquote>
<p>Diese willkürliche Benennung ist aber im Zusammenhang mit einem Sudokulöser reichlich irrelevant</p>
</blockquote>
<p>Und dafür schrieb ich ja in meinem Beitrag auch bereits (möglicherweise nicht deutlich genug):</p>
<blockquote>
<p>Da es aber offensichtlich Ausnahmen (ob Sudoko oder dann nicht mehr) gibt, sollte eine Software wohl damit klarkommen.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2330096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2330096</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 10 Jun 2013 21:56:45 GMT</pubDate></item></channel></rss>