<?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; sequences</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/sequences/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>Sun, 29 Jan 2012 17:24:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Designing a Module for Combinatory Logic in Haskell</title>
		<link>http://coder.bsimmons.name/blog/2010/09/designing-a-module-for-combinatory-logic-in-haskell/</link>
		<comments>http://coder.bsimmons.name/blog/2010/09/designing-a-module-for-combinatory-logic-in-haskell/#comments</comments>
		<pubDate>Sat, 04 Sep 2010 21:28:43 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[combinator]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[NumericTypes]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[sequences]]></category>
		<category><![CDATA[theory]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=471</guid>
		<description><![CDATA[<p>Like the <a href="http://en.wikipedia.org/wiki/Lambda_calculus">Lambda Calculus</a> (on which Lisp is based), Combinatory Logic is a formal system that can be used to model and study computation. What makes it fascinating is that it is as powerful as the (already simple) lambda&#8230; <a href="http://coder.bsimmons.name/blog/2010/09/designing-a-module-for-combinatory-logic-in-haskell/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Like the <a href="http://en.wikipedia.org/wiki/Lambda_calculus">Lambda Calculus</a> (on which Lisp is based), Combinatory Logic is a formal system that can be used to model and study computation. What makes it fascinating is that it is as powerful as the (already simple) lambda calculus, but has no need for the variables that LC requires to perform substitution!</p>
<p>Here I show how we can use Haskell&#8217;s type classes and other language features to model the Combinator Calculus. The goals of this module were:</p>
<ol>
<li>     don&#8217;t force any one evaluation strategy </li>
<li>     allow users to define new combinators without exposing the implementation</li>
<li>    allow new combinators to be defined in terms of other already-defined combinators.</li>
<li>    discourage creation of non-sensical combinator expressions, or possible mis-use of the module</li>
<li>    hide existential types and anything else exotic</li>
</ol>
<p>If you want to play with it, you can do a:</p>
<blockquote><p>
<code>$> darcs get http://coder.bsimmons.name/code/CombinatorCalculus</code>
</p></blockquote>
<p><span id="more-471"></span></p>
<h2>A Quick Combinator Calculus Primer</h2>
<p>A Combinatory Logic expression consists of a sequence of <em>combinator terms</em> and <em>sub-expressions</em>. Combinator terms are like functions which consume some arguments (themselves combinators or sub-expressions), and return a particular re-arrangement of those arguments. When no term can consume enough arguments to be &#8220;evaluated&#8221; any further, the expression is said to be in <em>normal form</em>.</p>
<p>The <a href="http://en.wikipedia.org/wiki/SKI_combinator_calculus">SKI Combinator Calculus</a> is a system that uses only three combinators (&#8216;S&#8217;, &#8216;K&#8217; and &#8216;I&#8217;) and forms a Turing Complete system. This means we can express any computation with expressions that look like <code>SK(SSS)I(S(KS)K)I</code>. It can even server as the basis of a turing complete <a href="http://www.madore.org/~david/programs/unlambda/">programming language</a>!</p>
<p>It&#8217;s a really fascinating topic, and you can get a great overview from wikipedia&#8217;s excellent <a href="http://en.wikipedia.org/wiki/Combinatory_logic">Combinatory Logic article</a>.</p>
<h2>The Design of the Module</h2>
<p>All terms in combinatory logic take some arguments and form a new expression from them, but different combinators transform their arguments in different ways. </p>
<p>We can express this in Haskell by creating a typeclass with methods that describe the behavior of a combinator. Then we can make a type (corresponding to a specific Combinator term) an instance of our class to define its behavior.</p>
<h3>The <code>Combinator</code> Class</h3>
<p>Here is how we define our <code>Combinator</code> class:</p>
<p><blockquote class="vimblock"><br />
&nbsp;<span class="Comment">-- a Class for combinators. Its methods represent a combinator's behavior on </span><br />
&nbsp;<span class="Comment">-- its arguments:</span><br />
<span class="Type">class</span>&nbsp;(Show&nbsp;c)<span class="Statement">=&gt;</span>&nbsp;Combinator&nbsp;c&nbsp;<span class="Type">where</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;takesArgs&nbsp;<span class="Statement">::</span>&nbsp;c&nbsp;<span class="Statement">-&gt;</span>&nbsp;Int<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;applyArgs&nbsp;<span class="Statement">::</span>&nbsp;c&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Term]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Expr<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- HIDDEN METHOD: EXPORTED AS A FUNCTION:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- if a combinator takes 0 args, we assume it can be evaluated and we</span><br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- say it is not in Normal Form:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;isNormal&nbsp;<span class="Statement">::</span>&nbsp;c&nbsp;<span class="Statement">-&gt;</span>&nbsp;Bool<br />
&nbsp;&nbsp;&nbsp;&nbsp;isNormal&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Statement">&gt;</span>&nbsp;<span class="Constant">0</span>)&nbsp;<span class="Statement">.</span>&nbsp;takesArgs<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- HIDDEN METHOD: user defined combinators are placed in a black box:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;toTerm&nbsp;<span class="Statement">::</span>&nbsp;c&nbsp;<span class="Statement">-&gt;</span>&nbsp;Term<br />
&nbsp;&nbsp;&nbsp;&nbsp;toTerm&nbsp;<span class="Statement">=</span>&nbsp;Term<br />
<br /></blockquote></p>
<p>The first two methods are the only ones exported to users of the module to define an instance of <code>Combinator</code>. <code>takesArgs</code> is used to indicate how many arguments this particular combinator requires before it can be evaluated. </p>
<p><code>applyArgs</code> actually performs the transformation of those arguments; it is given a list of terms (of length equal to `takesArgs`) and returns a new expression (type Expr).</p>
<p>The third method is used to check if an expression is in normal form. It is exported <em>as a regular function</em>, meaning that users can use it in their code but <em>cannot</em> use it in their own instance declarations. Instead the default value would apply.</p>
<p>The fourth method `toTerm` is used internally to encapsulate some Combinator class item in a `Term` data type. We use this when composing combinator expressions, in order to preserve the tree structure of the expression. (see below for more on this)</p>
<h3>The <code>Term</code> and <code>Expr</code> types</h3>
<p>The module defines two new datatypes, <em>both</em> of which are instances of `Combinator`.	</p>
<p>`Expr` is a <code>newtype</code> wrapper around <code>Seq Term</code>, but we don&#8217;t export the implementation so we can change this if we don&#8217;t want to use <a href="http://hackage.haskell.org/packages/archive/containers/0.2.0.1/doc/html/Data-Sequence.html">Sequences</a>:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">newtype</span>&nbsp;Expr&nbsp;<span class="Statement">=</span>&nbsp;Expr&nbsp;{&nbsp;combSeq&nbsp;<span class="Statement">::</span>&nbsp;Seq&nbsp;Term&nbsp;}<br />
<br /></blockquote></p>
<p>It simply represents a CL expression as a sequence of terms. Making it an instance of `Combinator` expresses the notion that an expression can be thought of as a combinator term whenever the need arises. In fact the distinction is simply one of <a href="http://en.wikipedia.org/wiki/Evaluation_strategy">evaluation strategy</a>.</p>
<p>`Term` is a wrapper for Combinator terms and sub-expressions. It is mutually-recursive with `Expr` and the two together form the tree structure of a combinator expression:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">data</span>&nbsp;Term&nbsp;<span class="Statement">=</span>&nbsp;forall&nbsp;c<span class="Statement">.</span>&nbsp;Combinator&nbsp;c&nbsp;<span class="Statement">=&gt;</span>&nbsp;Term&nbsp;{&nbsp;unbox&nbsp;<span class="Statement">::</span>&nbsp;c&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;SubExpr&nbsp;&nbsp; {&nbsp;subExpr&nbsp;<span class="Statement">::</span>&nbsp;Expr&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;NamedExpr&nbsp;{&nbsp;subExpr&nbsp;<span class="Statement">::</span>&nbsp;Expr,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">::</span>&nbsp;String&nbsp;}<br />
<br /></blockquote></p>
<p>All three constructors are hidden from the user. `SubExpr` simply holds an `Expr` type and represents a parenthesized sub-expression within the top level combinator sequence. `NamedExpr` is identical except that it also contains a String, which will be returned when `show` is called on that constructor. Here is the `Show` instance for `Term`:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">instance</span>&nbsp;Show&nbsp;Term&nbsp;<span class="Type">where</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;show&nbsp;(NamedExpr&nbsp;_&nbsp;n)&nbsp;<span class="Statement">=</span>&nbsp;n<br />
&nbsp;&nbsp;&nbsp;&nbsp;show&nbsp;(SubExpr&nbsp;e)&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Constant">&quot;(&quot;</span><span class="Statement">++</span>&nbsp;show&nbsp;e&nbsp;<span class="Statement">++</span><span class="Constant">&quot;)&quot;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;show&nbsp;(Term&nbsp;t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;show&nbsp;t<br />
<br /></blockquote></p>
<p>The remaining constructor is the most interesting: the `Term` constructor houses an <a href="http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types">existentially-quantified type</a> and can hold <em>any</em> type value of the `Combinator` class. </p>
<p>Notice that the type variable does not appear on the left side of the <code>=</code> in the type declaration. What this means in practical terms is that the `Term` constructor becomes a &#8220;black box&#8221;; once a value is inside, the only things we can &#8220;do with it&#8221; are to apply polymorphic Combinator class functions and methods.</p>
<p>And that&#8217;s why we have the internal `toTerm` method; it allows us to wrap sub-expressions in the `SubExpr` constructor, preserving the tree structure of an expression as we compose it. Without it we would either need to export multiple functions for composing a term with an expression, an expression with an expression, a term with a term, and an expression with a term. Ugly!</p>
<h3>Exported functions</h3>
<p>Our types and classes allow us to do some neat stuff. As mentioned above, we can compose expressions using a single haskell infix function. Since all the nice ASCII combinators were taken (and since I&#8217;m the only one using this) I decided to go with a Unicode symbol, the middle dot, for composition:</p>
<p><blockquote class="vimblock"><br />
&nbsp;<span class="Comment">-- operator for composing combinator expressions. This is the Middle Dot, </span><br />
&nbsp;<span class="Comment">-- unicode character 00B7. It is easily inserted in vim using the digraph: </span><br />
&nbsp;<span class="Comment">--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ctrl-K '.' 'M'</span><br />
<span class="PreProc">infixl</span>&nbsp;<span class="Constant">7</span>&nbsp;·<br />
<br /></blockquote></p>
<p>&#8230;and the implementation:</p>
<p><blockquote class="vimblock"><br />
&nbsp;<span class="Comment">-- for composing Combinator expressions:</span><br />
(·)&nbsp;<span class="Statement">::</span>&nbsp;(Combinator&nbsp;c1,Combinator&nbsp;c2)<span class="Statement">=&gt;</span>&nbsp;c1&nbsp;<span class="Statement">-&gt;</span>&nbsp;c2&nbsp;<span class="Statement">-&gt;</span>&nbsp;Expr<br />
c1&nbsp;· (toTerm<span class="Statement">-&gt;</span>t2)&nbsp;<span class="Statement">=</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">case</span>&nbsp;toTerm&nbsp;c1&nbsp;<span class="Statement">of</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;(SubExpr&nbsp;e)&nbsp;<span class="Statement">-&gt;</span>&nbsp;e&nbsp;<span class="Statement">`appendTerms`</span>&nbsp;singleton&nbsp;t2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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; <span class="Comment">-- named expression or bare Term start a new sub-expression:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">-&gt;</span>&nbsp;Expr&nbsp;(singleton&nbsp;t1&nbsp;<span class="Statement">|&gt;</span>&nbsp;t2)<br />
<br /></blockquote></p>
<p>We also have the ability to define new combinators in terms of other combinators using the `named` function. Here is an example showing how `I` can be defined in terms of `S` and `K` and used to form a Combinator Calculus equivalent of the <a href="http://en.wikipedia.org/wiki/Church_numeral">Church Numeral</a> 2:</p>
<p><blockquote class="vimblock"><br />
<span class="lnr">60 </span>two&nbsp;<span class="Statement">=</span>&nbsp;S·(S·(K·S)·K)·cI<br />
<span class="lnr">61 </span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;cI&nbsp;<span class="Statement">=</span>&nbsp;(S&nbsp;· K&nbsp;· K)&nbsp;&nbsp;<span class="Statement">`named`</span>&nbsp;<span class="Constant">&quot;I&quot;</span><br />
<br /></blockquote></p>
<h2>Playing with it</h2>
<p>The evaluation function exported in the module was written fairly hastily, but it is good enough to let us play with evaluating expressions.</p>
<p>I&#8217;ve run out of time on this post, but you can grab the darcs repo above and run the &#8216;main&#8217; function in `Examples.hs` and check out the source for more info. I&#8217;ll maybe show some cool examples in a later post.</p>
<p>Thanks for reading!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/09/designing-a-module-for-combinatory-logic-in-haskell/feed/</wfw:commentRss>
		<slash:comments>1</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>
		<item>
		<title>DeBruijn Sequences pt.3 &#8211; The &#8220;Prefer Opposite&#8221; algorithm</title>
		<link>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/</link>
		<comments>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 02:29:29 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[sequences]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=295</guid>
		<description><![CDATA[<p><em>This is the third post of mine on DeBruijn sequences, and is in preparation for another post to come which I hope should be an interesting investigation into a possible parallel algorithm. The first two posts are <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">here</a> and</em>&#8230; <a href="http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>This is the third post of mine on DeBruijn sequences, and is in preparation for another post to come which I hope should be an interesting investigation into a possible parallel algorithm. The first two posts are <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">here</a> and <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/">here</a>.</em><br />
<span id="more-295"></span><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p><div class="vimblock"><br />
This algorithm works identically to the Prefer One algorithm, however<br />
rather than choose a 1-bit if possible, we instead choose the opposite<br />
bit from the previous bit, if possible.<br />
<br />
This has the effect of evening out the locations of the zeros and ones<br />
throughout the sequence. We will exploit this in a later post where I<br />
will explore a possible parallel algorithm, which should be interesting<br />
I hope!<br />
<br />
Here's the code...<br />
<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="PreProc">import</span>&nbsp;Data.List(tails)<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Monad.State<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Arrow<br />
<br />
<br />
We use Bool for bits, where False ==&gt; 0, True ==&gt; 1:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;Bit&nbsp;<span class="Statement">=</span>&nbsp;<span class="Type">Bool</span><br />
<br />
<br />
We use a tree to search for the words already created in our bit stream:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">data</span>&nbsp;Tree&nbsp;<span class="Statement">=</span>&nbsp;Bs&nbsp;Tree&nbsp;Tree&nbsp;&nbsp;<span class="Comment">-- Bs (zero_bit) (one_bit)</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;X&nbsp;<span class="Comment">-- incomplete word</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;B&nbsp;<span class="Comment">-- final bit of word</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br />
<br />
<br />
We'll need to build a new tree from a list of bits, appending<br />
a final bit:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;treeWithFinal&nbsp;<span class="Statement">::</span>&nbsp;Bit&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Bit]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree<br />
<span class="Comment">&gt;</span>&nbsp;treeWithFinal&nbsp;p&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldr</span>&nbsp;mkBranch&nbsp;(<span class="Statement">if</span>&nbsp;p&nbsp;<span class="Statement">then</span>&nbsp;Bs&nbsp;X&nbsp;B&nbsp;<span class="Statement">else</span>&nbsp;Bs&nbsp;B&nbsp;X)&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;mkBranch&nbsp;b&nbsp;<span class="Statement">|</span>&nbsp;b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;Bs&nbsp;X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--1</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">flip</span>&nbsp;Bs&nbsp;X&nbsp;<span class="Comment">--0</span><br />
<br />
<br />
<br />
Finally, here is our new algorithm. The Tree which we use to search for<br />
previously-seen words is passed in the State monad, behind the scenes, <br />
with 'zipWithM', which in our case looks like:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;zipWithM :: (Bit -&gt; [Bit] -&gt; State Tree Bit) -&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Bit]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[[Bit]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;State Tree [Bit]<br />
<br />
The state monad is a little tricky sometimes:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;preferOpposite&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]<br />
<span class="Comment">&gt;</span>&nbsp;preferOpposite&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- the whole bit sequence, except for the final 1:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;bs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">take</span>&nbsp;(<span class="Constant">2</span><span class="Statement">^</span>n<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;(<span class="Identifier">replicate</span>&nbsp;n&nbsp;<span class="Constant">False</span>&nbsp;<span class="Statement">++</span>&nbsp;bs')<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- list of (n-1)-bit words:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (wp0<span class="Statement">:</span>wordPrefixes)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Identifier">take</span>&nbsp;(n<span class="Statement">-</span><span class="Constant">1</span>))&nbsp;(tails&nbsp;bs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we know the first word is n 0's so we create our initial</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- tree from (n-1) 0's with a zero at the end:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state0&nbsp;<span class="Statement">=</span>&nbsp;treeWithFinal&nbsp;<span class="Constant">False</span>&nbsp;wp0<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we zipWith a word with it's previous bit (so that we</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- can know which bit is the opposite) passing along the</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Tree with help from the State monad:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bsM' <span class="Statement">=</span>&nbsp;zipWithM&nbsp;thisBit&nbsp;(<span class="Constant">False</span><span class="Statement">:</span>bs')&nbsp;wordPrefixes<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs' <span class="Statement">=</span>&nbsp;evalState&nbsp;bsM' state0<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we place a 1 for the final bit:</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;bs&nbsp;<span class="Statement">++</span>&nbsp;[<span class="Constant">True</span>]<br />
<br />
If we wanted to be clever, we would have made the last line:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; in cycle (bs ++ [True])<br />
<br />
...as the sequence is actually cyclic.<br />
<br />
This helper function takes the previous bit and an n-1 bit word and returns <br />
a function :: Tree -&gt; (Bit,Tree), which takes the current search tree and<br />
checks the current word to see if the last bit of the word should be one<br />
or zero. The function :: Tree -&gt; (Bit,Tree) is wrapped in the State <br />
constructor, which is all you have to do to turn it into :: State Tree Bit<br />
<br />
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;<span class="Statement">::</span>&nbsp;Bit&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]&nbsp;<span class="Statement">-&gt;</span>&nbsp;State&nbsp;Tree&nbsp;Bit<br />
<br />
The wrapper function splits up the input tuple and tuples up the returned<br />
bit to make a proper St so that we can pass the last bit through the state<br />
monad.<br />
<br />
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;bP&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;State&nbsp;<span class="Statement">.</span>&nbsp;thisBit'<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp; <span class="Type">where</span>&nbsp;bOpp&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;bP&nbsp;<br />
<br />
We start checking a word, moving down the tree:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' (<span class="Constant">False</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;second&nbsp;(<span class="Identifier">flip</span>&nbsp;Bs&nbsp;o)&nbsp;(thisBit' bs&nbsp;z)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' (<span class="Constant">True</span><span class="Statement">:</span>bs)&nbsp;&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;second&nbsp;(Bs&nbsp;z)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(thisBit' bs&nbsp;o)<br />
<br />
...or we walked off end of branch, so return opposite bit, and attach <br />
the rest of word to the tree:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' bs&nbsp;X&nbsp;<span class="Statement">=</span>&nbsp;(bOpp,&nbsp;treeWithFinal&nbsp;bOpp&nbsp;bs)<br />
<br />
...or we reached the end of our word, so we prefer the opposite for the last <br />
bit, and check if it was seen:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisBit' []&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;bOpp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">case</span>&nbsp;o&nbsp;<span class="Statement">of</span>&nbsp;<span class="Comment">-- opposite bit is 1 (True)</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bOpp,Bs&nbsp;z&nbsp;B)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bP&nbsp;&nbsp;,Bs&nbsp;B&nbsp;B)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">case</span>&nbsp;z&nbsp;<span class="Statement">of</span><br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bOpp,Bs&nbsp;B&nbsp;o)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_&nbsp;<span class="Statement">-&gt;</span>&nbsp;(bP&nbsp;&nbsp;,Bs&nbsp;B&nbsp;B)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
Finally, here are some functions to generate the actual sequences <br />
in 0s and 1s:<br />
<br />
<span class="Comment">&gt;</span>&nbsp;test&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Statement">\</span>x<span class="Statement">-&gt;</span><span class="Statement">if</span>&nbsp;x&nbsp;<span class="Statement">then</span>&nbsp;<span class="Constant">'1'</span>&nbsp;<span class="Statement">else</span>&nbsp;<span class="Constant">'0'</span>)&nbsp;<span class="Statement">.</span>&nbsp;preferOpposite&nbsp;<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;main&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Statement">$</span>&nbsp;test&nbsp;<span class="Constant">10</span><br />
<br />
<br /></div></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/12/debruijn-sequences-pt3-the-prefer-opposite-algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk
Database Caching 8/15 queries in 0.046 seconds using disk

Served from: coder.bsimmons.name @ 2012-02-05 11:34:43 -->
