<?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>LAMBDAPHONE &#187; algorithm</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/algorithm/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:58:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>17&#215;17: A Simulated Annealing approach using thresholds</title>
		<link>http://coder.bsimmons.name/blog/2010/07/17x17-a-simulated-annealing-approach-using-thresholds/</link>
		<comments>http://coder.bsimmons.name/blog/2010/07/17x17-a-simulated-annealing-approach-using-thresholds/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 17:05:07 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[heuristics]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=443</guid>
		<description><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no</em></p></blockquote><p>&#8230; <a href="http://coder.bsimmons.name/blog/2010/07/17x17-a-simulated-annealing-approach-using-thresholds/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no rectangle is formed from four cells of the same color.</em></p></blockquote>
<p>This is something I&#8217;ve been wanting to play with for months now, but haven&#8217;t made the time to implement: I wondered if <a href="http://en.wikipedia.org/wiki/Simulated_annealing">simulated annealing</a> techniques could be effective in finding a complete grid covering. </p>
<p>We would simply start with four copies of the 74-color grid and swap their rows and columns around, within each color set, trying to cover all of the cells by the union of the four subsets. So all of the sets of cells of a single color are fundamentally simply different permutations of the same 74-cell rectangle-free Graph. </p>
<p>Here is an illustration of the concept. Our algorithm starts with all four colored sets of cell overlapping (the red cells are on top, covering the other three colors):</p>
<p><a href="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-74-coloring.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-74-coloring-285x300.png" alt="Illustration showing four sets of colored cells, all overlapping in every cell" title="Screenshot - 74-coloring" width="285" height="300" class="aligncenter size-medium wp-image-446" /></a></p>
<p>&#8230;then we swap two rows or two columns from a colored subset of cells, until the four colored subsets spread out covering as much of the grid as possible. Here we cover all but 21 cells:</p>
<p><a href="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-20-free.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-20-free-300x291.png" alt="Four layers of cells of colors RGBY, spread out to cover most of the grid" title="Screenshot - 20 free" width="300" height="291" class="aligncenter size-medium wp-image-447" /></a></p>
<p><span id="more-443"></span></p>
<h2>A Brief Intro to Simulated Annealing</h2>
<p>Simulated Annealing is a bit of an intimidating term (has its origins in <a href="http://en.wikipedia.org/wiki/Annealing_%28metallurgy%29">metallurgy</a> of all things), but the idea is simple: you start off with an initial solution (in my case, four sets of cells, all of which overlap) and then you mutate it randomly by choosing a random &#8220;neighbor&#8221; solution (in my case, a grid in which two rows or two columns of the same color are swapped).</p>
<p>You score these solutions so that you can compare a current solution with a proposed mutated solution, and here&#8217;s the key: </p>
<blockquote><p>
You begin by accepting nearly every mutation, whether it improves your solution or not. But as the procedure progresses you become more picky about &#8220;how much worse&#8221; a new solution can be from the previous one.
</p></blockquote>
<p>So in the classic <a href="http://en.wikipedia.org/wiki/Travelling_salesman_problem">Traveling Salesman Problem</a> a neighbor solution would be a new route that goes from city C to city E, where in the last solution we went from city E to city C.</p>
<h3>Threshold Acceptance</h3>
<p>There are various ways of accomplishing the task of &#8220;ratcheting down&#8221; the computation over time. The traditional method (the method most matching the metallurgical metaphor, if you will) is to have a function that computes the probability of a proposed change being accepted. This probability function changes over time, such that as we progress it becomes more and more unlikely that a solution worse than the previous will be accepted.</p>
<p>Another method, and the one I chose to implement, seems to be referred to as <a href="http://comisef.wikidot.com/concept:thresholdaccepting">Threshold Accepting</a>; instead of having a probability function, you accept all mutations that are below a certain threshold of change from the previous solution. The threshold becomes more strict over time.</p>
<p>So in our case we might start off with a threshold of five, meaning that we will accept all changes that give us a <em>worse</em> solution of no more than 5 new un-colored cells. So for example: if swapping blue rows 5 and 12 create a new solution with 6 fewer colored (covered) cells from the previous solution (i.e. a worse solution by six), then it won&#8217;t be accepted by our meta-algorithm at this stage.</p>
<h2>Notes on the implementation</h2>
<p>The approach I tried to describe above was really attractive to me because it short-circuits the whole complex &#8220;rectangle-free&#8221; constraint entirely. We simply start with a known rectangle-free subset and see if we can make four copies fit together. </p>
<p>Also, because we swap two rows or columns at a time, we need only look at the local change of score produced by the swap and then add it to the global score to obtain the new global score.</p>
<p>The astronomical number (<code>17!^2</code>) of possible permutations of a single rectangle-free subset give me hope that this approach could work, but that is an open question as far as I know. </p>
<p>I wrote this first draft of the script in haskell (as usual), and was happy with how fast it is, thanks in large part to the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/vector">vector library</a>, which was a pleasure to work with. The code uses 4 pairs of <code>Vector</code>s (arrays of Ints), 8 in total, each of which represent a row or column ordering of one of the four colors. </p>
<p>We store the original 74-cell rectangle-free subset as a 2D <code>Array (Int,Int) Bool</code>. The pairs of Vectors act as references to row or column slices of this 2D array.</p>
<p>When we want to score a swap, we have to &#8220;render&#8221; all four colors of the pair of rows/columns in question using our 2D reference array. Then a swap consists of swapping two Ints in a single Vector. This is much more friendly on more poor laptop than if we were to try storing all four color subsets as 2D arrays and swapping them around!</p>
<p>You can <a href="http://coder.bsimmons.name/code/simulatedAnnealing.lhs">download the code here</a>, but mind it isn&#8217;t incredibly pretty.</p>
<h2>Initial findings</h2>
<p>The best I&#8217;ve done with this initial version is a grid with 19 empty cells:</p>
<p><a href="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-19-free.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/Screenshot-19-free-283x300.png" alt="A 17 by 17 grid showing all but 19 cells colored" title="Screenshot - 19 free" width="283" height="300" class="aligncenter size-medium wp-image-448" /></a></p>
<p>It is obvious though that the heuristic needs a lot of tuning, and that in my case the &#8220;Threshold Accepting&#8221; approach isn&#8217;t working well. That is because it is far too granular: we get from complete disorder to a minimum in just a handful of threshold rounds.</p>
<p>Here is a quick graph overlaying two runs, one of which starts with a threshold (each threshold round bracketed in black) of 5, the other (in blue) starts with a threshold of 2. The Y-axis is the number of uncolored cells in the grid at the current solution:</p>
<p><a href="http://coder.bsimmons.name/blog/wp-content/uploads/5-2.combined-annotated.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/5-2.combined-annotated-300x136.png" alt="" title="5-2.combined-annotated" width="300" height="136" class="aligncenter size-medium wp-image-449" /></a></p>
<p>You can see that both basically look like <a href="http://en.wikipedia.org/wiki/Brownian_motion">random Brownian walks</a> during the course of a threshold round, and quickly drop to a lower energy level (better solution) as soon as the threshold is tightened. Most dramatic is the jump when we go from 2 to 1.</p>
<p>This looks like we&#8217;re being thrust into a local minima, which is the opposite of what we want here. But whether a more finely-tuned annealing schedule can do better is anyone&#8217;s guess.</p>
<h2>What&#8217;s next?</h2>
<p>It should be very simple to implement a more traditional annealing procedure that would ease us into lower &#8220;energy levels&#8221; without the harsh dives we get from using only a handful of threshold levels. So that is what is next on the agenda for this problem.</p>
<p>If this annealing business looks promising after I master the black art of &#8220;tuning the meta-heuristic&#8221;, it would be cool to come up with a single-coloring algorithm, capable of generating rectangle free colorings of 72,73, or 74 cells. We would then feed those solutions into our annealing framework, finding the best combinations of colorings via a genetic algorithm or the like.</p>
<p>But that leads to the question I&#8217;ve posed earlier: it is sometimes trivial to determine if two colorings are &#8220;unique&#8221; (i.e. by counting colored cells in rows and columns); but when it isn&#8217;t trivial, determining whether two colorings are <em>&#8220;equivalent&#8221;</em> seems to be a very difficult problem. </p>
<p>What a hole I&#8217;ve fallen into&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/07/17x17-a-simulated-annealing-approach-using-thresholds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Jam 2010: Incrementing a Binary Counter</title>
		<link>http://coder.bsimmons.name/blog/2010/05/code-jam-2010-incrementing-a-binary-counter/</link>
		<comments>http://coder.bsimmons.name/blog/2010/05/code-jam-2010-incrementing-a-binary-counter/#comments</comments>
		<pubDate>Sun, 09 May 2010 21:36:44 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[cellularAutomata]]></category>
		<category><![CDATA[CodeJam]]></category>
		<category><![CDATA[recursion]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=406</guid>
		<description><![CDATA[<h3>The Problem</h3>
<p><a href="http://code.google.com/codejam/contest/dashboard?c=433101#s=p0">Problem A</a> in the qualifying round of this year&#8217;s Google CodeJam contest was really clever. The problem used a classic made-for-TV gadget from the 80s: <a href="http://www.youtube.com/watch?v=-XUOhjW2AXM">The Clapper™</a> (&#8220;snapper&#8221; in google&#8217;s version) and went like this:</p>
<blockquote><p>
The</p></blockquote><p>&#8230; <a href="http://coder.bsimmons.name/blog/2010/05/code-jam-2010-incrementing-a-binary-counter/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<h3>The Problem</h3>
<p><a href="http://code.google.com/codejam/contest/dashboard?c=433101#s=p0">Problem A</a> in the qualifying round of this year&#8217;s Google CodeJam contest was really clever. The problem used a classic made-for-TV gadget from the 80s: <a href="http://www.youtube.com/watch?v=-XUOhjW2AXM">The Clapper™</a> (&#8220;snapper&#8221; in google&#8217;s version) and went like this:</p>
<blockquote><p>
The Snapper is a clever little device that, on one side, plugs its input plug into an output socket, and, on the other side, exposes an output socket for plugging in a light or other device.</p>
<p>When a Snapper is in the ON state and is receiving power from its input plug, then the device connected to its output socket is receiving power as well. When you snap your fingers &#8212; making a clicking sound &#8212; any Snapper receiving power at the time of the snap toggles between the ON and OFF states.</p>
<p>In hopes of destroying the universe by means of a singularity, I have purchased N Snapper devices and chained them together by plugging the first one into a power socket, the second one into the first one, and so on. The light is plugged into the Nth Snapper.</p>
<p>Initially, all the Snappers are in the OFF state, so only the first one is receiving power from the socket, and the light is off. I snap my fingers once, which toggles the first Snapper into the ON state and gives power to the second one. I snap my fingers again, which toggles both Snappers and then promptly cuts power off from the second one, leaving it in the ON state, but with no power. I snap my fingers the third time, which toggles the first Snapper again and gives power to the second one. Now both Snappers are in the ON state, and if my light is plugged into the second Snapper it will be on. </p>
<p>I keep doing this for hours. Will the light be on or off after I have snapped my fingers K times? The light is on if and only if it&#8217;s receiving power from the Snapper it&#8217;s plugged into.
</p></blockquote>
<p><span id="more-406"></span><br />
It&#8217;s a great problem because we have a situation that is easily modeled with a computer program, and yet a naive solution will be far too inefficient to process the inputs that google provides (e.g. 10^8 claps).</p>
<p>Here is a direct-to-code translation of the functioning of a &#8220;chain of snappers&#8221; implemented in (very verbose) Haskell:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;Main<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span><br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;ClapperChain&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Type">Bool</span>]<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;clapOnOff&nbsp;<span class="Statement">::</span>&nbsp;ClapperChain&nbsp;<span class="Statement">-&gt;</span>&nbsp;ClapperChain<br />
<span class="Comment">&gt;</span>&nbsp;clapOnOff&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[]<br />
<span class="Comment">&gt;</span>&nbsp;clapOnOff&nbsp;(c<span class="Statement">:</span>cs)&nbsp;<span class="Statement">=</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">if</span>&nbsp;isPowered&nbsp;cs<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">then</span>&nbsp;toggleState&nbsp;c&nbsp;<span class="Statement">:</span>&nbsp;clapOnOff&nbsp;cs<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">else</span>&nbsp;c&nbsp;<span class="Statement">:</span>&nbsp;clapOnOff&nbsp;cs<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;isPowered&nbsp;<span class="Statement">::</span>&nbsp;ClapperChain&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span><br />
<span class="Comment">&gt;</span>&nbsp;isPowered&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Constant">True</span>&nbsp;<span class="Comment">-- at the outlet</span><br />
<span class="Comment">&gt;</span>&nbsp;isPowered&nbsp;(c<span class="Statement">:</span>cs)&nbsp;<span class="Statement">=</span>&nbsp;inOnState&nbsp;c&nbsp;<span class="Statement">&amp;&amp;</span>&nbsp;isPowered&nbsp;cs<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;inOnState&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">id</span><br />
<span class="Comment">&gt;</span>&nbsp;toggleState&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;<br />
<br /></div></p>
<p>We can then look at a few iterations (snaps) and see how the chain changes. <code>True</code> is a &#8220;snapper&#8221; in the ON state:</p>
<blockquote><pre>
*Main> take 4 $ iterate clapOnOff [False,False,False]
[[False,False,False],[False,False,True],[False,True,False],[False,True,True]]</pre>
</blockquote>
<h3>A Solution</h3>
<p>After working out a few iterations on paper I realized that the snappers follow the pattern of an ascending binary number count: <code>000, 001, 010, 011...</code></p>
<p>The lamp will be on when all of the snappers are <code>1s</code> (i.e. in the ON state) which will occur every (2^number_of_snappers) snaps. Thus my solution was simply the following:</p>
<p><blockquote class="vimblock"><br />
caseAlgorithm&nbsp;(n,k)&nbsp;<span class="Statement">=</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;(((k<span class="Statement">+</span><span class="Constant">1</span>)&nbsp;<span class="Statement">`mod`</span>&nbsp;<span class="Constant">2</span><span class="Statement">^</span>n)&nbsp;<span class="Statement">==</span>&nbsp;<span class="Constant">0</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">then</span>&nbsp;ON<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">else</span>&nbsp;OFF<br />
<br /></blockquote></p>
<h3>More Code and Thoughts</h3>
<p>Here is a more terse and better version of the Snapper simulation code I posted above, now simply called <code>increment</code> for incrementing a binary number:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;increment&nbsp;<span class="Statement">::</span>&nbsp;ClapperChain&nbsp;<span class="Statement">-&gt;</span>&nbsp;ClapperChain<br />
<span class="Comment">&gt;</span>&nbsp;increment&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;[]&nbsp;&nbsp;<span class="Comment">-- [] is the outlet</span><br />
<span class="Comment">&gt;</span>&nbsp;increment&nbsp;chain<span class="Statement">@</span>(c<span class="Statement">:</span>cs)&nbsp;&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">and</span>&nbsp;cs&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;<span class="Identifier">not</span>&nbsp;chain<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;c&nbsp;<span class="Statement">:</span>&nbsp;increment&nbsp;cs<br />
<br /></div></p>
<p>We can convert our lists into pretty strings with&#8230;</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;showBinary&nbsp;<span class="Statement">::</span>&nbsp;ClapperChain&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">String</span><br />
<span class="Comment">&gt;</span>&nbsp;showBinary&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Statement">\</span>b<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">if</span>&nbsp;b&nbsp;<span class="Statement">then</span>&nbsp;<span class="Constant">'1'</span>&nbsp;<span class="Statement">else</span>&nbsp;<span class="Constant">'0'</span>)<br />
<br /></div></p>
<p>And play with it like so:</p>
<blockquote><pre>
*Main> map showBinary $ take 9 $ iterate increment  [False,False,False]
["000","001","010","011","100","101","110","111","000"]</pre>
</blockquote>
<p>I liked realizing that a binary count could be represented recursively and <a href="http://en.wikipedia.org/wiki/Counter">mechanically</a>. It led me to look into how <a href="http://www.play-hookey.com/digital/ripple_counter.html">binary</a> <a href="http://www.play-hookey.com/digital/synchronous_counter.html">counter</a> <a href="http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/bincount.html">circuits</a> are implemented in electronics (it turns out The Clapper™  is not generally involved), and got me thinking about <a href="http://en.wikipedia.org/wiki/Cellular_automaton">cellular automata</a>.</p>
<p>A binary counter could be implemented as Cellular Automata in which each bit is an Automaton with two states: an ON/OFF state and a POWERED/UNPOWERED state.</p>
<p>&#8230;although I think POWERED or UNPOWERED would have to be evaluated lazily, which might not fit the model.</p>
<p>Oh well, good luck to everyone doing the competition this year!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/05/code-jam-2010-incrementing-a-binary-counter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>17&#215;17: More about symmetry and a new rotation</title>
		<link>http://coder.bsimmons.name/blog/2010/03/17x17-more-about-symmetry-and-a-new-rotation/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/17x17-more-about-symmetry-and-a-new-rotation/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 19:17:55 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=362</guid>
		<description><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no</em></p></blockquote><p>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/17x17-more-about-symmetry-and-a-new-rotation/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<blockquote><p><em>Note: this is part of a <a href="http://coder.bsimmons.name/blog/tag/17x17/">series of posts</a> is related to the &#8220;<a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17&#215;17 Challenge</a>&#8221; posted by Bill Gasarch. The goal is to color cells of a 17 by 17 grid, using only four colors, such that no rectangle is formed from four cells of the same color.</em></p></blockquote>
<p>In my <a href="http://coder.bsimmons.name/blog/2010/03/17x17-symmetric-single-colorings-and-some-graph-theory/">last post</a>, I gave a symmetrical rotation of the known 74-cell single-coloring. I want to use a slight variation of that grid to show why I think treating the grids as symmetrical will help us in solving this problem.</p>
<p>Here is a new spreadsheet, with several panes you can click through on the bottom. Panes ONE through FIVE represent the first few rows of a single-coloring in which we avoid making any real choices, thanks to a few assumptions we make (I&#8217;ll come back to that).</p>
<p>Orange represents the row we&#8217;re coloring, gray cells are rectangle forming cells (in which marks are not allowed), and blue cells represent what I consider to be the real search-space:</p>
<blockquote><p>
<iframe width='425' height='400' frameborder='0' src='http://spreadsheets.google.com/pub?key=tmOFAqHDqtADZJqwWOeenIw&#038;output=html&#038;widget=true'></iframe></p></blockquote>
<p><em><br />
NOTE: We&#8217;re simply using another automorphism of the original 74-coloring, i.e. a series of rotations that preserve all the significant attributes of the graph. </em></p>
<p><span id="more-362"></span></p>
<h3>Making Coloring Decisions</h3>
<p>We can choose, arbitrarily, to start with a 5-cell row starting on the cell in the upper left. This is our first decision: if it were that in an optimal single-coloring of 17&#215;17 <em>no</em> row with five colored cells shared a cell with <em>any</em> column with five colored cells, then we would have made a poor decision.</p>
<p>But given that in the 74-coloring that we have, <em>all</em> 5-colored-cell rows share a cell with a 5-colored column, we can probably assume that at least one will in our optimal single-coloring. So our first row (in pane 1) is a non-decision.</p>
<p>We continue with the second row by dumping 3 cells as soon as we can (i.e. as far to the left as possible. The only decision made here is in whether to make row two a row of four or five. But as we can see very quickly (and as a shallow search algorithm would see very quickly), making row 2 a five-colored-cell row would force us into forming a 3-cell row out of row five.</p>
<p>So in row 2 we have an easy decision (seeing that we would soon regret creating a 5-cell row) based on our assumption that a good singly-colored grid will have its cells spread evenly over rows &#038; columns. </p>
<p>And we have the non-decision of the column placement of those three cells: because identical columns (in this case empty columns) can be freely swapped without changing anything, there is no need to try every combination of column placement for the row. We put off our decision making for later. </p>
<p>We continue on in the same way.</p>
<h3>Search Ideas</h3>
<p>I&#8217;m coding up a program to try to generate good grids based on some heuristics. I think that a <a href="http://en.wikipedia.org/wiki/Minimax">minimax</a> type solution might be good: in which the coloring of a cell is assigned a point-value based on how many future cells it makes unusable. I could then keep track of which previous cells were complicit in forming potential rectangles and back-track at apparently-bad decisions: i.e. <a href="http://en.wikipedia.org/wiki/Hill_climbing">hill climbing</a>.</p>
<p>I may try to formulate the algorithm like a game and see if I can use the <a href="http://hackage.haskell.org/package/game-tree-0.1.0.0">game-tree module</a> by Colin Adams.</p>
<h3>Conclusion</h3>
<p>It seems to me that the key to the problem of a single-coloring is shrinking the search-space by eliminating false-choices. Treating the graph as it&#8217;s symmetrical (by our definition of symmetrical) automorphism is one way: suddenly the search space becomes the shaded area in the graph above.</p>
<p>Thankfully, my next post will be haskell-related and have nothing to do with Grids.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/17x17-more-about-symmetry-and-a-new-rotation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>17&#215;17: Some Thoughts on the Problem</title>
		<link>http://coder.bsimmons.name/blog/2010/03/17x17-some-thoughts-on-the-problem/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/17x17-some-thoughts-on-the-problem/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 02:32:54 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=344</guid>
		<description><![CDATA[<p><em>I&#8217;ve been puzzling over some of the problems presented by the <a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17 x 17 Challenge</a>, and wanted to share some of what I&#8217;ve learned and have been wondering about. The problem and ultimate goal is to color a 17</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/17x17-some-thoughts-on-the-problem/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>I&#8217;ve been puzzling over some of the problems presented by the <a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17 x 17 Challenge</a>, and wanted to share some of what I&#8217;ve learned and have been wondering about. The problem and ultimate goal is to color a 17 x 17 grid with four colors such that every cell is colored and no rectangle is formed by any four cells of the same color. </em></p>
<h2>Single-Color Subsets</h2>
<p>I&#8217;ve started by trying to find an algorithm to find optimal single-color subsets, i.e. a way of coloring a grid with one color such that no rectangle is formed by the colored cells, and we have the greatest number of cells colored as possible. I started thinking of coloring cells one at a time, following a path based on the notion of an &#8220;extended rectangle&#8221; where the fourth side was longer or shorter than the first, to avoid forming rectangles.</p>
<p>I also noticed that we could traverse all the cells in the <a href="http://www.cs.umd.edu/~gasarch/BLOGPAPERS/17x17.pdf">largest known 17&#215;17 subset</a> by following a simple spiraling algorithm. It didn&#8217;t seem to matter which cell or direction we started in either:</p>
<p><div id="attachment_345" class="wp-caption aligncenter" style="width: 410px"><a href="http://coder.bsimmons.name/blog/wp-content/uploads/17x17.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/17x17-300x235.png" alt="grid traversal algorithm" title="17x17" width="300" height="235" class="size-medium wp-image-345" /></a><p class="wp-caption-text">go until you hit a colored cell, then rotate 90 degrees</p></div><br />
<span id="more-344"></span><br />
This led to a <a href="http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/">simple algorithm</a> that does well in finding pretty good subsets, but doesn&#8217;t find optimal subsets for the larger grids (at least it couldn&#8217;t find a grid of size 74, linked above). The algorithm is something like &#8220;wagging the dog&#8221;, and it&#8217;s surprising that it works as well as it does. I wonder whether the sub-problem of optimal single-colorings has applications to <a href="http://en.wikipedia.org/wiki/Knot_theory">knot theory</a>.</p>
<h3>Optimal Grids</h3>
<p>I generated some optimally-colored grids to see if they all followed this property of being traversable via this &#8220;rotation&#8221; algorithm above. It turns out that some directions and starting points loop before they touch every colored cell. I suspect that will also be the case for the 74-color grid above.</p>
<p>Here are the grids I was able to generate <a href="http://coder.bsimmons.name/blog/2010/02/17x17-brute-force-algorithm-for-an-optimal-rectangle-free-subset/">via brute force</a>:</p>
<p><a href="http://coder.bsimmons.name/blog/wp-content/uploads/grids.png"><img src="http://coder.bsimmons.name/blog/wp-content/uploads/grids-300x108.png" alt="" title="grids" width="300" height="108" class="aligncenter size-medium wp-image-348" /></a></p>
<p>Notice that, as you might guess, colored cells are spread out as evenly as possible among rows and columns (i.e. no two rows differ by more than one in their number of colored cells).</p>
<h4>&#8230;and Symmetry and Rotations</h4>
<p>Also notice the diagonal symmetry that all of the grids exhibit. The 5&#215;5 grid was not symmetrical when it came out of my brute force algorithm, but I was happy to see that I could turn it into the above symmetrical version with a few rotations (a fun puzzle by the way). The symmetry reminds me of creating/solving <a href="http://en.wikipedia.org/wiki/Algorithmics_of_sudoku">sudoku</a> and I wonder if this is a similar constraint-solving problem.</p>
<p>It would be interesting to see if the 17&#215;17 grid was symmetrical in one of its possible rotations. I would like to look into that as well as code up a symmetrical variation of the algorithm I described in my <a href="http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/">last</a> post. If all optimal subsets were symmetrical, that could make the search-space considerably smaller.</p>
<p>I also wonder whether <em>all</em> subsets of the same size are not simply rotations of the others. This seems to be the case for the smaller optimal subsets in the image above.</p>
<h2>Four-Coloring the 17&#215;17 Grid</h2>
<p>The author suggests that a 17&#215;17 grid is an edge case, meaning that it may or may not be possible to four-color. A single-coloring of at least 73 must be possible in order for a four-coloring to be possible: <code>73 + 72 + 72 + 72 = 289 = 17 x 17</code>. The author of the challenge has found one of size 74.</p>
<p>Given the difficulty of finding a single-coloring (74 colors seems to be the largest known), we can perhaps assume that each of the four <em>single-color subsets</em> will be evenly distributed with 4 or 5 cells per row/column. </p>
<p>Thus <em>every</em> row of a successful four coloring will have <code>4 + 4 + 4 + 5 = 17</code> in each of the four colors respectively.</p>
<p>There are 2380 possible unique 17-length rows with four colored cells in the row. There are 6188 with 5 colored. Here&#8217;s the code I used for that fun fact:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment">-- finding promising rows:</span><br />
allRowsSize&nbsp;sz&nbsp;n<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;sz&nbsp;<span class="Statement">==</span>&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;<span class="Identifier">replicate</span>&nbsp;n&nbsp;&nbsp;<span class="Constant">True</span>&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;n&nbsp;&nbsp;<span class="Statement">==</span>&nbsp;<span class="Constant">0</span>&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;<span class="Identifier">replicate</span>&nbsp;sz&nbsp;<span class="Constant">False</span>&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [&nbsp;<span class="Constant">True</span><span class="Statement">:</span>as&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;as&nbsp;<span class="Statement">&lt;-</span>&nbsp;allRowsSize&nbsp;(sz<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;(n<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;]&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">++</span>&nbsp;[&nbsp;<span class="Constant">False</span><span class="Statement">:</span>as&nbsp;<span class="Statement">|</span>&nbsp;as&nbsp;<span class="Statement">&lt;-</span>&nbsp;allRowsSize&nbsp;(sz<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;n&nbsp;]<br />
<br /></blockquote></p>
<h3>Going Forward</h3>
<p>If the couple ideas I still have for an optimal single-coloring don&#8217;t work out, it may be interesting to try to &#8220;deconstruct&#8221; the known 74-coloring, treating it like the algorithm I developed in my last post, but in reverse, noticing the &#8220;choices&#8221; made. </p>
<p>After giving up on a deterministic single-coloring algorithm it might be interesting to investigate some kind of ladder climbing algorithm that looks at trying to consolidate rectangle-forming squares.</p>
<p>Finally, an approach that might have been the easiest all along, would be to take the author&#8217;s 74-coloring above and try to generate 4 different permutations of sizes 73 and 72 that could fit together. We don&#8217;t learn too much from that though.</p>
<p>I&#8217;m really interested to know your thoughts on the problem as well. So leave a comment if you like!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/17x17-some-thoughts-on-the-problem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>17&#215;17: Deterministic algorithm for single-coloring a grid</title>
		<link>http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 08:17:55 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[17x17]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=337</guid>
		<description><![CDATA[<p><em>I finally got some time to code up a messy script to test out a few variations of an algorithm to generate rectangle-free single colorings of a grid, as part of a <del datetime="2010-03-02T18:50:50+00:00">lazy</del> humble effort to solve the <a</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>I finally got some time to code up a messy script to test out a few variations of an algorithm to generate rectangle-free single colorings of a grid, as part of a <del datetime="2010-03-02T18:50:50+00:00">lazy</del> humble effort to solve the <a href="http://blog.computationalcomplexity.org/2009/11/17x17-challenge-worth-28900-this-is-not.html">17 x 17 challenge</a>. </em></p>
<p>This post is going to be a bit of a code-dump. The algorithm is essentially: </p>
<ol>
<li>color cell, </li>
<li>turn to the right, </li>
<li>stop on first non-rectangle forming cell, </li>
<li>
if the cell is uncolored, color it and turn to the right, else if the cell was already colored and has been entered from this direction already, then skip it, else turn to the right</li>
</ol>
<p><span id="more-337"></span><br />
I&#8217;m not sure if an algorithm exists yet to find rectangle free colorings. The authors of the challenge seem to know of no optimal deterministic algorithm.</p>
<p>The code below produces a rectangle-free subset of 68 colored cells on a 17&#215;17 grid. Apparently the <a href="http://www.cs.umd.edu/~gasarch/BLOGPAPERS/17x17.pdf">largest known subset</a> is <del datetime="2010-03-02T18:50:50+00:00">73</del> 74 (important because <del datetime="2010-03-03T15:11:51+00:00">4 subsets of length 73 or 72</del> one subset of size 73 and three of size 72 would fill a 17&#215;17 grid if they could be made to fit together). So hopefully one of the variations of the algorithm above that I have in mind will be able to match or beat that. </p>
<p>We don&#8217;t yet have logic for stopping once a row or column is exhausted, so it will just hang:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">module</span>&nbsp;Main<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span><br />
<br />
<span class="PreProc">import</span>&nbsp;Data.List<br />
<span class="PreProc">import</span>&nbsp;<span class="PreProc">qualified</span>&nbsp;Data.Map <span class="PreProc">as</span>&nbsp;M<br />
<span class="PreProc">import</span>&nbsp;Data.Maybe<br />
<br />
<br />
<br />
<span class="Comment">-- we move clockwise:</span><br />
<span class="Type">data</span>&nbsp;Direction&nbsp;<span class="Statement">=</span>&nbsp;W&nbsp;<span class="Statement">|</span>&nbsp;N&nbsp;<span class="Statement">|</span>&nbsp;E&nbsp;<span class="Statement">|</span>&nbsp;S&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;(<span class="Type">Show</span>,&nbsp;<span class="Type">Ord</span>,&nbsp;<span class="Type">Eq</span>,&nbsp;<span class="Type">Enum</span>)<br />
<br />
<span class="Type">data</span>&nbsp;Cell&nbsp;<span class="Statement">=</span>&nbsp;FormsRectangle<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;Colored&nbsp;DirectionsEntered<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br />
<br />
<span class="Comment">-- to avoid loops, keep track of which way we've entered a cell :</span><br />
<span class="Type">type</span>&nbsp;DirectionsEntered&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;Direction&nbsp;]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
<span class="Type">type</span>&nbsp;Grid&nbsp;<span class="Statement">=</span>&nbsp;M.Map&nbsp;(<span class="Type">Int</span>,<span class="Type">Int</span>)&nbsp;Cell<br />
<br />
singleColoring&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[(<span class="Type">Int</span>,<span class="Type">Int</span>)]<br />
singleColoring&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;colorCells&nbsp;M.empty&nbsp;dI&nbsp;turns&nbsp;posI&nbsp;<span class="Type">where</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- start as we enter lower left corner cell...</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;posI&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Constant">1</span>,<span class="Constant">1</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- ...moving to the left:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;(dI<span class="Statement">:</span>turns)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">cycle</span>&nbsp;[W&nbsp;<span class="Statement">..</span>]<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- we wrap when moving off the grid:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;mv&nbsp;d&nbsp;<span class="Statement">=</span>&nbsp;wrapped&nbsp;<span class="Statement">.</span>&nbsp;move&nbsp;d<br />
&nbsp;&nbsp;&nbsp;&nbsp;wrapped&nbsp;(x,y)&nbsp;<span class="Statement">=</span>&nbsp;(w&nbsp;x,&nbsp;w&nbsp;y)&nbsp;&nbsp;<span class="Type">where</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;<span class="Constant">0</span>&nbsp;<span class="Statement">=</span>&nbsp;n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;x&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">if</span>&nbsp;x&nbsp;<span class="Statement">==</span>&nbsp;(n<span class="Statement">+</span><span class="Constant">1</span>)&nbsp;<span class="Statement">then</span>&nbsp;<span class="Constant">1</span>&nbsp;<span class="Statement">else</span>&nbsp;x<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- our coloring algorithm:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;colorCells&nbsp;g&nbsp;d&nbsp;ts<span class="Statement">@</span>(d'<span class="Statement">:</span>ds)&nbsp;xy&nbsp;<span class="Statement">=</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;M.lookup&nbsp;xy&nbsp;g&nbsp;<span class="Statement">of</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- color this cell:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">Nothing</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;xy&nbsp;<span class="Statement">:</span>&nbsp;turnUpdating&nbsp;(color&nbsp;xy&nbsp;d)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- NO LOGIC YET FOR STOPPING WHEN WE&quot;VE EXHAUSTED A ROW:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">Just</span>&nbsp;FormsRectangle&nbsp;<span class="Statement">-&gt;</span>&nbsp;skip<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">Just</span>&nbsp;(Colored&nbsp;es)&nbsp;<span class="Statement">-&gt;</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;d&nbsp;<span class="Statement">`elem`</span>&nbsp;es<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">--then []</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">then</span>&nbsp;skip<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- cell colored and we haven't entered this way yet; turn:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">else</span>&nbsp;turnUpdating&nbsp;(addEntered&nbsp;d&nbsp;es&nbsp;xy)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;skip&nbsp;<span class="Statement">=</span>&nbsp;colorCells&nbsp;g&nbsp;d&nbsp;ts&nbsp;(mv&nbsp;d&nbsp;xy)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;turnUpdating&nbsp;f&nbsp;<span class="Statement">=</span>&nbsp;colorCells&nbsp;(f&nbsp;g)&nbsp;d' ds&nbsp;(mv&nbsp;d' xy)<br />
<br />
<span class="Comment">-- insert colored cell, along with markers for the cells that would form</span><br />
<span class="Comment">-- a rectanlge with this newly-colored cell:</span><br />
color&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Int</span>,<span class="Type">Int</span>)&nbsp;<span class="Statement">-&gt;</span>&nbsp;Direction&nbsp;<span class="Statement">-&gt;</span>&nbsp;Grid&nbsp;<span class="Statement">-&gt;</span>&nbsp;Grid<br />
color&nbsp;(x,y)&nbsp;d&nbsp;g&nbsp;<span class="Statement">=</span>&nbsp;M.insert&nbsp;(x,y)&nbsp;(Colored&nbsp;[d])&nbsp;rectsFormed<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ccs&nbsp;<span class="Statement">=</span>&nbsp;M.keys&nbsp;<span class="Statement">$</span>&nbsp;M.filter&nbsp;isColored&nbsp;g<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- all x coords of colored cells in same row (i.e. with same y):</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;<span class="Statement">=</span>&nbsp;inRow&nbsp;y<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- all y coords of colored cells in same column:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;<span class="Statement">=</span>&nbsp;inCol&nbsp;x<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- rectangles would be formed by these coordinates:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xyRects&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;(x',&nbsp;y')&nbsp;<span class="Statement">|</span>&nbsp;x'<span class="Statement">&lt;-</span>&nbsp;row,&nbsp;y' <span class="Statement">&lt;-</span>&nbsp;col&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xxRects&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;(x,&nbsp;y')&nbsp;<span class="Statement">|</span>&nbsp;x'<span class="Statement">&lt;-</span>&nbsp;row,&nbsp;y' <span class="Statement">&lt;-</span>&nbsp;delete&nbsp;y&nbsp;(inCol&nbsp;x')&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yyRects&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;(x',&nbsp;y)&nbsp;<span class="Statement">|</span>&nbsp;y'<span class="Statement">&lt;-</span>&nbsp;col,&nbsp;x' <span class="Statement">&lt;-</span>&nbsp;delete&nbsp;x&nbsp;(inRow&nbsp;y')&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;corners&nbsp;<span class="Statement">=</span>&nbsp;xyRects&nbsp;<span class="Statement">++</span>&nbsp;xxRects&nbsp;<span class="Statement">++</span>&nbsp;yyRects<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rectsFormed&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldr</span>&nbsp;(<span class="Identifier">flip</span>&nbsp;M.insert&nbsp;FormsRectangle)&nbsp;g&nbsp;corners<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- some helpers for above:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inRow&nbsp;r&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;x' <span class="Statement">|</span>&nbsp;(x',y')&nbsp;<span class="Statement">&lt;-</span>&nbsp;ccs,&nbsp;y' <span class="Statement">==</span>&nbsp;r&nbsp;]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inCol&nbsp;c&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;y' <span class="Statement">|</span>&nbsp;(x',y')&nbsp;<span class="Statement">&lt;-</span>&nbsp;ccs,&nbsp;x' <span class="Statement">==</span>&nbsp;c&nbsp;]<br />
<br />
isColored&nbsp;(Colored&nbsp;_)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">True</span><br />
isColored&nbsp;_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Constant">False</span><br />
<br />
<span class="Comment">-- mark the cell as having been entered from the direction we're going:</span><br />
addEntered&nbsp;<span class="Statement">::</span>&nbsp;Direction&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Direction]&nbsp;<span class="Statement">-&gt;</span>&nbsp;(<span class="Type">Int</span>,<span class="Type">Int</span>)&nbsp;<span class="Statement">-&gt;</span>&nbsp;Grid&nbsp;<span class="Statement">-&gt;</span>&nbsp;Grid<br />
addEntered&nbsp;d&nbsp;es&nbsp;<span class="Statement">=</span>&nbsp;M.adjust&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">const</span>&nbsp;<span class="Statement">$</span>&nbsp;Colored&nbsp;(d<span class="Statement">:</span>es)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
move&nbsp;S&nbsp;(x,y)&nbsp;<span class="Statement">=</span>&nbsp;(x,y<span class="Statement">-</span><span class="Constant">1</span>)<br />
move&nbsp;E&nbsp;(x,y)&nbsp;<span class="Statement">=</span>&nbsp;(x<span class="Statement">+</span><span class="Constant">1</span>,y)<br />
move&nbsp;N&nbsp;(x,y)&nbsp;<span class="Statement">=</span>&nbsp;(x,y<span class="Statement">+</span><span class="Constant">1</span>)<br />
move&nbsp;W&nbsp;(x,y)&nbsp;<span class="Statement">=</span>&nbsp;(x<span class="Statement">-</span><span class="Constant">1</span>,y)<br />
<br /></blockquote></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/17x17-deterministic-algorithm-for-single-coloring-a-grid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
