<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BarneyBlog &#187; sudoku</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/sudoku/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Mon, 02 Mar 2020 13:20:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sudoku PointingPairStrategy</title>
		<link>https://www.barneyb.com/barneyblog/2010/03/05/sudoku-pointing-pair-strategy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/03/05/sudoku-pointing-pair-strategy/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 06:51:46 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1330</guid>
		<description><![CDATA[The next sudoku strategy is called a "pointing pair" which I'm going to start by generalizing into "pointing triple".Â  The strategy is pretty straightforward: if, for a given number in a given block, all the potential cells are in the same row or column, then that number cannot exist in any other block's cells of [...]]]></description>
			<content:encoded><![CDATA[<p>The next sudoku strategy is called a "pointing pair" which I'm going to start by generalizing into "pointing triple".Â  The strategy is pretty straightforward: if, for a given number in a given block, all the potential cells are in the same row or column, then that number cannot exist in any other block's cells of the same row or column.</p>
<p>A pointing pair is easier to see than a pointing triple, but necessitates making the definition slightly tighter: if a block contains only two potential cells for a given number and they're in the same row or column, then that number cannot exist in any other block's cells of the same row or column.</p>
<p>Of course, if you crank it down one more step (to a "pointing single"), you have the definition of a known cell (either a given or one already solved for).Â  But enough prose, on to the code:</p>
<pre>boolean play(Board board) {
  def madePlay = false
  board.blocks.each { b -&gt;
    (1..9).each { n -&gt;
      def cells = b.findAll {
        it.hasMark(n)
      }
      if (cells.size() &gt;= 2) {
        if (cells*.col.unique().size() == 1) {
          // all in one col
          cells[0].col.each {
            if (it.block != b) { // different block
              madePlay = it.removeMark(n, this) || madePlay
            }
          }
        }
        if (cells*.row.unique().size() == 1) {
          // all in one row
          cells[0].row.each {
            if (it.block != b) { // different block
              madePlay = it.removeMark(n, this) || madePlay
            }
          }
        }
      }
    }
  }
  madePlay
}
</pre>
<p>This is the longest strategy so far, but it's pretty straightforward.Â  For each block, consider each number.Â  Find all the candidate cells, and if there are two or more, see if they're all in a single column.Â  If so, loop over the column and remove the number from each cell not in the current block.Â  Then do the same check for rows.</p>
<p>Using Groovy's getAt (bracket) notation, I could have wrapped the col and row checks into a single loop to reduce some duplication, but I haven't here.Â  You'll see that technique in some of the later strategies, however.</p>
<p>Finally, you'll notice that the whole board is iterated over and potentially many plays are made before the method returns.Â  As such, using each iterators wasn't a big deal.Â  This is probably somewhat wasteful, because a pointing pair can potentially do a lot of elimination (and therefore falling back to the <a href="http://www.barneyb.com/barneyblog/2010/01/27/sudoku-gamerulesstrategy/">GameRulesStrategy</a> would be useful), but I haven't done it here.</p>
<p>The raw source (including the test cases) is available at <a href="https://ssl.barneyb.com/svn/barneyb/sudoku/groovy/trunk/PointingPairStrategy.groovy">PointingPairStrategy.groovy</a>, should you be interested.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/03/05/sudoku-pointing-pair-strategy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sudoku HiddenSingleStrategy</title>
		<link>https://www.barneyb.com/barneyblog/2010/02/18/sudoku-hiddensinglestrategy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/02/18/sudoku-hiddensinglestrategy/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 02:48:17 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1258</guid>
		<description><![CDATA[The next Sudoku solving strategy I want to dig into is called "hidden single".Â  Here's the implementation to start with:
class HiddenSingleStrategy implements Strategy {

  static getTests() {
    [
      new Test(
        '0' * 9 + '000200000' + '0' * 9 [...]]]></description>
			<content:encoded><![CDATA[<p>The next Sudoku solving strategy I want to dig into is called "hidden single".Â  Here's the implementation to start with:</p>
<pre>class HiddenSingleStrategy implements Strategy {

  static getTests() {
    [
      new Test(
        '0' * 9 + '000200000' + '0' * 9 + '000060000' + '0' * 9 + '000080000' + '0' * 9 * 2 + '000002000',
        {
          def cell = it.getCell(5, 5)
          cell.isKnown() &amp;&amp; cell.value == 2
        }
      )
    ]
  }

  boolean play(Board board) {
    for (h in board.houses) {
      for (n in 1..9) {
        def cells = h.findAll {
          ! it.isKnown() &amp;&amp; it.hasMark(n)
        }
        if (cells.size() == 1) {
          // we found a hidden single
          cells[0].setValue(n, this)
          return true
        }
      }
    }
    false
  }

}</pre>
<p>As you can see, the test is a little different than for <a href="http://www.barneyb.com/barneyblog/2010/01/27/sudoku-gamerulesstrategy/">GameRulesStrategy</a>.Â  Before I just supplied a board and a successful test was when the board is solved.Â  In this case I'm just checking for if cell (5, 5) is known and it's value is 2 (no need to solve the whole board).</p>
<p>The strategy itself is pretty simple: for every house, for every number, see if any cell is the ONLY cell in the house that can contain the number, and if so, set that cell to that number.Â  Once we find a cell to set, the method exits (returning true) and does not continue the search.Â  This is the reason for the 'for' loops instead of the Groovy 'each' iterator.Â  This lets GameRulesStrategy "clean up" the board before continuing the search.Â  In this case it's probably not a big deal, but with the more complex strategies this is an essential optimization.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/02/18/sudoku-hiddensinglestrategy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sudoku GameRulesStrategy</title>
		<link>https://www.barneyb.com/barneyblog/2010/01/27/sudoku-gamerulesstrategy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/01/27/sudoku-gamerulesstrategy/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 21:46:39 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1197</guid>
		<description><![CDATA[A couple days ago I posted about implementing a Sudoku solver in Groovy as a sort of cross-training exercise, and promised to delve into the strategies a bit more.Â  So here's GameRulesStrategy:
class GameRulesStrategy implements Strategy {

  static getTests() {
    [
      new Test(
     [...]]]></description>
			<content:encoded><![CDATA[<p>A couple days ago I posted about <a href="http://www.barneyb.com/barneyblog/2010/01/25/sudoku-is-groovy/">implementing a Sudoku solver in Groovy</a> as a sort of cross-training exercise, and promised to delve into the strategies a bit more.Â  So here's <a href="https://ssl.barneyb.com/svn/barneyb/sudoku/groovy/trunk/GameRulesStrategy.groovy">GameRulesStrategy</a>:</p>
<pre>class GameRulesStrategy implements Strategy {

  static getTests() {
    [
      new Test(
        '900637100030001000107520300004810500019000820006059400002048705000200080001793006'
      )
    ]
  }

  boolean play(Board board) {
    def madePlay = false
    board.cells.findAll {
      it.isKnown()
    }.each { c -&gt;
      c.houses.flatten().findAll {
        it != c &amp;&amp; ! it.isKnown()
      }.each {
        madePlay = it.removeMark(c.value, this) || madePlay
      }
    }
    madePlay
  }

}</pre>
<p>As with all strategies, it starts with test cases that exercise the strategy: in this case a single board that can be solved by application of the rules alone.Â  That board spec, just for reference, describes this board:</p>
<pre>+-------+-------+-------+
| 9     | 6 3 7 | 1     |
|   3   |     1 |       |
| 1   7 | 5 2   | 3     |
+-------+-------+-------+
|     4 | 8 1   | 5     |
|   1 9 |       | 8 2   |
|     6 |   5 9 | 4     |
+-------+-------+-------+
|     2 |   4 8 | 7   5 |
|       | 2     |   8   |
|     1 | 7 9 3 |     6 |
+-------+-------+-------+</pre>
<p>There are three things a strategy can do when asked to play: remove a mark from a cell, set a cell's value, or nothing.Â  It's up to the strategy to determine if doing several of them at once is appropriate or not.Â  And keep in mind that a cell with only one mark remaining is implicitly set to that value, so removing a mark can actually set a cell's value behind the scenes.</p>
<p>For GameRulesStrategy, we're only concerned with removing marks from cells, and we can do many of them in a single pass without stepping on our own toes.Â  We start by asking the board for all the cells, and then grabbing only the known ones.Â  Then we iterate over those cells, and for each one get the cell's houses (the row, column, and block the cell is in), flatten them into a single collection, and find all the other cells that aren't know.Â  Finally we iterate over those cells and remove the mark from each of them, keeping track of whether it actually did anything in the 'madePlay' variable.</p>
<p>If you're interested, this same algorithm can be implemented with for..in loops, instead of .each { } constructs, which is a technique I've used in later strategies where the closures get "in the way" of returning from the method early.Â  Here's the loop based implementation (minus the tests):</p>
<pre>class GameRulesStrategy implements Strategy {

  boolean play(Board board) {
    def madePlay = false
    for (c in board.cells.findAll {
      it.isKnown()
    }) {
      for (it in c.houses.flatten().findAll {
        it != c &amp;&amp; ! it.isKnown()
      }) {
        madePlay = it.removeMark(c.value, this) || madePlay
      }
    }
    madePlay
  }

}</pre>
<p>If you're wondering, the loop performs marginally faster (&lt;1%) than the iterator, but I find it to be a bit less readable, so I generally prefer the iterator approach.Â  If performance is paramount, Groovy is probably the wrong choice &#8211; it's forte is concise, readable code (and therefore development throughput) not CPU throughput.Â  People are more expensive than machines in most cases, and certainly this one.</p>
<p>This is a really simple strategy, but there are plenty more complicated ones to come, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/01/27/sudoku-gamerulesstrategy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sudoku is Groovy</title>
		<link>https://www.barneyb.com/barneyblog/2010/01/25/sudoku-is-groovy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/01/25/sudoku-is-groovy/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 19:42:07 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1190</guid>
		<description><![CDATA[Last week I spent a bunch of time implementing Sudoku solving strategies in Groovy.Â  Actually a pretty interesting exercise, I thought.Â  Even the simple solving techniques/strategies require a bit of thought to generalize into code.Â  This might seems like a pointless exercise, but think of it a cross training.Â  Football players can't hope to compete [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I spent a bunch of time implementing Sudoku solving strategies in Groovy.Â  Actually a pretty interesting exercise, I thought.Â  Even the simple solving techniques/strategies require a bit of thought to generalize into code.Â  This might seems like a pointless exercise, but think of it a cross training.Â  Football players can't hope to compete without lifting weights, and developers can't hope to be at their peak without doing some heavy lifting as well.</p>
<p>I picked Groovy because it let me avoid so much of the boilderplate code you might have with Java, and gives you some really powerful syntactic constructs that are missing from CFML.Â  Data structure searching/manipulation is the task at hand, and the code reflects that without much extra cruft.Â  I did run into some issues with aboring .each { } "loops", so had to convert a number of those to for..in loops instead.Â  I prefer the 'each' syntax, but it's problematic with aborting iteration several levels deep since you don't have the equivalent of a method-return or a labeled-break construct.</p>
<p>I'm going to walk through some of these strategies, but first I'm going to present the general Sudoku framework I built.Â  It's founded on two main types (Board and Cell) with a number of anciliary types (BoardSpec, House, Row, Column, Block, Chute, Stack and Band), and the actual solving types (Strategy, Solver, TestRunner and Test).Â  Starting at the top, the "runner" script looks like this:</p>
<pre>new TestRunner(new Solver([new GameRulesStrategy()])).test()</pre>
<p>That'll create a new Solver with just the GameRulesStrategy, and then supply that to a TestRunner to run the test (using the Strategy's internal test case(s)).Â  Here's GameRulesStrategy:</p>
<pre>class GameRulesStrategy implements Strategy {
  static getTests() {
    [new Test('900637100030001000107520300004810500019000820006059400002048705000200080001793006')]
  }

  boolean play(Board board) {
    def madePlay = false
    board.cells.each { c -&gt;
      if (c.isKnown()) {
        c.houses.each { h -&gt;
          h.findAll {
            ! it.isKnown()
          }.each {
            if (it != c) {
              madePlay = it.removeMark(c.value, this) || madePlay
            }
          }
        }
      }
    }
    madePlay
  }
}</pre>
<p>The getTests() method returns a List of Test objects, which contain a BoardSpec and an optional 'check' Closure for when the test has passed (the default is when the board is solved).Â  The BoardSpec uses a board literal &#8211; an 81 character string representing the board's cells starting in the upper left, and moving to the lower right, exactly like reading an English-language page.Â  1-9 represent themselves, any other character (zeros in this case) represent blank cells.</p>
<p>The solving loop simply iterates over each strategy invoking play(Board) on each one in turn, where a play is either removing a mark from a cell, or setting a cell's value.Â  Cells with a single mark are automatically promoted to a "known" cell.Â  Any time a strategy makes a play, the loop starts back at the first strategy.Â  Itereration continues until every strategy fails to make a play (the test fails), or the board passes the check (usually being solved).</p>
<p>Raw code is available at <a href="https://ssl.barneyb.com/svn/barneyb/sudoku/groovy/trunk/">https://ssl.barneyb.com/svn/barneyb/sudoku/groovy/trunk/</a> and requires Groovy 1.7 to run.Â  You should be able to export the code and run 'groovy driver.groovy' and have it.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/01/25/sudoku-is-groovy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sudoku Anyone?</title>
		<link>https://www.barneyb.com/barneyblog/2006/07/19/sudoku-anyone/</link>
		<comments>https://www.barneyb.com/barneyblog/2006/07/19/sudoku-anyone/#comments</comments>
		<pubDate>Thu, 20 Jul 2006 06:24:41 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://barneyb.com/barneyblog/?p=171</guid>
		<description><![CDATA[For my birthday last month, Heather (my wife) got me a book of Sudoku puzzles.&#160; If you like puzzles and haven't tried Sudoku, highly recommended.&#160; Simple and fun.
However, being the good computer geek that I am, I quickly decided that it'd be a heck of a lot easier to let the computer solve them for [...]]]></description>
			<content:encoded><![CDATA[<p>For my birthday last month, Heather (my wife) got me a book of Sudoku puzzles.&nbsp; If you like puzzles and haven't tried Sudoku, highly recommended.&nbsp; Simple and fun.</p>
<p>However, being the good computer geek that I am, I quickly decided that it'd be a heck of a lot easier to let the computer solve them for me.&nbsp; Note that <strong>this is <em>not</em> cheating</strong>.&nbsp; Since the computer can't do anything I don't tell it to do, I'm still solving the puzzles; the computer must exhibit a subset of my Sudoku prowess.&nbsp; However, it does have far better &quot;bookkeeping&quot; abilities, which is a marked advantage.</p>
<p>I built it as a simple JUnit-driven Java 5 application.&nbsp; It's pretty basic: 20 types, plus a few nested types.&nbsp; It leverages the Strategy pattern for implementing strategies, so adding a new strategy is as simple as implementing the <code>Strategy</code> interface (probably by extending <code>AbstractStrategy</code>) and registering the implementing class as a known strategy.</p>
<p>What was particularly interesting, however, was that the program was able to solve one- through four-star puzzles (five stars is the most difficult) with just two simple strategies:</p>
<ol>
<li>Checking to see if any given unit (a row, column, or block) has only one cell that can contain a given number, which means that cell must contain the number in question.</li>
<li>Checking to see if all cells in a given unit that can contain a given number are also within a second unit, which means the rest of the second unit can't contain the number in question. </li>
</ol>
<p>I've no idea how difficult the puzzles are in the overal universe of Sudoku, but it was surprising to me that those two simple strategies were so effective.</p>
<p>I should mention that the rule of the game (each number is present exactly once in each block) is enforced by the system itself, and was usually enough to solve the one-star puzzles.&nbsp; So you might consider the rules themselves to be strategy zero as they are effective in their own right.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2006/07/19/sudoku-anyone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
