<?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; release</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/release/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>Befunge-93 Interpreter on Hackage</title>
		<link>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/</link>
		<comments>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/#comments</comments>
		<pubDate>Thu, 20 May 2010 18:36:42 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[MonadTransformers]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=413</guid>
		<description><![CDATA[<p>I&#8217;ve fixed a bug related to upgrading GHC to version 6.12 (thanks to Cale and the folks on haskell-cafe who helped me with the issue) and got my <a href="http://en.wikipedia.org/wiki/Befunge">Befunge-93</a> interpreter up on hackage. The program is written in haskell&#8230; <a href="http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve fixed a bug related to upgrading GHC to version 6.12 (thanks to Cale and the folks on haskell-cafe who helped me with the issue) and got my <a href="http://en.wikipedia.org/wiki/Befunge">Befunge-93</a> interpreter up on hackage. The program is written in haskell (as usual). You should be able to get it soon with a:</p>
<blockquote><pre>$> cabal install Befunge93</pre>
</blockquote>
<p>If you want to read about how I designed it you can check out the source above, or take a look at my <a href="http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/">previous blog post</a>.</p>
<p>Please report any bugs to me, and I&#8217;m also very interested in patches or suggestions for performance improvements if anyone ends up being interested in this program.</p>
<p><strong>EDIT</strong>: Here is the package page: <a href="http://hackage.haskell.org/package/Befunge93">http://hackage.haskell.org/package/Befunge93</a></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Befunge-93 Interpreter</title>
		<link>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/</link>
		<comments>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 21:13:50 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[MonadTransformers]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[state]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=302</guid>
		<description><![CDATA[<p><em>I just finished an initial release of an interpreter for the <a href="http://en.wikipedia.org/wiki/Befunge">befunge</a> programming language, based on the <a href="http://catseye.tc/projects/befunge93/">&#8216;93 spec</a>. The project was quite fun! My goal was to produce a well-designed program with performance that didn&#8217;t suck too</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>I just finished an initial release of an interpreter for the <a href="http://en.wikipedia.org/wiki/Befunge">befunge</a> programming language, based on the <a href="http://catseye.tc/projects/befunge93/">&#8216;93 spec</a>. The project was quite fun! My goal was to produce a well-designed program with performance that didn&#8217;t suck too bad. Here are some highlights:</em></p>
<h2>Design</h2>
<p>I found that writing the core functionality of the interpreter took almost no time, once I settled on the approach I would take. I used a monad transformer for the first time, <code>StateT</code>: </p>
<p><blockquote class="vimblock"><br />
<span class="Type">type</span>&nbsp;REPL&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;StateT&nbsp;ProgramState&nbsp;<span class="Type">IO</span>&nbsp;a<br />
<br /></blockquote></p>
<p>This let me pass around the state of the computation in the <code>State</code> monad while doing IO actions. This made some potentially-awkward befunge commands really easy to implement.<br />
<span id="more-302"></span><br />
Here is an excerpt from the function <code>execute :: Char -> REPL ()</code> which reads the befunge character at our position and returns the code to execute:</p>
<p><blockquote class="vimblock"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Pop value and output as an integer. funge-98 spec calls for</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- integer to be followed by a space, so we'll do that too:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'.'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;i&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liftIO&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">putStr</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">show</span>&nbsp;i&nbsp;<span class="Statement">++</span><span class="Constant">&quot; &quot;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Pop value and output as ASCII character</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">','</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;i&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liftIO&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">putChar</span>&nbsp;<span class="Statement">$</span>&nbsp;chr&nbsp;i<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'</span><span class="Special">\\</span><span class="Constant">'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;(a,b)&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;a<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;b<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">':'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;a&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; replicateM_&nbsp;<span class="Constant">2</span>&nbsp;(push&nbsp;a)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- program flow commands: --</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">' '</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Identifier">return</span>&nbsp;()&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'&gt;'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;right<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'&lt;'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;left&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'^'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;up<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'v'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;down<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'?'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;getRandomDirection&nbsp;<span class="Statement">&gt;&gt;=</span>&nbsp;setDirection&nbsp;<br />
<br /></blockquote></p>
<p>And here is the program state that gets passed in the monad:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">data</span>&nbsp;ProgramState&nbsp;<span class="Statement">=</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ES&nbsp;{&nbsp;<span class="Comment">-- state of the code and stack:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code&nbsp;<span class="Statement">::</span>&nbsp;Code,&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack&nbsp;<span class="Statement">::</span>&nbsp;Stack,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- state of program flow:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; position&nbsp;<span class="Statement">::</span>&nbsp;Position,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; direction&nbsp;<span class="Statement">::</span>&nbsp;Direction,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; haltBit&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Bool</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- random generator:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; randGen&nbsp;<span class="Statement">::</span>&nbsp;StdGen,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- errors or other messages we collect:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; messages&nbsp;<span class="Statement">::</span>&nbsp;[<span class="Type">String</span>],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- should we announce messages and warnings?:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; verbose&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Bool</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
<br /></blockquote></p>
<p>I only use the accessor functions (as opposed to pattern matching) to reach into the state in my code, so it was easy to add another state parameter if I wanted to extend the functionality somewhere.</p>
<p>Finally here is the evaluation loop that ties the core of the interpreter together:</p>
<p><blockquote class="vimblock"><br />
evalLoop&nbsp;<span class="Statement">::</span>&nbsp;REPL&nbsp;()<br />
evalLoop&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- extract the command at our position &amp; execute it:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;getCmd&nbsp;<span class="Statement">&gt;&gt;=</span>&nbsp;execute<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- print messages in the queue (unless quiet), and clear it:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;printMessages<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- halt if @ command issued, else move and recurse:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;halting&nbsp;<span class="Statement">&lt;-</span>&nbsp;gets&nbsp;haltBit<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless&nbsp;halting&nbsp;(move&nbsp;<span class="Statement">&gt;&gt;</span>&nbsp;evalLoop)&nbsp;<br />
<br /></blockquote></p>
<p>I found the most time-consuming parts of this project were in the design decisions and behaviour tweaks related to holes in the &#8216;93 spec, and tracking down a few silly bugs that came from wrong assumptions about the spec. </p>
<p>Vital in debugging were the <a href="http://users.tkk.fi/~mniemenm/befunge/ccbi.html">CCBI interpreter</a> as well as the <a href="http://mearie.org/projects/pyfunge/">pyfunge interpreter.</a> It&#8217;s difficult to debug an interpreter when you don&#8217;t whether the befunge code you are testing on is buggy or whether your interpreter is!</p>
<p>One last detail that I am proud of is the test suite that I have integrated into my darcs repo. Darcs automatically runs the befunge-93 portion of the amazing <a href="http://iki.fi/matti.niemenmaa/befunge/mycology.html">mycology test suite</a> by Matti Niemenmaa on each commit, as well as two smaller <a href="http://www.phlamethrower.co.uk/befunge/#files">test befunge programs</a> from phlamethrower, testing that the interpreter hasn&#8217;t changed behavior.</p>
<h2>Play With It</h2>
<p>You can check out the full source for the program <a href="http://coder.bsimmons.name/code/Befunge/Befunge.hs">here</a>, or get my whole darcs repository with:</p>
<blockquote><p>
<code>$ darcs get --tag=v0.2 http://coder.bsimmons.name/code/Befunge</code>
</p></blockquote>
<p>And here are a few nice programs to try out, written by folks cleverer than I, and stolen from vsync&#8217;s funge stuff <a href="http://quadium.net/funge/downloads/bef93src/">here</a>.</p>
<p><em>aturley.bf</em> by Andrew Turley:</p>
<blockquote><pre>
>84*>:#v_55+"ude.ub@yelruta">:#,_@>188*+>\02p\12p\:22p#v_$    55+,1-         v
    ^  0 v +1\                   _^#-+*<>22g02g*"_@"*-!1- #v_v>
       >:>::3g: ,\188                  ^^               -1\g21\g22
<p3 \"_":<
________________________________@_________________________________^  p3\"@":<
</pre>
</p3></pre>
</blockquote>
<p><em>life.bf</em> by Dmitry M Litvinov:</p>
<blockquote><pre>
v>>31g> ::51gg:2v++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9p BXY|-+<v3 *89<%+ *                                                      *   +
21 >98 *7^>+\-0|< + *                                                     *    +
*5 ^:+ 1pg15\,:< + *                                                     ***  +
10^  <>$25*,51g1v+                                                            +
-^ p< | -*46p15:+<+                                                            +
> 31^> 151p>92*4v+                                                            +
 ^_ ".",   ^ vp1< +                                                            +
>v >41p      >0 v+                                                            +
:5! vg-1g15-1g14< +                                                            +
+1-+>+41g1-51gg+v+                                                            +
1p-1vg+1g15-1g14< +                                                            +
g61g>+41g51g1-g+v+                                                            +
14*1v4+g+1g15g14< +                           * *                              +
5>^4>1g1+51g1-g+v+                           * *                              +
^ _^v4+gg15+1g14< +                           ***                              +
>v! >1g1+51g1+g+v+                                                            +
g8-v14/*25-*4*88< +                                                            +
19+>g51gg" "- v  +                                                            +
4*5  v< v-2:_3v+                                                            +
 >^   |!-3_$  v< -+                                                            +
^    < <      <|<+                                                         ***+
>g51gp ^ >51gp^>v+                                                            +
^14"+"< ^g14"!"<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
</pre>
<p></v3></pre>
</blockquote>
<p><em>prime.bf</em> by Kalyna Zazelenchuk:</p>
<blockquote><pre>
222p35*89+*11p>133p                   >33g1+33p   22g33g- v>22g33g%#v_v
 o                                                        >|
  2                             v,,,,, ,,,,,.g22"is prime."< 1                            >    v^                             < ^_@#-g11g22p22+1g22,*25<,,,,,,,,,,,,,.g22"is not prime."<
</pre>
</pre>
</blockquote>
<p>There is still a lot that could be done, but I think I&#8217;m done with it for now. Thanks for looking!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Some Haskell Boilerplate For Google CodeJam</title>
		<link>http://coder.bsimmons.name/blog/2009/08/haskell-boilerplate-for-google-codejam/</link>
		<comments>http://coder.bsimmons.name/blog/2009/08/haskell-boilerplate-for-google-codejam/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 07:37:16 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[CodeJam]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=207</guid>
		<description><![CDATA[<p>I put together a skeleton module which should be usable for any of the problems in this year&#8217;s <a href="http://code.google.com/codejam/">Google CodeJam Programming Contest</a> (as long as they don&#8217;t adopt a new format/pattern for the problems this year). The module includes&#8230; <a href="http://coder.bsimmons.name/blog/2009/08/haskell-boilerplate-for-google-codejam/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I put together a skeleton module which should be usable for any of the problems in this year&#8217;s <a href="http://code.google.com/codejam/">Google CodeJam Programming Contest</a> (as long as they don&#8217;t adopt a new format/pattern for the problems this year). The module includes some useful parsing functions which should in the worst case be useful as a cheatsheet for those not too experienced with <a href="http://legacy.cs.uu.nl/daan/download/parsec/parsec.html">Parsec</a> (*cough me). I hope it will encourage people to <a href="http://code.google.com/codejam/contest/registration">sign up</a> and use Haskell in the contest!</p>
<p>To adapt the module to a problem, one defines the following:</p>
<ol>
<li>a type <code>Case</code> into which we will parse a test case (i.e. problem)</li>
<li>a type <code>SolvedCase</code>, representing a solution to a test case</li>
<li>our <code>algorithm :: Case -> SolvedCase</code></li>
<li>a Parser <code>caseParser</code> which can parse a <em>single test case</em> (n.b. not the whole file) into the <code>Case</code> type</li>
<li>a function <code>formatCase :: SolvedCase -> String</code> which brings the solution to the state where it can be prepended with the standard &#8220;Case #1: &#8221; string</li>
</ol>
<p>Here is the module, filled in to solve the Minimum Scalar Product practice problem. You can download the code <a href="http://coder.bsimmons.name/code/Boiler.hs">here</a>:</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;Text.ParserCombinators.Parsec<br>
<span class="PreProc">import</span>&nbsp;IO <span class="PreProc">hiding</span>&nbsp;(try)<br>
<span class="PreProc">import</span>&nbsp;System.Environment<br>
<br>
<span class="Comment">-- PROBLEM-SPECIFIC IMPORTS --</span><br>
<span class="PreProc">import</span>&nbsp;Data.List (sort)<br>
<span class="PreProc">import</span>&nbsp;Control.Arrow<br>
<span class="Comment">------------------------------</span><br>
<br>
<br>
<span class="Comment">-- the input file will be parsed into a list of some type representing</span><br>
<span class="Comment">-- individual cases to be solved by our algorithm:</span><br>
<span class="Type">type</span>&nbsp;Input&nbsp;<span class="Statement">=</span>&nbsp;[Case]&nbsp;<br>
<br>
<span class="Comment">-- our algorithms will produce a list of some type SolutionCase:</span><br>
<span class="Type">type</span>&nbsp;Solution&nbsp;<span class="Statement">=</span>&nbsp;[SolvedCase]&nbsp;<br>
<br>
<span class="Comment">-- we convert each solved case into a String, which is zipped with</span><br>
<span class="Comment">--&nbsp;&nbsp;the standard &quot;Case #x: &quot; strings for the final output</span><br>
<span class="Type">type</span>&nbsp;Output&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Type">String</span>]<br>
<br>
<br>
<br>
<br>
<br>
<span class="Comment">-- --------------- BEGIN EDITING --------------- --</span><br>
<br>
<br>
<br>
<span class="Comment">-- DEFINE A TYPE TO REPRESENT A SINGLE UNSOLVED TEST CASE: --</span><br>
<span class="Type">type</span>&nbsp;Case&nbsp;<span class="Statement">=</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- EXAMPLE: a pair of lists of Ints (our &quot;vectors&quot;):</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;([<span class="Type">Int</span>],[<span class="Type">Int</span>])<br>
<br>
<br>
<span class="Comment">-- DEFINE A TYPE TO REPRESENT A SINGLE SOLVED TEST CASE: --</span><br>
<span class="Type">type</span>&nbsp;SolvedCase&nbsp;<span class="Statement">=</span>&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- EXAMPLE: our Minimum Scalar Product as an Int:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">Int</span><br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- -- -- ALGORITHMS -- -- --</span><br>
<br>
<br>
<span class="Comment">-- SOLVE A TEST CASE HERE:</span><br>
algorithm&nbsp;<span class="Statement">::</span>&nbsp;Case&nbsp;<span class="Statement">-&gt;</span>&nbsp;SolvedCase<br>
algorithm&nbsp;<span class="Statement">=</span>&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- EXAMPLE: simply sort both lists, reverse one, and combine:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">sum</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">uncurry</span>&nbsp;(<span class="Identifier">zipWith</span>&nbsp;(<span class="Statement">*</span>))&nbsp;<span class="Statement">.</span>&nbsp;(<span class="Identifier">reverse</span>&nbsp;<span class="Statement">.</span>&nbsp;sort&nbsp;<span class="Statement">***</span>&nbsp;sort)<br>
<br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- -- -- PARSING INPUT -- -- --</span><br>
<br>
<br>
<span class="Comment">-- DEFINE PARSER FOR A TEST CASE: --</span><br>
caseParser&nbsp;<span class="Statement">::</span>&nbsp;Parser&nbsp;Case<br>
caseParser&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- EXAMPLE: parses a case consisting of 3 lines: the first describes the </span><br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">--&nbsp;&nbsp;number n of elements in the following two lines, the next two lines </span><br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- have n space-separated elements:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;<span class="Statement">&lt;-</span>&nbsp;word<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">read</span>&nbsp;w<br>
&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;<span class="Statement">&lt;-</span>&nbsp;count&nbsp;n&nbsp;word<br>
&nbsp;&nbsp;&nbsp;&nbsp;bs&nbsp;<span class="Statement">&lt;-</span>&nbsp;count&nbsp;n&nbsp;word<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;&nbsp;(<span class="Identifier">map</span>&nbsp;<span class="Identifier">read</span>&nbsp;as,&nbsp;<span class="Identifier">map</span>&nbsp;<span class="Identifier">read</span>&nbsp;bs)<br>
<br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- -- -- FORMAT OUTPUT -- -- --</span><br>
<br>
<br>
<span class="Comment">-- DEFINE A FUNCTION FROM AN INDIVIDUAL SolvedCase -&gt; String. </span><br>
formatCase&nbsp;<span class="Statement">::</span>&nbsp;SolvedCase&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">String</span><br>
formatCase&nbsp;sol&nbsp;<span class="Statement">=</span>&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- EXAMPLE: nothing to speak of here:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">show</span>&nbsp;sol<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp; <br>
<br>
<span class="Comment">-- --------------- STOP EDITING --------------- --</span><br>
<br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--------------------</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- IO BOILERPLATE --</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--------------------</span><br>
<br>
<br>
main&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- pass the input file name to our program:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;(f<span class="Statement">:</span>_)&nbsp;<span class="Statement">&lt;-</span>&nbsp;getArgs<br>
&nbsp;&nbsp;&nbsp;&nbsp;file&nbsp;&nbsp;<span class="Statement">&lt;-</span>&nbsp;<span class="Identifier">readFile</span>&nbsp;f<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- start parsing, solve problem, and prepare output: </span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;inp&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;parseWith&nbsp;mainParser&nbsp;file<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solution&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;algorithm&nbsp;inp<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;solutionStrings&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;formatCase&nbsp;solution<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outp&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">zipWith</span>&nbsp;(<span class="Statement">++</span>)&nbsp;prefixes&nbsp;solutionStrings<br>
&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- write the prepared output to screen:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">putStr</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">unlines</span>&nbsp;outp<br>
<br>
<br>
<span class="Comment">-- dies with error, or returns some datatype with our parsed data:</span><br>
parseWith&nbsp;p&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">either</span>&nbsp;(<span class="Identifier">error</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">show</span>)&nbsp;<span class="Identifier">id</span>&nbsp;<span class="Statement">.</span>&nbsp;parse&nbsp;p&nbsp;<span class="Constant">&quot;&quot;</span>&nbsp;<br>
<br>
<span class="Comment">-- to begin parsing, we read in a line containing the number of test cases </span><br>
<span class="Comment">-- to follow. We parse them with caseParser, returning a list:</span><br>
mainParser&nbsp;<span class="Statement">::</span>&nbsp;Parser&nbsp;Input<br>
mainParser&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;&nbsp;<span class="Statement">&lt;-</span>&nbsp;word<br>
&nbsp;&nbsp;&nbsp;&nbsp;ms&nbsp;<span class="Statement">&lt;-</span>&nbsp;count&nbsp;(<span class="Identifier">read</span>&nbsp;n)&nbsp;caseParser&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;ms<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;mainParser&quot;</span><br>
<br>
<span class="Comment">-- strings to prepend to output:</span><br>
prefixes&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;<span class="Constant">&quot;Case #&quot;</span>&nbsp;<span class="Statement">++</span>&nbsp;<span class="Identifier">show</span>&nbsp;n&nbsp;<span class="Statement">++</span>&nbsp;<span class="Constant">&quot;: &quot;</span>&nbsp;<span class="Statement">|</span>&nbsp;n&nbsp;<span class="Statement">&lt;-</span>&nbsp;[<span class="Constant">1</span><span class="Statement">..</span>]]<br>
<br>
<br>
<br>
<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">---------------------</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- VARIOUS PARSERS --</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">---------------------</span><br>
<br>
<br>
<span class="Comment">-- -- LINE PARSERS -- --</span><br>
<br>
<br>
<span class="Comment">-- a single line String, up to the newline:</span><br>
wholeLine&nbsp;<span class="Statement">::</span>&nbsp;Parser&nbsp;<span class="Type">String</span><br>
wholeLine&nbsp;<span class="Statement">=</span>&nbsp;manyTill&nbsp;anyChar&nbsp;(try&nbsp;newline)&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;wholeLine&quot;</span><br>
<br>
<span class="Comment">-- parse a String with whitespace-separated values into [String]</span><br>
whiteSepLine&nbsp;<span class="Statement">=</span>&nbsp;manyTill&nbsp;spaceSepWord&nbsp;newline&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;whiteSepLine&quot;</span><br>
<br>
<br>
<span class="Comment">-- -- WORD PARSERS -- -- </span><br>
<br>
<br>
<span class="Comment">-- a single word followed by whitespace (space, newline, etc.):</span><br>
word&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;<span class="Statement">&lt;-</span>&nbsp;many1&nbsp;nonWhite<br>
&nbsp;&nbsp;&nbsp;&nbsp;spaces<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;w<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;word&quot;</span><br>
<br>
<span class="Comment">-- a single word followed by one or more ' ' characters (won't consume '\n')</span><br>
spaceSepWord&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;<span class="Statement">&lt;-</span>&nbsp;many1&nbsp;nonWhite<br>
&nbsp;&nbsp;&nbsp;&nbsp;many&nbsp;(char&nbsp;<span class="Constant">' '</span>)<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;w<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;spaceSepWord&quot;</span><br>
<br>
<span class="Comment">-- e.g. &quot;hello:world&quot; ---&gt; (&quot;hello&quot;,&quot;world&quot;)</span><br>
<span class="Comment">-- won't consume newlines</span><br>
twoWordsSepBy&nbsp;c&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;<span class="Statement">&lt;-</span>&nbsp;manyTill&nbsp;nonWhite&nbsp;(try<span class="Statement">$</span>&nbsp;char&nbsp;c)<br>
&nbsp;&nbsp;&nbsp;&nbsp;y&nbsp;<span class="Statement">&lt;-</span>&nbsp;many1&nbsp;nonWhite<br>
&nbsp;&nbsp;&nbsp;&nbsp;many&nbsp;(char&nbsp;<span class="Constant">' '</span>)<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;(x,y)<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;twoWordsSepBy&quot;</span><br>
<br>
<br>
<span class="Comment">-- -- CHARACTER PARSERS -- --</span><br>
<br>
<br>
<span class="Comment">-- nonWhitespace character:</span><br>
nonWhite&nbsp;<span class="Statement">=</span>&nbsp;noneOf&nbsp;<span class="Constant">&quot; </span><span class="Special">\v\f\t\r\n</span><span class="Constant">&quot;</span>&nbsp;<span class="Statement">&lt;?&gt;</span>&nbsp;<span class="Constant">&quot;nonWhite&quot;</span><br>
<br>
<br>
<br></blockquote></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/08/haskell-boilerplate-for-google-codejam/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>List Grouping module released</title>
		<link>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/</link>
		<comments>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 01:09:55 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[sorting]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=202</guid>
		<description><![CDATA[<p><strong>EDIT:</strong> <em>Don&#8217;t use this package, but use instead <a href="http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html">Data.List.Split</a> by Brent Yorgey. I didn&#8217;t see that a package like his existed! This module will hopefully be removed from hackage if they can do that.</em></p>
<p>I just finished the initial&#8230; <a href="http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>EDIT:</strong> <em>Don&#8217;t use this package, but use instead <a href="http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html">Data.List.Split</a> by Brent Yorgey. I didn&#8217;t see that a package like his existed! This module will hopefully be removed from hackage if they can do that.</em></p>
<p>I just finished the initial release of a simple module called <a href="http://hackage.haskell.org/package/list-grouping">list-grouping</a> that contains functions to partition a list into sub-lists in various ways, based on some predicate or integer offset. Functions like these are a little awkward to write and I was surprised when I didn&#8217;t see anything on hackage! </p>
<p>Check out the package description and install it with:</p>
<blockquote><p>$ cabal install list-grouping</p></blockquote>
<p>Here is an example from a previous post to <a href="http://coder.bsimmons.name/blog/2009/03/building-a-tree-from-an-ordered-list/">build a binary tree from an in-order list</a>, which uses the above library:</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.Grouping<br>
<br>
<span class="Type">data</span>&nbsp;Tree&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;Node&nbsp;a&nbsp;(Tree&nbsp;a)&nbsp;(Tree&nbsp;a)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;End<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br>
<br>
fromSorted&nbsp;<span class="Statement">::</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree&nbsp;a<br>
fromSorted&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldl</span>&nbsp;mkTree&nbsp;End&nbsp;<span class="Statement">.</span>&nbsp;splitWith&nbsp;[<span class="Constant">2</span><span class="Statement">^</span>n&nbsp;<span class="Statement">|</span>&nbsp;n<span class="Statement">&lt;-</span>[<span class="Constant">0</span><span class="Statement">..</span>]]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;mkTree&nbsp;l&nbsp;(n<span class="Statement">:</span>ns)&nbsp;<span class="Statement">=</span>&nbsp;Node&nbsp;n&nbsp;l&nbsp;(fromSorted&nbsp;ns)<br>
<br></blockquote></p>
<p>I&#8217;m sure the functions can be made more efficient, to take advantage of <a href="http://www.reddit.com/r/haskell/comments/96s3q/understanding_when_ghc_will_fuse_away/?sort=new">fusion or what-not</a>, and I hope the library will eventually contain the most efficient implementations possible.</p>
<p>I also am looking for suggestions for other useful list grouping functions to include. Send your suggestions along! You can get the darcs source with:</p>
<blockquote><p>$ darcs get http://coder.bsimmons.name/code/ListGrouping/ </p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>directory-tree module released</title>
		<link>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/</link>
		<comments>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/#comments</comments>
		<pubDate>Sat, 09 May 2009 16:33:12 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=148</guid>
		<description><![CDATA[<p>I&#8217;ve released my first package, <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree">up now on hackage</a> (haddock docs should be generated soon). The module provides a simple data structure that mirrors a directory tree, and some useful functions for doing IO on directories of files. You&#8230; <a href="http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released my first package, <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree">up now on hackage</a> (haddock docs should be generated soon). The module provides a simple data structure that mirrors a directory tree, and some useful functions for doing IO on directories of files. You can <a href="http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/">read more about it here</a>.</p>
<p>It&#8217;s very likely there are some bugs, especially related to cross platform issues with file names and paths. The module is also fairly bare, so please send me any requests for functionality that I haven&#8217;t thought of, as well as any bugs you might find. </p>
<p>You can install it with:</p>
<blockquote><p>$ cabal install directory-tree</p></blockquote>
<p>And get the source with:</p>
<blockquote><p>$ darcs get http://coder.bsimmons.name/code/DirectoryTree/</p></blockquote>
<p>I hope this is useful to someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
