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 && candidates[row].Get && candidates[region].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: | |