1 2 3 | CCC CCC |
Laat ik deze regel even toelichten aan de hand van een paar voorbeelden.quote:Op woensdag 28 december 2005 21:38 schreef thabit het volgende:
Regel 1. Stel je hebt een verzameling cijfers S en een rij/kolom/blok waarvoor geldt dat het aantal vakjes v met a(v) deelverzameling van S minstens gelijk is aan het aantal elementen van S, dan mag je in alle andere vakjes van je rij/kolom/blok de cijfers van S wegstrepen.
Heb je hier ook een bron van?quote:Op woensdag 28 december 2005 22:03 schreef -jos- het volgende:
Ehm, ik vind het wel een leuk idee maar volgens mij kun je elke sudoku gewoon met een simpel excel file-tje oplossen, heb ik gelezen ergens
Jij bent grappig, maar inderdaad een beetje simpel als je niet eens een beetje kan Sudoku'en.quote:Op woensdag 28 december 2005 21:57 schreef tass het volgende:
Ik ben gek op rekenspelletjes, maar van het hele sudoku of zo, snap ik echt geen ene bal!!!
Ik heb 't geprobeerd maar ik ben blond. Dus hou ik er maar mee op :-D :-D
Het stond enkele weken terug in een computerblad dat een oud-leraar van me op het perron stond te lezen.quote:
Ik denk dat hij een of ander computerblad bedoelde, daar stond schijnbaar in hoe random Sudoku's kon laten maken doormiddel van een excel sheet. Maar opzich is het niet heel moeilijk om op te lossen doormiddel van een programmatje te schrijven voor je rekenmachine, iig een maat van hem deed dat nog vrij rapquote:
ff op google gezocht ( op excel sudoku oplosser )quote:
Hmm, nee. Niet voor die. Er moeten dus nog regels bij. Vooral regel 2 moet algemener.quote:Op woensdag 28 december 2005 22:29 schreef Zap het volgende:
Klik hier: http://www.stolaf.edu/people/hansonr/sudoku eens op Hardest (rechtsboven).
Zijn jouw regels ook voldoende voor die Sudoku?
Als je per vakje zou bijhouden welke getallen er niet meer in zouden kunnen staan, vind je vanzelf vakjes waarvoor alle mogelijkheden uitgeput zijn. Bij een moeilijke soduko ontkom je er denk ik echter niet aan om eerst puur op de gok bijv. drie vakjes in te vullen. Je hebt dan 1000 mogelijkheden, en bij een van de mogelijkheden kom je met de andere regel tot een oplossing.quote:Op woensdag 28 december 2005 23:05 schreef thabit het volgende:
De beginsituatie is al een probleem.
Ik was altijd onder de indruk dat je er met "simpel" wegstrepen wel kon komen, als je moet gaan gokken is het toch niet echt een leuk spel meer, lijkt me. Je moet er toch rekenkundig uit kunnen komen.quote:Op donderdag 29 december 2005 08:10 schreef Alicey het volgende:
[..]
Bij een moeilijke soduko ontkom je er denk ik echter niet aan om eerst puur op de gok bijv. drie vakjes in te vullen.
Zelfs de allermoeilijkste soduku's kunnen zonder gokwerk opgelost worden.quote:Op donderdag 29 december 2005 08:10 schreef Alicey het volgende:
[..]
Als je per vakje zou bijhouden welke getallen er niet meer in zouden kunnen staan, vind je vanzelf vakjes waarvoor alle mogelijkheden uitgeput zijn. Bij een moeilijke soduko ontkom je er denk ik echter niet aan om eerst puur op de gok bijv. drie vakjes in te vullen. Je hebt dan 1000 mogelijkheden, en bij een van de mogelijkheden kom je met de andere regel tot een oplossing.
De vraag is natuurlijk weer of het toevoegen van dat patroon genoeg is, en of je wel elke soduko kunt oplossen met 3 vakjes (bij elkaar of random?) proberen in te vullen..
Dat is een feit?quote:Op donderdag 29 december 2005 15:15 schreef DionysuZ het volgende:
[..]
Zelfs de allermoeilijkste soduku's kunnen zonder gokwerk opgelost worden.
Anders is het geen Sudoku.quote:
quote:Bij het maken van een opgave moet het computerprogramma eerst een oplossing in mekaar knutselen d.m.v. random-verdelingen van de 9 cijfers en toetsing van de rij-kolom-blok-compatibiliteit. Zodra een nieuwe oplossing is gevonden moet ze omgezet worden naar een opgave door er (eveneens random) een aantal cijfers van vrij te geven. Het computerprogramma moet dan nagaan of de vrijgegeven cijfers toelaten de puzzel op te lossen. Is dat niet het geval dan kan een bijkomend cijfer vrijgegeven worden (en telkens weer een volgend) tot de puzzel zonder gokken oplosbaar is.
Het lijkt me wel logisch, op zich. Als je moet gaan gokken, is er toch niks uitdagends meer aan? Het is juist de truc om het met flink zoeken op te lossen, niet met mazzel.quote:
Brengt je wel op de vraag wanneer een sudoku als gokken wel was toegestaan makkelijker gaat worden naarmate je meer symbolen weglaat. Je krijgt dan, heb ik het idee, nl meer mogelijkheden op een gegeven moment. Zo is een geheel lege sodoku vast makkelijker als eentje met een heel stel cijfers al fixed erin.quote:
Bekijk de source van bestaande sudoku solvers zou ik zeggenquote:Op donderdag 29 december 2005 15:18 schreef ThE_ED het volgende:
Ik vraag me af wat nou (voor een computer) de snelste manier van oplossen is (als we even een database met alle mogelijkheden niet meerekenen.) zelf zou ik het zo aanpakken als TS denk ik. Zo ver kom ik nog wel met mijn beperkte wiskundige vermogens, maar blijkbaar is dat nog niet helemaal sluitend.
ik doe het altijd zo in mijn hoofd, en tot nu toe ben ik nog nooit 1 tegengekomen waarmee ik er niet uitkwam, en echt moest gaan gokkenquote:Op woensdag 28 december 2005 21:38 schreef thabit het volgende:Met de hand deze regels toepassen is erg omslachtig. Het lukt mij in elk geval niet. Ik ben te langzaam en te slordig daarvoor. Een computer is echter snel en precies dus ik heb een computerprogrammaatje geschreven dat herhaaldelijk op alle mogelijke manieren de regels 1 en 2 toepast totdat het de sudoku heeft opgelost. Het mooie is: elke sudoku die ik erin heb gestopt heeft het weten op te lossen.
Zijn hier sudoku-beoefenaars die er meer van weten? Zijn er sudoku's waarbij je echt cijfertjes moet uitproberen anders kun je er niet uitkomen?
Ik neem aan dat met "zonder gokwerk" bedoeld wordt dat de oplossing eenduidig is.quote:Op donderdag 29 december 2005 15:15 schreef DionysuZ het volgende:
[..]
Zelfs de allermoeilijkste soduku's kunnen zonder gokwerk opgelost worden.
quote:Op donderdag 29 december 2005 19:19 schreef thabit het volgende:
[..]
Ik neem aan dat met "zonder gokwerk" bedoeld wordt dat de oplossing eenduidig is.
Nee, afzonderlijk werken ze niet. Maar een generalisatie die beide omvat zou inderdaad wel interessant zijn.quote:Op donderdag 29 december 2005 15:46 schreef Koekepan het volgende:
Werkt regel 1 of 2 ook afzonderlijk al? En is er misschien een generalisatie te verzinnen die beide regels omvat?
Helaas, de puzzels die daar op het moeilijkste niveau staan kunnen gewoon met de in de OP beschreven regels worden opgelost.quote:Op donderdag 29 december 2005 20:39 schreef Rewimo het volgende:
Online spelen in diverse moeilijkheidsgraden
In het geval van de sudoku klopt dat aardig.quote:Op donderdag 29 december 2005 20:42 schreef soulsurvivor het volgende:
Als je dit spel kan kraken met simpele formules is er volgens mij gelijk geen reet meer an.
In dat geval is dom blijven dus een slimmere keuzequote:Op donderdag 29 december 2005 20:51 schreef Koekepan het volgende:
[..]
In het geval van de sudoku klopt dat aardig.
Dat is nou een sudoku....quote:Op donderdag 29 december 2005 20:42 schreef soulsurvivor het volgende:
Als je dit spel kan kraken met simpele formules is er volgens mij gelijk geen reet meer an.
Begrijp me niet verkeerd, ik vind het erg knap dat je een verzameling regels hebt gevonden die zeer waarschijnlijk werkt. Maar het zélf maken van sudoku's gaat natuurlijk wel vrij snel vervelen (precies omdat je zelf te werk gaat volgens een beperkte verzameling regels).quote:Op donderdag 29 december 2005 20:57 schreef thabit het volgende:
Ach ja, als je op sudoku bent uitgekeken kun je natuurlijk altijd aan het de Riemannhypothese gaan werken.
Dacht dat die al opgelost was.quote:Op donderdag 29 december 2005 20:57 schreef thabit het volgende:
Ach ja, als je op sudoku bent uitgekeken kun je natuurlijk altijd aan het de Riemannhypothese gaan werken.
Als je dit topic had doorgelezen had je gezien dat mijn verzameling regels niet werkt.quote:Op donderdag 29 december 2005 21:00 schreef Koekepan het volgende:
[..]
Begrijp me niet verkeerd, ik vind het erg knap dat je een verzameling regels hebt gevonden die zeer waarschijnlijk werkt. Maar het zélf maken van sudoku's gaat natuurlijk wel vrij snel vervelen (precies omdat je zelf te werk gaat volgens een beperkte verzameling regels).
Iemand die beweert die oplossing te begrijpen heeft sowieso ongelijk.quote:Op donderdag 29 december 2005 21:01 schreef soulsurvivor het volgende:
[..]
Dacht dat die al opgelost was.
maar volgens mij ben je idd wel een paar jaartjes zoet die oplossing te begrijpen.
1 2 3 | BBBEEEEEE CCC |
Wat wordt de regel dan precies?quote:Op donderdag 29 december 2005 21:16 schreef ThE_ED het volgende:
Werkt het niet als je regel 2 wat ruimer neemt met 1e rij/kolom erbij?
dus
[ code verwijderd ]
Jammer dat dit sowieso niet echt gaat leiden tot wat de mooiste regels zouden zijn...
Hmm, nee wacht, slaat niet echt ergens opquote:
1 2 3 | CCCDDDDDD EEEFFFFFF |
hihi, heb je t over mij??quote:Op woensdag 28 december 2005 23:28 schreef gexxz het volgende:
Een vriend van me heeft er een programmaatje voor geschreven
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | using System.Collections; namespace StateSolvingTest { class StateSolvingTest { /// Private attributes /// // Holds the list of empty cells private int[] emptyCells = new int[81]; // Holds the 27 candidate lists 1..9 private BitArray[] candidates = new BitArray[27]; // Holds the sudoku as a linear array private int[] pattern = new int[81]; // True when a solution has been found private bool ready; /// Properties /// public int[] Pattern { get { return pattern; } set { pattern = value; } } /// Constructors /// public StateSolvingTest() { // Instantiate the candidatelists for (int i = 0; i < 27; i++) { candidates[i] = new BitArray(10); } } /// Public methods /// public void FindSolution() { // Holds the indices of the candidatelists int column = 0; int row = 0; int region = 0; // Temporary store all empty cells ArrayList tempList = new ArrayList(); // Fill the candidate lists with all 9 bits set for (int i = 0; i < 27; i++) { candidates[i].SetAll(true); } // Exclude invalid candidates from the lists and get empty cells for (int i = 0; i < 81; i++) { if (pattern[i] != 0) { // Check which arraylists to remove from GetCandidateLists(i, ref column, ref row, ref region); candidates[column].Set(pattern[i], false); candidates[row].Set(pattern[i], false); candidates[region].Set(pattern[i], false); } else { tempList.Add ![]() } } // Copy the list into an int[] emptyCells = new int[tempList.Count]; tempList.CopyTo(emptyCells); // Set the ready flag to false ready = false; // Run the backtracking method from position 0 FindSolution(0); } // Recursive backtracking algorithm private void FindSolution(int eIndex) { // Holds the indices of the candidatelists int column = 0; int row = 0; int region = 0; // Check if we are before the end of the pattern if (eIndex < emptyCells.Length) { // Get the corresponding candidatelists GetCandidateLists(emptyCells[eIndex], ref column, ref row, ref region); // Testing 1..9 for (int i = 1; i < 10; i++) { // Check if the candidate exists in the corresponding lists if (candidates[column].Get ![]() ![]() ![]() // Add the number to the pattern pattern[emptyCells[eIndex]] = i; // Exclude this number from the corresponding candidatelists candidates[column].Set(i, false); candidates[row].Set(i, false); candidates[region].Set(i, false); // Don't advance if a solution has been found if (ready) return; // Advance to the next cell FindSolution(eIndex + 1); // Don't revert if a solution has been found if (ready) return; // Reset the cell pattern[emptyCells[eIndex]] = 0; // Put the tested number back into the candidatelists candidates[column].Set(i, true); candidates[row].Set(i, true); candidates[region].Set(i, true); } } } else { // A solution has been found, get out of recursion ready = true; } } // Obtain the corresponding candidatelists private void GetCandidateLists(int position, ref int column, ref int row, ref int region) { column = position % 9; row = 9 + position / 9; region = 18 + column / 3 + 3 * ((row - 9) / 3); } public void DisplayPattern() { for (int i = 0; i < 81; i++) { if (i % 9 == 0) { Console.Write("\n\t"); } Console.Write(pattern[i]); } Console.WriteLine(); } public static void Main(String[] args) { Console.WriteLine("StateSolvingTest v0.1"); Console.WriteLine("Code by Markus\n"); StateSolvingTest sst = new StateSolvingTest(); int[] pattern = { 0,7,0,0,0,3,2,0,0, 0,0,5,6,9,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,8,0,7,0,3, 0,0,4,0,0,0,8,0,0, 9,0,1,0,2,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,5,8,4,0,0, 0,0,6,4,0,0,0,1,0}; sst.Pattern = pattern; DateTime startTime = DateTime.Now; sst.FindSolution(); TimeSpan elapsed = DateTime.Now - startTime; Console.WriteLine("\tExecution time: {0}s", elapsed.TotalSeconds.ToString()); sst.DisplayPattern(); } } } |
Er zijn enorm veel verschillende methodes om ze op te lossen.. BruteForce (recursief backtracken) is de meest voorkomende manier, maar de een backtrackt heel anders dan de andere. Ik heb bv verschillende backtrackers geschreven maar mn 3e manier van aanpak is dan weer vele malen efficienter.quote:Op donderdag 29 december 2005 15:18 schreef ThE_ED het volgende:
Ik vraag me af wat nou (voor een computer) de snelste manier van oplossen is (als we even een database met alle mogelijkheden niet meerekenen.) zelf zou ik het zo aanpakken als TS denk ik. Zo ver kom ik nog wel met mijn beperkte wiskundige vermogens, maar blijkbaar is dat nog niet helemaal sluitend.
er is geen `simpele formule` om dit op te lossen. want met formules reken je, en met sudoku's niet.quote:Op donderdag 29 december 2005 20:42 schreef soulsurvivor het volgende:
Als je dit spel kan kraken met simpele formules is er volgens mij gelijk geen reet meer an.
Hoe moet je dit compileren?quote:Op woensdag 1 februari 2006 16:15 schreef marq het volgende:
[..]
hihi, heb je t over mij??
ik heb zojuist de mn 4e algoritme voor het laatst geoptimaliseerd en het is nu met extreem moeilijke sudoku's nog steeds retesnel. de standaard sudoku's worden sowieso binnen 0.01 seconden opgelost als je computer > 1500MHz is.
om mn talenkennis te verbreden heb ik ervoor gekozen om het dit keer in C# te doen mbv mono onder linux.
[ code verwijderd ]
mocht iemand dit willen gebruiken..
dit is een console applicatie.. strip de Main en de ShowPattern en je houdt de klasse over die al het werk voor je doet. In de Main kun je zien hoe de klasse te benaderen..
voor andere rommel
http://mark.space.servehttp.com/sudoku/
Staat hier niet gewoon ieder getal mag maar één keer voorkomen in elke rij, kolom en blok maar dan onduidelijker?quote:Op woensdag 28 december 2005 21:38 schreef thabit het volgende:
Regel 1. Stel je hebt een verzameling cijfers S en een rij/kolom/blok waarvoor geldt dat het aantal vakjes v met a(v) deelverzameling van S minstens gelijk is aan het aantal elementen van S, dan mag je in alle andere vakjes van je rij/kolom/blok de cijfers van S wegstrepen.
Nee, het is een generalisatie van die regel.quote:Op woensdag 1 februari 2006 17:09 schreef Invictus_ het volgende:
[..]
Staat hier niet gewoon ieder getal mag maar één keer voorkomen in elke rij, kolom en blok maar dan onduidelijker?
dat maakt niet uit. je ontbeert het inzicht kennelijk niet anders had je me die tip nooit gegevenquote:
PC-Activequote:Op woensdag 28 december 2005 22:10 schreef Angel_of_Dth het volgende:
[..]
Het stond enkele weken terug in een computerblad dat een oud-leraar van me op het perron stond te lezen.
ik dacht dat er sudoku's waren met meerdere oplossingen.quote:Op donderdag 29 december 2005 19:19 schreef thabit het volgende:
[..]
Ik neem aan dat met "zonder gokwerk" bedoeld wordt dat de oplossing eenduidig is.
wat gebruikte je eerst dan?quote:Op woensdag 1 februari 2006 16:15 schreef marq het volgende:
[..]
hihi, heb je t over mij??
ik heb zojuist de mn 4e algoritme voor het laatst geoptimaliseerd en het is nu met extreem moeilijke sudoku's nog steeds retesnel. de standaard sudoku's worden sowieso binnen 0.01 seconden opgelost als je computer > 1500MHz is.
om mn talenkennis te verbreden heb ik ervoor gekozen om het dit keer in C# te doen mbv mono onder linux.
[ code verwijderd ]
mocht iemand dit willen gebruiken..
dit is een console applicatie.. strip de Main en de ShowPattern en je houdt de klasse over die al het werk voor je doet. In de Main kun je zien hoe de klasse te benaderen..
voor andere rommel
http://mark.space.servehttp.com/sudoku/
EDIT
overal waar dat domme blauwe ietje staat moet ( i ) staan (zonder spaties als t een beetje kan
Natuurlijk. Bijvoorbeeld de sudoku waar in het begin nog niets ingevuld is.quote:Op maandag 13 februari 2006 21:22 schreef McCarthy het volgende:
[..]
ik dacht dat er sudoku's waren met meerdere oplossingen.
dat ben ik nog nooit tegen gekomen in een sudoku.quote:Op maandag 13 februari 2006 22:06 schreef Schonedal het volgende:Het komt een enkele keer voor dat je moet gokken.
ik snap geen hol van je hele postquote:Op dinsdag 14 februari 2006 09:10 schreef JohnDDD het volgende:
ik vraag me wel af wat men nog onder gokken verstaat
kijk als je op een gegeven moment drie posities hebt in een rij waarin een drie kan komen te staan en je volgt dan logischerwijs voor elk van die mogelijkheden de gevolgen van het plaatsen van een 3 en je komt tot de conclusie dat ie maar in één van de vakjes kan staan, is dat dan gokken?
dan hangt "gokken" blijkbaar af van je genialiteit, dwz je vermogen tot het "uitrekenen" van de gevolgen van een bepaalde "zet", zoals een schaakcomputer ook kan bijv.
er zijn bijv. mogelijkheden bij het invullen van een sudoku om te zien dat bijv. een 7 alleen links kan zitten in een vierkantje
als je dan van het vierkant daar twee boven weet dat de 7 alleen rechts kan zitten, zit ie bij de driehoek daartussenin dus in het midden. dan kun je naar rechts kijken en als daar de 7 bovenaan moet komen (wat je ook nog eens kunt bepalen door twee andere vierkanten), weet je dat ie bij het vierkant daar weer rechts van in het midden of onderaan moet komen, en links ook.
nou ja zo kun je doorgaan
talen bedoel je?quote:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | // Include the class include 'StateSolver.class.php'; // This is what a given sudoku should look like (solution on the right) $sudoku = array( 0,2,0,4,0,9,5,0,6, // 321 489 576 0,4,5,0,7,0,8,0,9, // 645 173 829 0,7,0,0,2,6,0,0,0, // 879 526 413 0,0,0,0,3,0,6,0,1, // 587 234 691 9,0,2,0,6,0,0,0,0, // 912 865 347 0,0,0,7,0,1,0,5,0, // 436 791 258 0,0,0,3,1,0,0,0,4, // 258 317 964 7,0,0,0,0,0,1,0,0, // 794 658 132 0,0,3,9,0,2,7,8,0); // 163 942 785 // Instantiate the solver class $stateSolver = new StateSolver($sudoku); // Display the current sudoku DisplaySudoku($sudoku); // Obtain start time $beginTime = microtime(); // Call the solver $stateSolver->findSolution(); // Obtain end time $endTime = microtime(); // Calculate the total time $totalTime = $endTime - $beginTime; echo 'Elapsed time: '.$totalTime.'ms<br />'; // Display the solved sudoku DisplaySudoku($stateSolver->sudoku); function displaySudoku($sudoku) { for ($i = 0; $i < 81; $i++) { echo ' ' . $sudoku[$i] . ' '; if (($i + 1) % 9 == 0) { echo '<br />'; } } } ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | /* Sudoku State Solver v0.1 [04-feb-2006] -------------------------------------- All code by Mark Jelsma */ class StateSolver { ///////////////////////// /// PUBLIC ATTRIBUTES /// ///////////////////////// // Holds the sudoku puzzel as an array public $sudoku; ////////////////////////// /// PRIVATE ATTRIBUTES /// ////////////////////////// // Holds the 27 candidatelists as an array private $_candidates; // Holds the list of empty cells as an array private $_emptyCells; // Determines whether or not the algorithm has found a solution private $_ready; //////////////////// /// CONSTRUCTORS /// //////////////////// public function __construct($sudoku) { $this->sudoku = $sudoku; } ////////////////////// /// PUBLIC METHODS /// ////////////////////// // Initialize the solving algorithm public function findSolution() { $column = 0; $row = 0; $region = 0; $eIndex = 0; // Fill the candidatelists with all 9 bits set for ($i = 0; $i < 27; $i++) { $this->_candidates[$i] = 511; } // Exclude invalid candidates and get empty cells for ($i = 0; $i < 81; $i++) { if ($this->sudoku[$i] == 0) { // Add this empty cell to the list $this->_emptyCells[$eIndex++] = $i; } else { // Exclude this number from the candidatelists $this->_getCandidateLists($i, $column, $row, $region); $this->_exclude($this->_candidates[$column], $this->sudoku[$i]); $this->_exclude($this->_candidates[$row], $this->sudoku[$i]); $this->_exclude($this->_candidates[$region], $this->sudoku[$i]); } } // Set the ready flag to false $this->_ready = false; // Run the recursive backtracking algorithm $this->_solve(0); } /////////////////////// /// PRIVATE METHODS /// /////////////////////// // Recursive backtracking solver private function _solve($eIndex) { $column = 0; $row = 0; $region = 0; // See if haven't reached the end of the pattern if ($eIndex < count($this->_emptyCells)) { // Get the corresponding candidatelists $this->_getCandidateLists($this->_emptyCells[$eIndex], $column, $row, $region); // Check if $i occurs in all three candidatelists for ($i = 1; $i < 10; $i++) { if ($this->_isCandidate($this->_candidates[$column], $i) && $this->_isCandidate($this->_candidates[$row], $i) && $this->_isCandidate($this->_candidates[$region], $i)) { // Suitable candidate found, use it! $this->sudoku[$this->_emptyCells[$eIndex]] = $i; // Exclude this number from the candidatelists $this->_exclude($this->_candidates[$column], $i); $this->_exclude($this->_candidates[$row], $i); $this->_exclude($this->_candidates[$region], $i); // Don't advance if a solution has been found if ($this->_ready) return; // Advance to the next cell $this->_solve($eIndex + 1); // Don't revert if a solution has been found if ($this->_ready) return; // Reset the cell $this->sudoku[$this->_emptyCells[$eIndex]] = 0; // Put the candidates back in the lists $this->_include($this->_candidates[$column], $i); $this->_include($this->_candidates[$row], $i); $this->_include($this->_candidates[$region], $i); } } } else { // A solution has been found, get out of recursion $this->_ready = true; } } // Obtains the corresponding candidatelist indices private function _getCandidateLists($position, &$column, &$row, &$region) { $column = $position % 9; $row = floor(9 + $position / 9); $region = floor(18 + floor($column / 3) + 3 * floor(($row - 9) / 3)); } // Excludes a number from the list of candidates private function _exclude(&$bitSet, $bit) { $bitSet &= ~(1 << $bit -1); } // Includes a number into the list of candidates private function _include(&$bitSet, $bit) { $bitSet |= (1 << $bit - 1); } // Determines if number occurs in the specified list of candidates private function _isCandidate($bitSet, $bit) { return (($bitSet & (1 << $bit - 1)) == 0) ? false : true; } } ?> |
|
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |