<?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>/dev/tty &#187; Ruby</title>
	<atom:link href="http://blog.tty.nl/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tty.nl</link>
	<description>Notes on Web Development, Computer Programming, and Software Engineering</description>
	<lastBuildDate>Thu, 29 Dec 2011 10:59:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Simple ranked text search for MongoDB</title>
		<link>http://blog.tty.nl/2010/02/08/simple-ranked-text-search-for-mongodb/</link>
		<comments>http://blog.tty.nl/2010/02/08/simple-ranked-text-search-for-mongodb/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 14:46:28 +0000</pubDate>
		<dc:creator>Ward Bekker</dc:creator>
				<category><![CDATA[Open Source Projects]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=329</guid>
		<description><![CDATA[In this code snippit you can see how to do a basic ranked text search for MongoDB. The code relies on two simple mapreduce operations. One to create an inverted index from some demo text, and a second one to &#8230; <a href="http://blog.tty.nl/2010/02/08/simple-ranked-text-search-for-mongodb/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this <a href="http://gist.github.com/298175">code snippit</a> you can see how to do a basic ranked text search for <a href="http://www.mongodb.org">MongoDB</a>. The code relies on two simple mapreduce operations. One to create an<a href="http://en.wikipedia.org/wiki/Inverted_index"> inverted index</a> from some demo text, and a second one to score the matching documents based on query term hits.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2010/02/08/simple-ranked-text-search-for-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby Quiz, Haskell Solution: LCD Numbers</title>
		<link>http://blog.tty.nl/2009/12/17/ruby-quiz-haskell-solution-lcd-numbers/</link>
		<comments>http://blog.tty.nl/2009/12/17/ruby-quiz-haskell-solution-lcd-numbers/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 13:26:34 +0000</pubDate>
		<dc:creator>Michel Rijnders</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Ruby Quiz]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=288</guid>
		<description><![CDATA[A solution to Ruby Quiz #14 in literate Haskell: LCD Numbers =========== Problem ------- [original source](http://rubyquiz.com/quiz14.html) This week's quiz is to write a program that displays LCD style numbers at adjustable sizes. The digits to be displayed will be passed &#8230; <a href="http://blog.tty.nl/2009/12/17/ruby-quiz-haskell-solution-lcd-numbers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A solution to Ruby Quiz #14 in literate Haskell:</p>
<pre>
LCD Numbers
===========

Problem
-------

[original source](http://rubyquiz.com/quiz14.html)

This week's quiz is to write a program that displays LCD style numbers
at adjustable sizes.

The digits to be displayed will be passed as an argument to the
program. Size should be controlled with the command-line option -s
follow up by a positive integer. The default value for -s is 2.

For example, if your program is called with:

    $ lcd.rb 012345

The correct display is:

     --        --   --        --
    |  |    |    |    | |  | |
    |  |    |    |    | |  | |
               --   --   --   --
    |  |    | |       |    |    |
    |  |    | |       |    |    |
     --        --   --        -- 

And for:

    $ lcd.rb -s 1 6789

Your program should print:

     -   -   -   -
    |     | | | | |
     -       -   -
    | |   | | |   |
     -       -   - 

Note the single column of space between digits in both examples. For
other values of -s, simply lengthen the - and | bars.

Solution
--------

Module declaration and imports:

> module Main where
>
> import Data.Char (digitToInt)
> import Data.List (intersperse)
> import System.Console.GetOpt
> import System.Environment (getArgs)

First we define the numbers at size 1:

> n0 = [ " - "
>      , "| |"
>      , "   "
>      , "| |"
>      , " - "
>      ]
>
> n1 = [ "   "
>      , "  |"
>      , "   "
>      , "  |"
>      , "   "
>      ]
>
> n2 = [ " - "
>      , "  |"
>      , " - "
>      , "|  "
>      , " - "
>      ]
>
> n3 = [ " - "
>      , "  |"
>      , " - "
>      , "  |"
>      , " - "
>      ]
>
> n4 = [ "   "
>      , "| |"
>      , " - "
>      , "  |"
>      , "   "
>      ]
>
> n5 = [ " - "
>      , "|  "
>      , " - "
>      , "  |"
>      , " - "
>      ]
>
> n6 = [ " - "
>      , "|  "
>      , " - "
>      , "| |"
>      , " - "
>      ]
>
> n7 = [ " - "
>      , "  |"
>      , "   "
>      , "  |"
>      , "   "
>      ]
>
> n8 = [ " - "
>      , "| |"
>      , " - "
>      , "| |"
>      , " - "
>      ]
>
> n9 = [ " - "
>      , "| |"
>      , " - "
>      , "  |"
>      , " - "
>      ]
>

Put the numbers in  a list:

> numbers = [n0,n1,n2,n3,n4,n5,n6,n7,n8,n9]

Horizontal scaling function, given a string replicate the second
character n times:

> hscale n cs = head cs : replicate n (cs!!1) ++ [last cs]

Vertical scaling function, repeat the second and fourth row n times:

> vscale n css = head css : replicate n cs1 ++ [cs2] ++ replicate n cs3 ++ [cs4]
>   where cs1 = css !! 1
>         cs2 = css !! 2
>         cs3 = css !! 3
>         cs4 = last css

Scale function; note this function scales a single number:

> scale n = vscale n . map (hscale n)

Function that converts a list of numbers to a string of LCD numbers:

> lcd n = concat .
>         intersperse "\n" .
>         foldr1 (zipWith (++)) .
>         intersperse (replicate (3 + 2*n) " ") .
>         map (scale n . (numbers !!))

`main` function:

> main = do
>   args <- getArgs
>   let (n, digits) = parseArgs args
>   putStrLn $ lcd n $ map digitToInt digits

Command-line argument parsing:

> data Flag = Scale Int
>             deriving Eq
>
> options = [Option "s" [] (ReqArg (Scale . read) "") ""]
>
> parseArgs args =
>   case parse args of
>    (_, [], _)              -> error "Usage: lcd [-s n] digits"
>    ([], digits, [])        -> (2, head digits)
>    ([Scale n], digits, []) -> (n, head digits)
>    (_, _, _)               -> error "Usage: lcd [-s n] digits"
>   where
>     parse = getOpt RequireOrder options
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/12/17/ruby-quiz-haskell-solution-lcd-numbers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby Quiz, Haskell Solution: Sampling</title>
		<link>http://blog.tty.nl/2009/09/27/ruby-quiz-haskell-solution-sampling/</link>
		<comments>http://blog.tty.nl/2009/09/27/ruby-quiz-haskell-solution-sampling/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 07:54:57 +0000</pubDate>
		<dc:creator>Michel Rijnders</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Ruby Quiz]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=222</guid>
		<description><![CDATA[The Quiz A classic sampling problem: write a program sample which takes two integers n and m as input. n is the size of the sample. m is the size of the population. The program should print out n random &#8230; <a href="http://blog.tty.nl/2009/09/27/ruby-quiz-haskell-solution-sampling/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>The Quiz</h2>
<p>A classic sampling problem: write a program <tt>sample</tt> which takes two integers <tt>n</tt> and <tt>m</tt> as input. <tt>n</tt> is the size of the sample. <tt>m</tt> is the size of the population. The program should print out <tt>n</tt> random unique indices. Two example runs:</p>
<pre>
$ ./sample 3 10
0
2
8
$ ./sample 3 10
1
2
9
</pre>
<p>The output must be sorted. The complete, original quiz is <a href="http://rubyquiz.com/quiz39.html" target="_blank">here</a>.
</p>
<h2>A Haskell Solution</h2>
<h3>Take One</h3>
<p>My first (naïve) attempt uses a list of integers to represent the pool still available (i.e. the population not sampled yet). When it has to draw a sample it takes a random number <tt>i</tt> between 0 and the length of the list and removes the element at index <tt>i</tt> from the list, thus guaranteeing the uniqueness of the generated indices. It works correctly but it runs out of memory for the &quot;big sample&quot; (<tt>n= 5,000,000</tt> and <tt>m = 1,000,000,000</tt>) mentioned in the original quiz, not very suprising since it keeps both the current samples as well as the pool still availabe in memory. It is also quite slow because of the use of a plain list.</p>
<div class="codecolorer-container haskell default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span><br />
<br />
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span><span style="color: #339933; font-weight: bold;">.</span>State<br />
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span>List <span style="color: green;">&#40;</span>delete<span style="color: #339933; font-weight: bold;">,</span> sort<span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">import</span> System <span style="color: green;">&#40;</span>getArgs<span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Random<br />
<br />
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><br />
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> n <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span><span style="color: #cccc00; font-weight: bold;">Int</span><br />
&nbsp; &nbsp; &nbsp; m <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span><br />
&nbsp; gen <span style="color: #339933; font-weight: bold;">&lt;-</span> getStdGen<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> <span style="font-weight: bold;">init</span> <span style="color: #339933; font-weight: bold;">=</span> RandomPool <span style="color: green;">&#91;</span><span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">..</span>m<span style="color: green;">&#93;</span> gen<br />
&nbsp; &nbsp; &nbsp; result <span style="color: #339933; font-weight: bold;">=</span> evalState <span style="color: green;">&#40;</span>sample n<span style="color: green;">&#41;</span> <span style="font-weight: bold;">init</span><br />
&nbsp; <span style="font-weight: bold;">mapM_</span> <span style="font-weight: bold;">print</span> <span style="color: green;">&#40;</span>sort result<span style="color: green;">&#41;</span><br />
<br />
<span style="color: #06c; font-weight: bold;">data</span> RandomPool <span style="color: #339933; font-weight: bold;">=</span> RandomPool <span style="color: green;">&#123;</span> pool <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><span style="color: #339933; font-weight: bold;">,</span> gen <span style="color: #339933; font-weight: bold;">::</span> StdGen <span style="color: green;">&#125;</span><br />
<br />
<span style="color: #06c; font-weight: bold;">type</span> StateRP <span style="color: #339933; font-weight: bold;">=</span> State RandomPool<br />
<br />
sample <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> StateRP <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><br />
sample <span style="color: red;">0</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">return</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><br />
sample n <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; st <span style="color: #339933; font-weight: bold;">&lt;-</span> get<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> hi <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">length</span> <span style="color: green;">&#40;</span>pool st<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-</span> <span style="color: red;">1</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>i<span style="color: #339933; font-weight: bold;">,</span> gen'<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> randomR <span style="color: green;">&#40;</span><span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> hi<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>gen st<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; x <span style="color: #339933; font-weight: bold;">=</span> pool st <span style="color: #339933; font-weight: bold;">!!</span>i<br />
&nbsp; &nbsp; &nbsp; pool' <span style="color: #339933; font-weight: bold;">=</span> delete x <span style="color: green;">&#40;</span>pool st<span style="color: green;">&#41;</span><br />
&nbsp; put RandomPool <span style="color: green;">&#123;</span> pool <span style="color: #339933; font-weight: bold;">=</span> pool'<span style="color: #339933; font-weight: bold;">,</span> gen <span style="color: #339933; font-weight: bold;">=</span> gen' <span style="color: green;">&#125;</span><br />
&nbsp; xs <span style="color: #339933; font-weight: bold;">&lt;-</span> sample <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">-</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span><br />
&nbsp; <span style="font-weight: bold;">return</span> <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span></div></div>
<h3>Take Two</h3>
<p>My second attempt solves the memory problem by keeping only the current samples in memory. When it has to draw a sample it takes a random number <tt>x</tt> between 0 and <tt>m</tt> and checks if that number has already been used. If the number has been used it tries agian. This solution also uses the <tt>Data.Set</tt> module for increased performance.</p>
<div class="codecolorer-container haskell default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span><br />
<br />
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span><span style="color: #339933; font-weight: bold;">.</span>State<br />
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span>List <span style="color: green;">&#40;</span>sort<span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span>Set <span style="color: #06c; font-weight: bold;">as</span> S <br />
<span style="color: #06c; font-weight: bold;">import</span> System <span style="color: green;">&#40;</span>getArgs<span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Random<br />
<br />
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><br />
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> n <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span><span style="color: #cccc00; font-weight: bold;">Int</span><br />
&nbsp; &nbsp; &nbsp; m <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span><br />
&nbsp; gen <span style="color: #339933; font-weight: bold;">&lt;-</span> getStdGen<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> <span style="font-weight: bold;">init</span> <span style="color: #339933; font-weight: bold;">=</span> RandomSet S<span style="color: #339933; font-weight: bold;">.</span>empty gen<br />
&nbsp; &nbsp; &nbsp; result <span style="color: #339933; font-weight: bold;">=</span> evalState <span style="color: green;">&#40;</span>sample m n<span style="color: green;">&#41;</span> <span style="font-weight: bold;">init</span><br />
&nbsp; <span style="font-weight: bold;">mapM_</span> <span style="font-weight: bold;">print</span> <span style="color: green;">&#40;</span>sort result<span style="color: green;">&#41;</span><br />
<br />
<span style="color: #06c; font-weight: bold;">data</span> RandomSet <span style="color: #339933; font-weight: bold;">=</span> RandomSet <span style="color: green;">&#123;</span> set <span style="color: #339933; font-weight: bold;">::</span> S<span style="color: #339933; font-weight: bold;">.</span>Set <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">,</span> gen <span style="color: #339933; font-weight: bold;">::</span> StdGen <span style="color: green;">&#125;</span><br />
<br />
<span style="color: #06c; font-weight: bold;">type</span> StateRS <span style="color: #339933; font-weight: bold;">=</span> State RandomSet<br />
<br />
sample <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> StateRS <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><br />
sample hi n <span style="color: #339933; font-weight: bold;">=</span><br />
&nbsp; <span style="color: #06c; font-weight: bold;">if</span> n <span style="color: #339933; font-weight: bold;">==</span> <span style="color: red;">0</span><br />
&nbsp; &nbsp; <span style="color: #06c; font-weight: bold;">then</span> <span style="color: #06c; font-weight: bold;">do</span> st <span style="color: #339933; font-weight: bold;">&lt;-</span> get<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-weight: bold;">return</span> <span style="color: green;">&#40;</span>toList <span style="color: green;">&#40;</span>set st<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #06c; font-weight: bold;">else</span> <span style="color: #06c; font-weight: bold;">do</span> draw hi<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample hi <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">-</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span><br />
<br />
draw <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> StateRS <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><br />
draw hi <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; st <span style="color: #339933; font-weight: bold;">&lt;-</span> get<br />
&nbsp; <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>x<span style="color: #339933; font-weight: bold;">,</span> gen'<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> randomR <span style="color: green;">&#40;</span><span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> hi <span style="color: #339933; font-weight: bold;">-</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>gen st<span style="color: green;">&#41;</span><br />
&nbsp; put st <span style="color: green;">&#123;</span> gen <span style="color: #339933; font-weight: bold;">=</span> gen' <span style="color: green;">&#125;</span><br />
&nbsp; <span style="color: #06c; font-weight: bold;">if</span> x `S<span style="color: #339933; font-weight: bold;">.</span>member` set st<br />
&nbsp; &nbsp; &nbsp;<span style="color: #06c; font-weight: bold;">then</span> draw hi<br />
&nbsp; &nbsp; &nbsp;<span style="color: #06c; font-weight: bold;">else</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;put st <span style="color: green;">&#123;</span> set <span style="color: #339933; font-weight: bold;">=</span> insert x <span style="color: green;">&#40;</span>set st<span style="color: green;">&#41;</span> <span style="color: green;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="font-weight: bold;">return</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span></div></div>
<p>Here&apos;s an example run for the big sample. Note that I have to increase the maximum stack size for individual threads (<tt>+RTS -K250m</tt>) to prevent a stack space overflow:</p>
<pre>
$ time ./sample 5000000 1000000000 +RTS -K250m > big_sample.txt 

real    23m24.355s
user    23m1.658s
sys     0m9.548s
$ ls -l big_sample.txt
-rw-r--r--  1 mies  staff  49483467 Sep 27 17:13 big_sample.txt
$ head big_sample.txt
243
280
416
494
556
602
804
909
970
1126
$ tail big_sample.txt
999998483
999998863
999999002
999999028
999999052
999999053
999999115
999999291
999999853
999999870
</pre>
<p>The code plus solutions to other quizes is available on <a href="http://github.com/rmies/Quiz/" target="_blank">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/09/27/ruby-quiz-haskell-solution-sampling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>100% completeness-fu</title>
		<link>http://blog.tty.nl/2009/09/23/100-completeness-fu/</link>
		<comments>http://blog.tty.nl/2009/09/23/100-completeness-fu/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 21:25:51 +0000</pubDate>
		<dc:creator>Josh Kalderimis</dc:creator>
				<category><![CDATA[Open Source Projects]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=214</guid>
		<description><![CDATA[The age of completeness-fu is upon us! Sometimes validations just don&#8217;t cut the mustard and all you want to do is to grade an instance based on how complete its information is. For example, a Location has a title and &#8230; <a href="http://blog.tty.nl/2009/09/23/100-completeness-fu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>The age of completeness-fu is upon us!</strong></p>
<p>Sometimes validations just don&#8217;t cut the mustard and all you want to do is to grade an instance based on how complete its information is. For example, a Location has a title and a description but no address, thus its only 60% complete. Or maybe title is worth more than description and address so its 80% complete. Whatever the case, this is not a new problem and recreating the wheel is a bit unnecessary, so welcome to <a href="http://github.com/joshk/completeness-fu">completeness-fu</a>.</p>
<p>The dsl is based on the <a href="http://github.com/freelancing-god/thinking-sphinx/">thinking-sphinx</a> configuration, which is nice, clean and simple, but very effective.</p>
<p>Here is a sample of the config code used to define a set of checks for a completeness score:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">define_completeness_scoring do<br />
&nbsp; check :title, &nbsp; &nbsp; &nbsp; lambda { |per| per.title.present? }, &nbsp;:high<br />
&nbsp; check :description, lambda { |per| per.description.present? }, :medium<br />
&nbsp; check :main_image, &nbsp;lambda { |per| per.main_image? }, &nbsp; &nbsp; :low<br />
end</div></div>
<p>It still needs some more tlc, but its a nice start and a simple solution for a common problem. </p>
<p>So please, have a play around with it, fork the code, make some improvements/enhancements and let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/09/23/100-completeness-fu/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Nginx + Passenger as your development environment</title>
		<link>http://blog.tty.nl/2009/09/17/using-nginx-passenger-as-your-development-environment/</link>
		<comments>http://blog.tty.nl/2009/09/17/using-nginx-passenger-as-your-development-environment/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 19:12:42 +0000</pubDate>
		<dc:creator>Josh Kalderimis</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=193</guid>
		<description><![CDATA[As a rails developer you are blessed early on with the fantastic script/server for starting a local development server. Rails is smart enough that it will even suggest you install the Mongrel gem as it is a faster alternative to &#8230; <a href="http://blog.tty.nl/2009/09/17/using-nginx-passenger-as-your-development-environment/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As a rails developer you are blessed early on with the fantastic script/server for starting a local development server. Rails is smart enough that it will even suggest you install the Mongrel gem as it is a faster alternative to the basic stock standard WEBrick. But as time passes and your skills improve and the amount of projects you are working on increases, you may find yourself looking for a simpler solution than having to start up an individual script/server on different ports for each project. Or you may just want to have an app run in the background waiting for you to access one of the sites and start it up automatically. What ever the case, there are some very nice solutions available.</p>
<p>99% percent of people who have deployed a rails app have undoubtedly come across Passenger (<a href="http://www.modrails.com/">modrails</a>)  from the fantastic guys at Phusion. Simple put, this allows you to config and run your rails app with (initially) Apache or (as of lately) Nginx while also taking advantage of their supplier static assets serving capabilities.</p>
<p>So why would you choose Nginx over Apache in you development environment? For me the reasons for using Nginx was simple and quick configuration, very very very low memory usage, and it mimics my deployment server setup.</p>
<p>So waffle aside, how do we install and setup Nginx, including for you development environment</p>
<p><strong>installing nginx and passenger</strong></p>
<p>Passenger is nice enough to offer to install Nginx for you automagically, including downloading Nginx 0.7.61, but this is already an old version, so the plan is to :</p>
<ol>
<li>download the latest stable version of nginx</li>
<li>extract to /usr/local/src/nginx</li>
<li>install the latest version of passenger via gem</li>
<li>have passenger configure, compile and install nginx for us</li>
<li>tweak the nginx configs</li>
<li>putting it all together</li>
</ol>
<p>so lets get started&#8230;.</p>
<p><strong>1. and 2. download the latest stable version of nginx and extract it</strong></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd /usr/local<br />
sudo mkdir src<br />
cd src<br />
wget http://sysoev.ru/nginx/nginx-0.7.62.tar.gz (latest verion at time of writing)<br />
tar -zxvf nginx-0.7.62.tar.gz</div></div>
<p><strong>3. and 4. install passenger via gem and configure, compile and install nginx</strong></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo gem install passenger (or sudo gem update passenger if already installed)<br />
sudo passenger-install-nginx-module</div></div>
<p>during the installer program enter the following information</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">When asked: ‘Where is your Nginx source code located?’<br />
answer /usr/local/src/nginx-0.7.62</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">When asked: ‘Where do you want to install Nginx to?’<br />
answer /usr/local/nginx</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">When asked about: ‘Extra arguments to pass to configure script:’<br />
answer --with-http_ssl_module</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">When asked to ‘Confirm configure flags’<br />
answer yes</div></div>
<p>Ok, now nginx and passenger are installed with ssl support baked in, what to do from here&#8230;</p>
<p><strong>5. tweak the nginx configs</strong></p>
<p>The default nginx config file is pretty basic, which is excellent, because its all you really need, but a  few tweaks here and there can make a great thing even better. <a href="http://slicehost.com">Slicehost</a> has an excellent write up on some recommended changes <a href="http://articles.slicehost.com/2009/8/14/debian-lenny-nginx-configuration">here</a>, but as this is your development environment and not production, I suggest not changing worker_processes or keepalive_timeout.</p>
<p>In the end, this is what my server nginx.conf looks like:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">worker_processes &nbsp;1;<br />
<br />
events {<br />
&nbsp; &nbsp; worker_connections &nbsp;1024;<br />
}<br />
<br />
http {<br />
&nbsp; &nbsp; passenger_root /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.5;<br />
&nbsp; &nbsp; passenger_ruby /opt/local/bin/ruby;<br />
<br />
&nbsp; &nbsp; include &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mime.types;<br />
&nbsp; &nbsp; default_type &nbsp;application/octet-stream;<br />
<br />
&nbsp; &nbsp; sendfile &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on;<br />
&nbsp; &nbsp; tcp_nopush &nbsp; &nbsp; on;<br />
&nbsp; &nbsp; tcp_nodelay &nbsp; &nbsp; off;<br />
<br />
&nbsp; &nbsp; keepalive_timeout &nbsp;65;<br />
<br />
&nbsp; &nbsp; gzip &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;on;<br />
&nbsp; &nbsp; gzip_comp_level &nbsp; 2;<br />
&nbsp; &nbsp; gzip_proxied &nbsp; &nbsp; &nbsp;any;<br />
&nbsp; &nbsp; gzip_types &nbsp; &nbsp; &nbsp; &nbsp;text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;<br />
<br />
&nbsp; &nbsp; # All the virtual hosts exist here<br />
&nbsp; &nbsp; include /usr/local/nginx/sites-enabled/*;<br />
}</div></div>
<p>(I have taken out all the commented out lines)</p>
<p>You will notice the passenger_root and passenger_ruby properties/directives in the conf file. These are required for passenger to start, but you don&#8217;t need to worry about inserting them as the passenger nginx installer does it for you.</p>
<p>This is what my virtual server file looks like:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">server {<br />
&nbsp; &nbsp; listen &nbsp; &nbsp; &nbsp; 80;<br />
&nbsp; &nbsp; server_name &nbsp;lotsoffunstuff.local;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; root /Users/me/Development/ruby-workspace/pet-projects/lotsoffunstuff.com/public;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; passenger_enabled on;<br />
&nbsp; &nbsp; rails_env development;<br />
}</div></div>
<p>And thats it, an nginx server + one virtual host all ready to run via:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo /usr/local/nginx/sbin/nginx</div></div>
<p>I also added an alias to me ~/.profile file</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">alias nginx='sudo /usr/local/nginx/sbin/nginx'<br />
alias stopnginx='sudo /usr/local/nginx/sbin/nginx -s stop'</div></div>
<p>now you can just use <strong>nginx</strong> and <strong>stopnginx</strong>.</p>
<p><strong>6. putting it all together</strong></p>
<p>ok, the title is a little deceptive as it all seems to be together, but there is one very important change yet to be made, making sure passenger can reach and read your source code.</p>
<p>I ran into this problem when I was setting up my environment, and it all has to do with how passenger and nginx works. As per any good webserver, you need to start it as root so it can access the right ports (80) and directories (pid files), but its worker processes should run as nobody or www-data to restrict unneeded access to other resources. For Nginx to know if the server is a rails app or not, its worker process needs to be able to access the document root, in this case public, and every single one of its parent directories. As I keep my development files within my home directory, nginx would throw a 403 error and add a non-descriptive error message to the error.log file.</p>
<p>Two options are available to fix this:</p>
<ol>
<li>add read access to all the parent directories to everyone (chmod o+r -R .)(I think)</li>
<li>have the nginx worker processes run as a privileged user which can access all the directories in the path</li>
</ol>
<p>I choose option two and had the nginx worker processes run as myself. Although you could argue this is insecure, as I only have the server running when I need to, and nginx and passenger have a great track record, I think this is better than setting my home directory to read for everyone.</p>
<p>And there we are, all set up and ready to develop! And all in under 30 mins!</p>
<p><strong>some good links and tips</strong></p>
<p>important for deployment : <a href="http://onehub.com/past/2009/3/6/rails_maintenance_pages_done_right/">rails maintenance pages done right</a><br />
init script for ubuntu : <a href="http://code.google.com/p/nginx-init-ubuntu/">nginx-init-ubuntu</a><br />
1.9 + nginx + passenger : <a href="http://swig505.com/2009/07/28/ruby-rails-nginx-passenger.html">ruby-rails-nginx-passenger</a><br />
excellent config details : <a href="https://articles.slicehost.com/2009/3/5/ubuntu-intrepid-nginx-configuration">ubuntu-intrepid-nginx-configuration</a><br />
nginx + vhosts : <a href="hhttp://articles.slicehost.com/2009/3/6/ubuntu-intrepid-nginx-virtual-hosts-1">ubuntu-intrepid-nginx-virtual-hosts</a><br />
docs galore : <a href="http://nginx.net/">http://nginx.net/</a> and <a href="http://wiki.nginx.net/">http://wiki.nginx.net/</a></p>
<p>special mention to <a href="http://articles.slicehost.com">slicehost</a> for all the fantastic server and service related articles known to man</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/09/17/using-nginx-passenger-as-your-development-environment/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ruby Quiz, Haskell Solution: Maximum Sub-Array</title>
		<link>http://blog.tty.nl/2009/08/30/ruby-quiz-haskell-solution-maximum-sub-array/</link>
		<comments>http://blog.tty.nl/2009/08/30/ruby-quiz-haskell-solution-maximum-sub-array/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 13:35:23 +0000</pubDate>
		<dc:creator>Michel Rijnders</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Ruby Quiz]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=157</guid>
		<description><![CDATA[The Quiz Given an array of integers, find the sub-array with maximum sum. (The complete, original quiz is here.) A Haskell Solution module Main where import Data.List &#40;inits, maximumBy, tails&#41; import System &#40;getArgs&#41; maxSubArray :: &#91;Int&#93; -&#62; &#91;Int&#93; maxSubArray = &#8230; <a href="http://blog.tty.nl/2009/08/30/ruby-quiz-haskell-solution-maximum-sub-array/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>The Quiz</h2>
<p>Given an array of integers, find the sub-array with maximum sum. (The complete, original quiz is <a href="http://rubyquiz.com/quiz131.html" target="_blank">here</a>.)</p>
<h2>A Haskell Solution</h2>
<div class="codecolorer-container haskell default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span><br />
<br />
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span>List <span style="color: green;">&#40;</span>inits<span style="color: #339933; font-weight: bold;">,</span> maximumBy<span style="color: #339933; font-weight: bold;">,</span> tails<span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">import</span> System <span style="color: green;">&#40;</span>getArgs<span style="color: green;">&#41;</span><br />
<br />
maxSubArray <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><br />
maxSubArray <span style="color: #339933; font-weight: bold;">=</span><br />
&nbsp; maximumBy <span style="color: green;">&#40;</span>\ x y <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="font-weight: bold;">compare</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">sum</span> x<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">sum</span> y<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">concatMap</span> inits <span style="color: #339933; font-weight: bold;">.</span> tails<br />
<br />
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><br />
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs<br />
&nbsp; <span style="font-weight: bold;">print</span> <span style="color: green;">&#40;</span>maxSubArray <span style="color: green;">&#40;</span><span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">head</span> args<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/08/30/ruby-quiz-haskell-solution-maximum-sub-array/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby Quiz, Haskell Solution: Happy Numbers</title>
		<link>http://blog.tty.nl/2009/08/24/ruby-quiz-haskell-solution-happy-numbers/</link>
		<comments>http://blog.tty.nl/2009/08/24/ruby-quiz-haskell-solution-happy-numbers/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 21:21:16 +0000</pubDate>
		<dc:creator>Michel Rijnders</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Ruby Quiz]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=125</guid>
		<description><![CDATA[The Quiz Write a program that tells whether a given integer is happy. A happy number is found using the following process: Take the sum of the squares of its digits, and continue iterating this process until it yields 1, &#8230; <a href="http://blog.tty.nl/2009/08/24/ruby-quiz-haskell-solution-happy-numbers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>The Quiz</h2>
<p>Write a program that tells whether a given integer is happy. A happy number is found using the following process: Take the sum of the squares of its digits, and continue iterating this process until it yields 1, or produces an infinite loop. (The complete, original quiz is <a href="http://rubyquiz.com/quiz93.html" target="_blank">here</a>.)</p>
<h2>A Haskell Solution</h2>
<div class="codecolorer-container haskell default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span><br />
<br />
<span style="color: #06c; font-weight: bold;">import</span> System <span style="color: green;">&#40;</span>getArgs<span style="color: green;">&#41;</span><br />
<br />
digits <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#93;</span><br />
digits <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> <span style="color: green;">&#40;</span>\c <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="font-weight: bold;">read</span> <span style="color: green;">&#91;</span>c<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">show</span><br />
<br />
happy <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">Bool</span><br />
happy n <span style="color: #339933; font-weight: bold;">=</span> happy' n <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><br />
&nbsp; <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; &nbsp; s <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">sum</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">map</span> <span style="color: green;">&#40;</span>\x <span style="color: #339933; font-weight: bold;">-&gt;</span> x <span style="color: #339933; font-weight: bold;">*</span> x<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">.</span> digits<br />
&nbsp; &nbsp; happy' n ns<br />
&nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">|</span> s n <span style="color: #339933; font-weight: bold;">==</span> <span style="color: red;">1</span> &nbsp; &nbsp; &nbsp;<span style="color: #339933; font-weight: bold;">=</span> True<br />
&nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">|</span> s n `<span style="font-weight: bold;">elem</span>` ns <span style="color: #339933; font-weight: bold;">=</span> False<br />
&nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">|</span> <span style="font-weight: bold;">otherwise</span> &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">=</span> happy' <span style="color: green;">&#40;</span>s n<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>n : ns<span style="color: green;">&#41;</span><br />
<br />
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><br />
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span><br />
&nbsp; args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs<br />
&nbsp; <span style="color: #06c; font-weight: bold;">if</span> happy <span style="color: green;">&#40;</span><span style="font-weight: bold;">read</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">head</span> args<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Int</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #06c; font-weight: bold;">then</span> <span style="font-weight: bold;">putStrLn</span> <span style="background-color: #3cb371;">&quot;:-)&quot;</span><br />
&nbsp; &nbsp; <span style="color: #06c; font-weight: bold;">else</span> <span style="font-weight: bold;">putStrLn</span> <span style="background-color: #3cb371;">&quot;:-(&quot;</span><br />
&nbsp; <span style="font-weight: bold;">return</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/08/24/ruby-quiz-haskell-solution-happy-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paperclip I18n call to arms</title>
		<link>http://blog.tty.nl/2009/07/22/paperclip-i18n-call-to-arms/</link>
		<comments>http://blog.tty.nl/2009/07/22/paperclip-i18n-call-to-arms/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 10:20:01 +0000</pubDate>
		<dc:creator>Josh Kalderimis</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[paperclip]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=43</guid>
		<description><![CDATA[Paperclip is a fantastic library used by many many many developers, its github project page shows 1500 watchers but I have a feeling even more than that use the plugin in some shape or form. The one thing that has &#8230; <a href="http://blog.tty.nl/2009/07/22/paperclip-i18n-call-to-arms/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Paperclip is a fantastic library used by many many many developers, its github project page shows 1500 watchers but I have a feeling even more than that use the plugin in some shape or form.</p>
<p>The one thing that has been missing for me is proper I18n support and not basic interpolations using the :message option. I recently chanced upon an issue in the github issues registry (#14) which included a fork that implemented a basic version of I18n support but did not go far enough in my opinion. So after taking some advice from validates_timeliness, I have created a fork with goes a little bit further and adds two new messages for the attachment size.</p>
<p>The only thing now is to get some support for this fork so it gets patched into paperclip.</p>
<p>So without further ado, please support this change by leaving a message in the google group thread regarding this change:</p>
<p>Google Group Message &#8211; <a href="http://groups.google.com/group/paperclip-plugin/browse_thread/thread/6c85b99e74420fa7">I18n changes and additions</a></p>
<p>And voting for this issue to be resolved:</p>
<p>Github Issue &#8211; <a href="http://github.com/thoughtbot/paperclip/issues#issue/14">Support for I18n</a></p>
<p>Also, if you have any questions, comments or advice regarding the fork, please don&#8217;t hesitate to leave a message below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/07/22/paperclip-i18n-call-to-arms/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Thinking Sphinx DateTime MVAs</title>
		<link>http://blog.tty.nl/2009/07/16/thinking-sphinx-datetime-mvas/</link>
		<comments>http://blog.tty.nl/2009/07/16/thinking-sphinx-datetime-mvas/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 22:08:20 +0000</pubDate>
		<dc:creator>Josh Kalderimis</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=12</guid>
		<description><![CDATA[One of the most popular open-source indexers for web development has to be Sphinx, an sql full-text search engine. Sphinx has been used by many high profile site, including The Pirate Bay, Craigs List, and NetLog, to name the big &#8230; <a href="http://blog.tty.nl/2009/07/16/thinking-sphinx-datetime-mvas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the most popular open-source indexers for web development has to be <a title="Sphinx" href="http://sphinxsearch.com/">Sphinx</a>, an sql full-text search engine. Sphinx has been used by many high profile site, including The Pirate Bay, Craigs List, and NetLog, to name the big ones (<a href="http://sphinxsearch.com/powered.html">more here</a>).</p>
<p>But this post is not about Sphinx, but its Ruby helper library, Thinking Sphinx. In fact, its not just about Thinking Sphinx, finding and fixing a problem yourself.</p>
<p>Thinking Sphinx is an amazing open source gem/plugin/library for Rails, masterminded by the great Pat Allan (<a href="http://twitter.com/pat">@pat</a>), and available to all on <a href="http://github.com/freelancing-god/thinking-sphinx/tree/master">github</a>. In fact, with 89 contributors and climbing, this library has had some tender love and care for many caring developers. If you are a Ruby developer and you are interested in indexing, have a look at Thinking Sphinx today, it is simple to install and use, fast and effective, and has some excellent documentation and a very active google group.</p>
<p>Recently while working on a new project for a client of ours I encountered an annoying issue/problem/bug with Thinking Sphinx, more specifically, DateTime multi-value attributes. A multi-value attribute (MVA) is like specifying an array of values for a specific field, for example, employee names, the trouble is that MVAs can only be integers so strings need to be converted (<a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC values</a>, <a href="http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_crc32">CRC32</a>) and datetimes need to be converted to unix timestamps. In Thinking Sphinx MVAs are usually defined through the relationships a model might hold, eg. an office has many employees.</p>
<p>Thinking Sphinx had no problem with me specifying MVAs of integers, but datetimes where a bit of an issue due to two issues, one is the converting, and the other is the group concat to add them all together with commas (like an array). Now, to say that it was an issue makes it sound worse than it really was, because by breaking down the issue into the two parts, converting and concatenating, two improvements could be made at the same time.</p>
<p>So after a brief chat with Pat on the google group to confirm the issue, and on a perfect sunday to be inside (hungover and not great weather), I forked Thinking Sphinx on <a href="http://github.com/joshk/thinking-sphinx/tree/master">github</a> (gotta love github for making forking projects so easy) and created a four commit patch which solved the MVA datetime issue for everyone. This patch has since been pulled into the master Thinking Sphinx project so others can use datetime columns as MVAs without having to think about it.</p>
<p>The whole experience of finding this bug, fixing it, and submitting a patch, has reenforced<strong> a very important lesson for all developers</strong>. If you run into a problem which you do not believe is excepted behavior, do not run away from it and try to find a workaround, get into the code and try to find out where and why the problem is occurring. Its very easy to use libraries and gems and plugins without really knowing how they work or what they do, but if you never get your hands dirty and investigate what is going on then you never learn.</p>
<p>If you can&#8217;t find the problem, ask for help on the message boards or by emailing the maintainer. On the other hand, if you do find the problem, check with the maintainer if he can confirm your findings.</p>
<p>Next, create a patch which fixes the issue and does not break or alter current functionality (unless it really does need altering).</p>
<p>And last but not least, share the patch with the community. (make the world a better place)</p>
<p>By the time you have finished with the patch you will not only know the code a lot better, but you would have learnt a truck load about the library, which in the long run is a huge advantage as you are not blindly trusting code written by a hoard of other developers but know first hand what is going on.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/07/16/thinking-sphinx-datetime-mvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

