<?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; groovy</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/groovy/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>Boggle Boards</title>
		<link>https://www.barneyb.com/barneyblog/2011/07/20/boggle-board/</link>
		<comments>https://www.barneyb.com/barneyblog/2011/07/20/boggle-board/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 05:13:24 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1710</guid>
		<description><![CDATA[In case anyone wants to know, here are the specs for Boggle &#8211; both for Original Boggle and for Big Boggle &#8211; in a handy machine-readable format.  The format is line oriented with each line representing a single die, and the sides of the dice delimited by spaces.  Note that there is a [...]]]></description>
			<content:encoded><![CDATA[<p>In case anyone wants to know, here are the specs for Boggle &#8211; both for Original Boggle and for Big Boggle &#8211; in a handy machine-readable format.  The format is line oriented with each line representing a single die, and the sides of the dice delimited by spaces.  Note that there is a side with 'Qu' on it, so you must allow for a multi-letter side in your parser.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.barneyb.com/boggle/original_boggle.txt">original_boggle.txt</a></p>
<pre>A A C I O T
A B I L T Y
A B J M O Qu
A C D E M P
A C E L R S
A D E N V Z
A H M O R S
B F I O R X
D E N O S W
D K N O T U
E E F H I Y
E G I N T V
E G K L U Y
E H I N P S
E L P S T U
G I L R U W</pre>
</td>
<td><a href="http://www.barneyb.com/boggle/big_boggle.txt">big_boggle.txt</a></p>
<pre>A A A F R S
A A E E E E
A A F I R S
A D E N N N
A E E E E M
A E E G M U
A E G M N N
A F I R S Y
B J K Qu X Z
C C E N S T
C E I I L T
C E I L P T
C E I P S T
D D H N O T
D H H L O R
D H L N O R
D H L N O R
E I I I T T
E M O T T T
E N S S S U
F I P R S Y
G O R R V W
I P R R R Y
N O O T U W
O O O T T U</pre>
</td>
</tr>
</tbody>
</table>
<h2>Usage</h2>
<p>Here is a simple CFML function which accepts a board definition and returns an array representing a "roll" of the grid:</p>
<pre>&lt;cffunction name="roll" output="false" returntype="array"&gt;

   &lt;cfargument name="board" type="string" required="true" /&gt;
   &lt;cfset var result = [] /&gt;
   &lt;cfloop list="#board#" index="die" delimiters="#chr(10)#"&gt;

      &lt;cfset die = listToArray(die, ' ') /&gt;
      &lt;cfset arrayAppend(result, die[randRange(1, arrayLen(die))]) /&gt;
   &lt;/cfloop&gt;
   &lt;cfset createObject('java', 'java.util.Collections').shuffle(result) /&gt;
   &lt;cfreturn result /&gt;
&lt;/cffunction&gt;
</pre>
<p>And the result of executing it on the original board:</p>
<pre>[N, T, W, A, B, Qu, B, D, L, M, D, H, D, L, G, V]
</pre>
<p>Here's a Groovy Closure which does the same thing:</p>
<pre>{
   it = it.tokenize('\n')
      .collect{ it.tokenize(' ') }
      .collect{ it[new Random().nextInt(it.size)] }
   Collections.shuffle(it) // icky!
   it
}
</pre>
<p>And the result of executing it on the big board:</p>
<pre>[N, E, G, N, N, C, S, A, F, E, U, N, H, I, P, H, C, T, T, O, I, O, Qu, T, T]
</pre>
<p>NB: The source for this post can be found at <a href="http://www.barneyb.com/boggle/">http://www.barneyb.com/boggle/</a>.Â  Any updates I may have will go there.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2011/07/20/boggle-board/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groovy Gravity Processing</title>
		<link>https://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/#comments</comments>
		<pubDate>Fri, 28 May 2010 21:42:29 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1534</guid>
		<description><![CDATA[Joshua (a coworker) and I have been talking about gravity simulation for a while, and this week I threw together a very simple model to do exactly that.Â  This grew out of a game called Flotilla that he came across somewhere and has been working with the developer to add a network multiplayer mode.Â  Flotilla, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.joshuafrankamp.com/">Joshua</a> (a coworker) and I have been talking about gravity simulation for a while, and this week I threw together a very simple model to do exactly that.Â  This grew out of a game called <a href="http://www.blendogames.com/flotilla/">Flotilla</a> that he came across somewhere and has been working with the developer to add a network multiplayer mode.Â  Flotilla, however, doesn't have a concept of gravity, and doesn't really have an explicit concept of mass either, except the implicit stuff in it's acceleration constraints.</p>
<p>Gravity, however, is kind of nasty to work with (from a computational perspective), particularly in a game situation (where you want realism, but not so real the game play sucks).Â  Fortunately, it's also exactly the kind of thing that I enjoy wasting my free time playing with.Â  So I threw together a simple model in Groovy, including a little type system and DSL to help keep my numbers straight.</p>
<p>So now when I divide a Force by a Mass, I'll get an Acceleration back.Â  Or if I multiply an Acceleration by a Time, I'll get a Velocity.Â  This was a huge win.Â  In the world of paper calculations, you don't do just arithmetic, you do unit algebra as well, which helps you ensure your answer makes sense (e.g., if you solve for velocity and get units of "meters per kilogram second", you screwed up somewhere).Â  But with a computer you don't have units, so I employed a simple type system to afford the same check I'd usually get from unit algebra.Â  And Groovy makes it remarkably easy to create both an expressive type system and a simple syntax (via operator overloading).</p>
<p>Then I hacked up Processing ever so slightly so I could implement a PApplet in Groovy and avoid the compilation step, and built a simple viewer for the model.Â  Emphasis on "simple".Â  Here's a capture with three bodies:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-1.png"><img class="aligncenter size-full wp-image-1535" title="gravity-1" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-1.png" alt="" width="648" height="509" /></a></p>
<p>The bodies' sizes represent their relative mass, the green lines represent gravitation between them, the red lines are the velocity vector (per body), and the pink lines are acceleration (also per body).Â  Here's a few seconds later in the same simulation:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-2.png"><img class="aligncenter size-full wp-image-1536" title="gravity-2" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-2.png" alt="" width="648" height="509" /></a></p>
<p>Now, because the bodies are far closer, the forces between them are much greater, which is going to result in a couple fairly impressive slingshots in a moment.Â  They've also picked up a fair amount of speed, though their active acceleration has surpassed their velocities (i.e., slingshots are imminent).Â  Here's after the slingshots have happened:</p>
<p><a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-3.png"><img class="aligncenter size-full wp-image-1537" title="gravity-3" src="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/05/gravity-3.png" alt="" width="650" height="510" /></a></p>
<p>After the two larger bodies slingshotted around each other, the two smaller bodies did the same thing, resulting in a <em>rapidly</em> expanding model.Â  As you can see the forces are falling away, though the smallest and largest bodies will soon meet up and cross paths.Â  The velocity of the little one is high enough that the big one can't slow it down enough to do more than deflect it upward a bit.</p>
<p><a href="http://processing.org/">Processing</a> again completely delivered on it's promise of providing a remarkably simple way to sketch out visual stuff.Â  Simple event handling, simple setup, a simple draw loop, and solid primitives.Â  I need to do a little mucking about, but adding 3D support (which the model handles, but the viewer doesn't) will be similarly trivial: flip the "use 3D" bit, and add 'z' coordinates from the model in the various calls.Â  Very nice, especially when coupled with the <a href="http://groovy.codehaus.org/">Groovy</a> syntax and capabilities.</p>
<p>An interesting project, though we'll see how generally useful.Â  Code, of course, is <a href="http://subversion.assembla.com/svn/gravity/trunk/">available from SVN</a>.Â  It's a single Eclipse project, including Groovy, Processing, the hacked PApplet (from Processing), the model and the viewer applet.Â  Check it out and run driver.groovy to see it in action.Â  While running SPACE will pause/unpause the action, though there is currently no way to rewind/reset the simulation.Â  If you don't want to check out the project, you can <a href="http://www.assembla.com/code/gravity/subversion/nodes">browse it directly</a>.Â  The interesting bits are in the /src/com/barneyb/gravity/ package.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/05/28/groovy-gravity-processing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tulsa CFUG Presentation (CFGroovy)</title>
		<link>https://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/#comments</comments>
		<pubDate>Wed, 26 May 2010 15:35:35 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1526</guid>
		<description><![CDATA[Yesterday I presented CFGroovy to the Tulsa CFUG via Connect.Â  The recording is now available on Connect, thanks to Steve.Â  You can also grab the slidedeck (as a PDF) I skimmed through, and of course, the CFGroovy framework itself (project page, core SVN, demo SVN), including the demo files that I showed. Â Note that the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I presented CFGroovy to the Tulsa CFUG via Connect.Â  The recording is now <a href="http://adobechats.adobe.acrobat.com/p20888993/">available on Connect</a>, thanks to Steve.Â  You can also grab the <a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/04/Polyglot_Programming.pdf">slidedeck (as a PDF)</a> I skimmed through, and of course, the CFGroovy framework itself (<a href="http://www.barneyb.com/barneyblog/projects/cfgroovy2/">project page</a>, <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy2/trunk/engine/">core SVN</a>, <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy2/trunk/demo/">demo SVN</a>), including the demo files that I showed. Â Note that the slidedeck is actually titled 'Polyglot Programming' and served as an introduction as to <em>why</em> you might want to use Groovy (or another language) before delving into <em>how</em> you'd actually do it.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/05/26/tulsa-cfug-cfgroovy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Groovy DataSources for Railo</title>
		<link>https://www.barneyb.com/barneyblog/2010/05/25/groovy-datasources-for-railo/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/05/25/groovy-datasources-for-railo/#comments</comments>
		<pubDate>Tue, 25 May 2010 16:39:27 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[railo]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1522</guid>
		<description><![CDATA[If you've ever wanted to do raw JDBC stuff in your ColdFusion applications, you probably know that you can get a javax.sql.DataSource via this code:
createObject("java", "coldfusion.server.ServiceFactory")
  .dataSourceService.getDatasource("myDSN")
Unfortunately, this doesn't work on Railo, because the result isn't actually a javax.sql.DataSource, it just looks like one (see RAILO-43).  To put that another way, it's duck typed.
Fortunately, [...]]]></description>
			<content:encoded><![CDATA[<p>If you've ever wanted to do raw JDBC stuff in your ColdFusion applications, you probably know that you can get a javax.sql.DataSource via this code:</p>
<pre>createObject("java", "coldfusion.server.ServiceFactory")
  .dataSourceService.getDatasource("myDSN")</pre>
<p>Unfortunately, this doesn't work on Railo, because the result isn't actually a javax.sql.DataSource, it just looks like one (see <a ="https://jira.jboss.org/browse/RAILO-43">RAILO-43</a>).  To put that another way, it's duck typed.</p>
<p>Fortunately, Groovy's "fake" interfaces make beating the typechecks fairly trivial (if kind of ugly):</p>
<pre><cfset variables.my.datasource = createObject("java", "coldfusion.server.ServiceFactory")
  .dataSourceService.getDatasource(my.dsn) />
<g:script>
  def rds = variables.my.datasource
  variables.my.datasource = {
    rds.getConnection()
  } as javax.sql.DataSource
</g:script></pre>
<p>The CFSET gets the "datasource" as normal, and then the little Groovy scriptlet simply wraps it with a closure and tells it to pretend to be a javax.sql.DataSource. The game Escape from Tarkov has one important feature: after your death in a RAID, you lose your equipment. To prevent the loss of important equipment in the game, there are special sites with <a href="https://needmana.com/wow-gold/escape-from-tarkov-currency-and-items/">eft roubles</a> you can always get top equipment and kill all pepegas squad. The items you store from needmana will not disappear. There are three types of containers in total. Alpha, Beta, and Gamma. These containers differ in their size. Usually, these containers should store the most important equipment-maps, ammunition, keys, and so on.  In this case we're assuming that the only method on DataSource that will be invoked is getConnection(), which is the usual case.  If you need to support other methods you'd need to go the Map-as-interface route.</p>
<p>Now we can use variables.my.datasource as a javax.sql.DataSource.  Yay!  Unfortunately, you have to use this sort of snippet everywhere you need a DataSource in your Railo apps, but hopefully that'll get fixed.</p>
<p>For more info on Groovy interfaces, the docs are at <a ="http://groovy.codehaus.org/Groovy+way+to+implement+interfaces">http://groovy.codehaus.org/Groovy+way+to+implement+interfaces</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/05/25/groovy-datasources-for-railo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFGroovy at the Tulsa CFUG on May 25th</title>
		<link>https://www.barneyb.com/barneyblog/2010/05/18/cfgroovy-at-tulsa-cfug-may-25/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/05/18/cfgroovy-at-tulsa-cfug-may-25/#comments</comments>
		<pubDate>Tue, 18 May 2010 16:35:52 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1520</guid>
		<description><![CDATA[Next Tuesday (May 25th), I will be presenting CFGroovy to the Tulsa CFUG via Connect.Â  Details are at http://www.tulsacfug.org/meetings.cfm, but the important bit is that it's at 12:30 central time, not in the evening.Â  Steve Bryant &#8211; who manages the group &#8211; graciously extended a general invitation to anyone else who would like to join [...]]]></description>
			<content:encoded><![CDATA[<p>Next Tuesday (May 25th), I will be presenting CFGroovy to the Tulsa CFUG via Connect.Â  Details are at <a href="http://www.tulsacfug.org/meetings.cfm">http://www.tulsacfug.org/meetings.cfm</a>, but the important bit is that it's at 12:30 central time, not in the evening.Â  Steve Bryant &#8211; who manages the group &#8211; graciously extended a general invitation to anyone else who would like to join via Connect.Â  I'll post again with more details as we get closer to the event.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/05/18/cfgroovy-at-tulsa-cfug-may-25/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Polyglot Programming at cf.objective()</title>
		<link>https://www.barneyb.com/barneyblog/2010/04/23/polyglot-programming-at-cf-objective/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/04/23/polyglot-programming-at-cf-objective/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 19:00:10 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1484</guid>
		<description><![CDATA[This afternoon I presented on Polyglot Programming at cf.objective() 2010.Â  Unlike most presentations I give, this one has almost no code, so the slidedeck (as a PDF) is the whole shebang.Â  The in-deck content is admittedly light; really just an outline to follow along as I talked.Â  The short version of the verbal part is:
Using [...]]]></description>
			<content:encoded><![CDATA[<p>This afternoon I presented on Polyglot Programming at cf.objective() 2010.Â  Unlike most presentations I give, this one has almost no code, so the <a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2010/04/Polyglot_Programming.pdf">slidedeck (as a PDF)</a> is the whole shebang.Â  The in-deck content is admittedly light; really just an outline to follow along as I talked.Â  The short version of the verbal part is:</p>
<blockquote><p>Using multiple languages has a bit of a learning curve but it pays off, and more quickly than you think.Â  Language selection and design is a vital aspect to being a successful developer, both for individual projects and as part of your continuing career.</p></blockquote>
<p>I'll probably give the presentation again on CFMeetup at some point this year, and maybe at a user group or two, so if you missed it all is not lost.Â  Unfortunately (or fortunately), cf.objective() is so content-rich that it's hard to get to every session you want, so if you missed it you can probably get a second chance.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/04/23/polyglot-programming-at-cf-objective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CF9 ORM and CFGroovy</title>
		<link>https://www.barneyb.com/barneyblog/2010/04/05/cf9-orm-and-cfgroovy/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/04/05/cf9-orm-and-cfgroovy/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 21:34:11 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1421</guid>
		<description><![CDATA[As I've stated at various times and places, CFGroovy 1 (with Hibernate integration) has been superceded by the ORM functionality now available in ColdFusion 9 and soon to be available in Railo 3.Â  It has never been my intention to compete with the CFML vendors in the Hibernate space &#8211; without access to the engine [...]]]></description>
			<content:encoded><![CDATA[<p>As I've stated at various times and places, <a href="http://www.barneyb.com/barneyblog/projects/cfgroovy/">CFGroovy 1</a> (with Hibernate integration) has been superceded by the ORM functionality now available in ColdFusion 9 and soon to be available in Railo 3.Â  It has never been my intention to compete with the CFML vendors in the Hibernate space &#8211; without access to the engine internals there is simply no way I can do as good a job as the vendors.</p>
<p>As of today I am officially declaring CFGroovy 1 abandonware.</p>
<p>I still use CFGroovy 1 on a couple personal projects and at Mentor (where I work) we run our entire service tier on CFGroovy 1.Â  So it is by no means unsuitable for production deployment, but no new development should take place on it.Â  It does not run on CF9 without modifying your CF9 installation, and the same will be true of Railo when it supports Hibernate as well.Â  So you should assume that if you're upgrading a CFGroovy 1 application from CF7/8 to CF9, part of the upgrade process will be converting to CF9 ORM.Â  This is not nearly as difficult as you would expect &#8211; Groovy beans directly translate to persistent CFCs and your Groovy business logic can be encapsulated with <a href="http://www.barneyb.com/barneyblog/projects/cfgroovy2/">CFGroovy 2</a> scriptlets.Â  Existing scriptlets (and non-persistent helper classes) should transfer without any modification.Â  The only exception is that CFGroovy 2 does not provide the concept of a Groovy classpath, but that's typically only required for entities.</p>
<p><a href="http://www.barneyb.com/barneyblog/projects/cfgroovy2/">CFGroovy 2</a> is <em><strong>not</strong></em> affected by this; it is alive and well and will continue to be supported, developed, and widely used for a long time.Â  As well as being all kinds of useful, it is a crucial part of upgrading CFGroovy 1 applications.</p>
<p>From this point on the term "CFGroovy" will refer specifically to what has until now been called CFGroovy 2.Â  The Hibernate integration is the only reason anyone should be using CFGroovy 1 as CFGroovy is superior in every way when you're only looking for scriptlet support.Â  It provides not only a richer environmental binding, it also supports arbitrary JSR-223 languages, will transparently bootstrap Groovy (via JavaLoader) if it's not on your classpath, provides hooks for CFML ORM (CFML, not just CF9) integration, and works in a significantly more streamlined and efficient fashion.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/04/05/cf9-orm-and-cfgroovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>
	</channel>
</rss>
