<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8513438391157777465</id><updated>2012-01-25T18:36:32.066-08:00</updated><title type='text'>Re: Factor</title><subtitle type='html'>Factor: the language, the theory, and the practice.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default?start-index=101&amp;max-results=100'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>127</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1698303244758636335</id><published>2012-01-25T18:24:00.000-08:00</published><updated>2012-01-25T18:24:34.822-08:00</updated><title type='text'>Colored Timestamps</title><content type='html'>&lt;p&gt;I noticed a &lt;a href="http://coding.pressbin.com/123/Second-Color-maps-seconds-to-RGBA-colors"&gt;fun post&lt;/a&gt; in early December that implements a mapping between current time and a "unique" &lt;a href="http://en.wikipedia.org/wiki/RGBA_color_space"&gt;RGBA color&lt;/a&gt;.  I thought it might be fun to use &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; to implement a colored clock.&lt;/p&gt;&lt;p&gt;The basic concept is to map the 4,294,967,296 unique RGBA colors to seconds, which gives just over 136 years of unique colors.&lt;/p&gt;&lt;h2&gt;timestamp&amp;gt;rgba&lt;/h2&gt;&lt;p&gt;We calculate timestamps as an offset from &lt;a href="http://en.wikipedia.org/wiki/Dennis_Ritchie"&gt;Dennis Ritchie&lt;/a&gt;'s birthday:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;start-date&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1941 9 9 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The offset is an elapsed number of seconds from the start date:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;elapsed&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;seconds&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;start-date&lt;span style="color: #008000"&gt; &lt;/span&gt;time-&lt;span style="color: #008000"&gt; &lt;/span&gt;duration&amp;gt;seconds&lt;span style="color: #008000"&gt; &amp;gt;integer &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The conversion from a timestamp into a unique RGBA color does successive &lt;a href="http://docs.factorcode.org/content/word-__slash__mod,math.html"&gt;divmod&lt;/a&gt; operations to map into Red, Green, Blue, and Alpha values:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;timestamp&amp;gt;rgba&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;color/f&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;elapsed&lt;span style="color: #008000"&gt; dup &lt;/span&gt;&lt;span style="color: #666666"&gt;0 32 &lt;/span&gt;2^&lt;span style="color: #008000"&gt; &lt;/span&gt;between?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;24 &lt;/span&gt;2^&lt;span style="color: #008000"&gt; /mod &lt;/span&gt;&lt;span style="color: #666666"&gt;16 &lt;/span&gt;2^&lt;span style="color: #008000"&gt; /mod &lt;/span&gt;&lt;span style="color: #666666"&gt;8 &lt;/span&gt;2^&lt;span style="color: #008000"&gt; /mod&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;255 &lt;/span&gt;&lt;span style="color: #008000"&gt;/f &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;napply&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;rgba&amp;gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;You can try it for yourself, showing how the values change over time:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;start-date&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&amp;gt;rgba&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;rgba&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;red&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.0 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;green&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.0 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;blue&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.0 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;alpha&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.0 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;now&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&amp;gt;rgba&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;rgba&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;red&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.5176470588235295 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;green&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.3803921568627451 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;blue&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.4313725490196079 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;alpha&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.3333333333333333 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;&amp;lt;rgba-clock&amp;gt;&lt;/h2&gt;&lt;p&gt;Let's use the &lt;code&gt;timestamp&amp;gt;rgba&lt;/code&gt; word to make an updating "colored clock".  Specifically, we can use an &lt;a href="http://docs.factorcode.org/content/article-models.arrow.html"&gt;arrow model&lt;/a&gt; to update a &lt;a href="http://docs.factorcode.org/content/article-ui.gadgets.labels.html"&gt;label&lt;/a&gt; every second to create an RGBA clock:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;update-colors&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;color&lt;/span&gt; &lt;span style="color: #19177C"&gt;label&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;font&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;background&amp;lt;&amp;lt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;solid&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;interior&amp;lt;&amp;lt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;boundary&amp;lt;&amp;lt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2bi &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    2bi &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;rgba-clock&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;gadget&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;&amp;lt;label-control&amp;gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;time&lt;span style="color: #008000"&gt; get over &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&amp;gt;rgba&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;update-colors&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&amp;gt;hms&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;arrow&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;&amp;gt;model&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;HH:MM:SS&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;&amp;gt;string&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;monospace-font&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;&amp;gt;font&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Use the &lt;a href="http://docs.factorcode.org/content/word-gadget.,ui.gadgets.panes.html"&gt;gadget.&lt;/a&gt; word to try it in your listener, and watch it update:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;rgba-clock&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;gadget.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/second-color/second-color.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1698303244758636335?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1698303244758636335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1698303244758636335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1698303244758636335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1698303244758636335'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2012/01/colored-timestamps.html' title='Colored Timestamps'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-7511138317079200854</id><published>2012-01-13T16:07:00.000-08:00</published><updated>2012-01-13T16:07:06.770-08:00</updated><title type='text'>Friday the 13th</title><content type='html'>&lt;p&gt;In honor of January 13, 2012, a &lt;a href="http://en.wikipedia.org/wiki/Friday_the_13th"&gt;Friday the 13th&lt;/a&gt;, I thought it might be fun to use &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; to explore similar dates in past and future history.  According to Wikipedia, such a day "&lt;i&gt;occurs at least once, but at most three times a year&lt;/i&gt;".&lt;/p&gt;&lt;h2&gt;friday-13th?&lt;/h2&gt;&lt;p&gt;A day is "Friday the 13th" if it is both &lt;i&gt;(a)&lt;/i&gt; Friday and &lt;i&gt;(b)&lt;/i&gt; the 13th:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;friday-13th?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;day&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 = &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;friday?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi and &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Trying it for today and tomorrow, to make sure it works:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;now&lt;span style="color: #008000"&gt; &lt;/span&gt;friday-13th?&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #880000"&gt;t&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;tomorrow&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                   &lt;/span&gt;now&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;days&lt;span style="color: #008000"&gt; &lt;/span&gt;time+&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;tomorrow&lt;span style="color: #008000"&gt; &lt;/span&gt;friday-13th?&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #880000"&gt;f&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;friday-13ths&lt;/h2&gt;&lt;p&gt;Getting all Friday the 13th's for a given year:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;friday-13ths&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;year&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;12 &lt;/span&gt;[0,b)&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; dup &lt;/span&gt;friday?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; with map sift &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Or, for a range of years:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;all-friday-13ths&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;start-year&lt;/span&gt; &lt;span style="color: #19177C"&gt;end-year&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[a,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;friday-13ths&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map concat &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Trying it for 2012:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2012 &lt;/span&gt;friday-13ths&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;year&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2012 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;month&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;day&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;year&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2012 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;month&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;day&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;year&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2012 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;month&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;7 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;day&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;next-friday-13th&lt;/h2&gt;&lt;p&gt;We can iterate, looking for the next Friday the 13th:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-friday-13th&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;timestamp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;date&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;day&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;months&lt;span style="color: #008000"&gt; &lt;/span&gt;time+&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;&amp;gt;&amp;gt;day&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;friday?&lt;span style="color: #008000"&gt; not &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;months&lt;span style="color: #008000"&gt; &lt;/span&gt;time+&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; while &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Trying it for today, shows the next Friday the 13th is April, 13, 2012:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;now&lt;span style="color: #008000"&gt; &lt;/span&gt;next-friday-13th&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;year&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2012 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;month&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;day&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;13 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code (and some tests) for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/friday-13th/friday-13th.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-7511138317079200854?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/7511138317079200854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=7511138317079200854' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/7511138317079200854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/7511138317079200854'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2012/01/friday-13th.html' title='Friday the 13th'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4880953548780317710</id><published>2012-01-03T18:45:00.000-08:00</published><updated>2012-01-03T18:45:19.842-08:00</updated><title type='text'>Duplicate Files</title><content type='html'>&lt;p&gt;A few months ago, Jon Cooper wrote a &lt;a href="http://blog.carbonfive.com/2011/10/04/explorations-in-go-a-dupe-checker-in-go-and-ruby/"&gt;duplicate file checker&lt;/a&gt; in &lt;a href="http://golang.org"&gt;Go&lt;/a&gt; and &lt;a href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Below, I contribute a simple version in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; that runs faster than both Go and Ruby solutions.  In the spirit of the original article, I have separated the logic into steps.&lt;/p&gt;&lt;h2&gt;Argument Parsing&lt;/h2&gt;&lt;p&gt;The &lt;a href="http://docs.factorcode.org/content/article-cli.html"&gt;command-line&lt;/a&gt; vocabulary gives us the arguments passed to the script.  We check for the &lt;i&gt;verbose&lt;/i&gt; flag and the root directory to traverse:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;arg?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;name&lt;/span&gt; &lt;span style="color: #19177C"&gt;args&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;args&amp;#39;&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    2dup &lt;/span&gt;member?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; remove &lt;/span&gt;&lt;span style="color: #880000"&gt;t &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; nip &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;parse-args&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;verbose?&lt;/span&gt; &lt;span style="color: #19177C"&gt;root&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;--verbose&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;command-line&lt;span style="color: #008000"&gt; get &lt;/span&gt;arg?&lt;span style="color: #008000"&gt; swap first &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Filesystem Traversal&lt;/h2&gt;&lt;p&gt;We can traverse the filesystem with the &lt;a href="http://docs.factorcode.org/content/word-each-file,io.directories.search.html"&gt;each-file&lt;/a&gt; word (choosing breadth-first instead of depth-first).  In our case, we want to collect these files into a map of all paths that share a common filename:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;collect-files&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #880000"&gt;t &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; clone &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;file-name&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; push-at &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;each-file&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Our duplicate files are those files that share a common filename:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;duplicate-files&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;dupes&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;collect-files&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; nip length &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &amp;gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;assoc-filter!&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;MD5 Hashing Files&lt;/h2&gt;&lt;p&gt;Using the &lt;a href="http://docs.factorcode.org/content/vocab-checksums.md5.html"&gt;checksums.md5&lt;/a&gt; vocabulary, it is quite simple:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;md5-file&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;string&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;md5&lt;span style="color: #008000"&gt; &lt;/span&gt;checksum-file&lt;span style="color: #008000"&gt; &lt;/span&gt;hex-string&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Printing Results&lt;/h2&gt;&lt;p&gt;If &lt;i&gt;verbose&lt;/i&gt; is selected, then we print each filename and the MD5 checksum for each full path:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;print-md5&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;name&lt;/span&gt; &lt;span style="color: #19177C"&gt;paths&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%s:\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;md5-file&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  %s\n    %s\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;bi*&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We put this all together by calculating the possible duplicate files, optionally printing verbose MD5 checksums, and then print the total number of duplicates detected:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;run-dupe&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;parse-args&lt;span style="color: #008000"&gt; &lt;/span&gt;duplicate-files&lt;span style="color: #008000"&gt; swap&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;print-md5&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-each &lt;/span&gt;]&lt;span style="color: #008000"&gt; when&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    assoc-size &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Total duped files found: %d\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Performance&lt;/h2&gt;&lt;p&gt;I tested performance using two directory trees, one with over 500 files and another with almost 36,000 files.  While the original article focuses more on syntax than speed, it is nice to see that the Factor solution is faster than the Go and Ruby versions.&lt;/p&gt;&lt;blockquote&gt;&lt;table style="border: 1px solid gray" cellpadding="5"&gt;&lt;tr&gt;&lt;th&gt;Duplicates&lt;/th&gt;&lt;th&gt;Factor&lt;/th&gt;&lt;th&gt;Go&lt;/th&gt;&lt;th&gt;Ruby&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;583&lt;/td&gt;&lt;td&gt;&lt;b&gt;1.453&lt;/b&gt;&lt;/td&gt;&lt;td&gt;2.298&lt;/td&gt;&lt;td&gt;3.861&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;35,953&lt;/td&gt;&lt;td&gt;&lt;b&gt;19.084&lt;/b&gt;&lt;/td&gt;&lt;td&gt;24.452&lt;/td&gt;&lt;td&gt;30.597&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;i&gt;The above time is seconds on my laptop.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/dupe/dupe.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4880953548780317710?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4880953548780317710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4880953548780317710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4880953548780317710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4880953548780317710'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2012/01/duplicate-files.html' title='Duplicate Files'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-2872987612915165972</id><published>2011-12-31T16:08:00.000-08:00</published><updated>2012-01-02T09:56:44.695-08:00</updated><title type='text'>Picomath</title><content type='html'>&lt;p&gt;The &lt;a href="http://picomath.org"&gt;Picomath&lt;/a&gt; project holds some reusable math functions inspired by John D. Cook's &lt;a href="http://www.johndcook.com/stand_alone_code.html"&gt;Stand-alone code for numerical computing&lt;/a&gt;, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Error function&lt;/li&gt;&lt;li&gt;Phi (standard normal CDF)&lt;/li&gt;&lt;li&gt;Phi inverse&lt;/li&gt;&lt;li&gt;Gamma&lt;/li&gt;&lt;li&gt;Log Gamma&lt;/li&gt;&lt;li&gt;exp(x) - 1 (for small x)&lt;/li&gt;&lt;li&gt;log(n!)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These functions are &lt;a href="https://github.com/ghewgill/picomath"&gt;implemented&lt;/a&gt; in an impressive list of languages: Ada, C++, C#, D, Erlang, Go, Haskell, Java, Javascript, Lua, Pascal, Perl, PHP, Python (2.x and 3.x), Ruby, Scheme, and Tcl.&lt;/p&gt;&lt;p&gt;And now &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;You can find the code (and a bunch of tests) for this on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/picomath"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-2872987612915165972?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/2872987612915165972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=2872987612915165972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2872987612915165972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2872987612915165972'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/12/picomath.html' title='Picomath'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1622382874929462087</id><published>2011-12-30T14:48:00.000-08:00</published><updated>2011-12-30T18:12:43.485-08:00</updated><title type='text'>Slot Machines</title><content type='html'>&lt;p&gt;Playing &lt;a href="http://en.wikipedia.org/wiki/Slot_machine"&gt;slot machines&lt;/a&gt; can be pretty fun, but don't be fooled by claims that the casino has the "loosest slots", odds are probably still against you.  I thought it would be fun (&lt;i&gt;and cheaper!&lt;/i&gt;) to build a slot machine simulator using &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Our slot machine is going to be a &lt;a href="http://en.wikipedia.org/wiki/Console_application"&gt;console application&lt;/a&gt; that will look something like this:&lt;/p&gt;&lt;img src="https://lh3.googleusercontent.com/-dA0sVlrHL5w/Tv5r12ptH0I/AAAAAAAAANc/vK4pThlKSVo/s800/slot-machine.png" /&gt;&lt;h2&gt;Spinning&lt;/h2&gt;&lt;p&gt;Even though our slot machine is text-only, we can still make use of some nice unicode characters to be our symbols:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;SYMBOLS&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;☀☁☂☃&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Each spin chooses a different symbol at random (each being equally likely):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;spin&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;value&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;value&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;SYMBOLS&lt;span style="color: #008000"&gt; remove &lt;/span&gt;random&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To reproduce the feel of spinning a slot machine, we will introduce a slight delay so that the wheel spins fast at the beginning and then slower and slower until it stops on a symbol:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;spin-delay&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;15 * 25 + &lt;/span&gt;milliseconds&lt;span style="color: #008000"&gt; &lt;/span&gt;sleep&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Spinning the slot machine takes a spin number, delays for a bit, then rotates each wheel (we stop spinning the first column after 10 spins, the second after 15, and the last after 20):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;spin-slots&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;a&lt;/span&gt; &lt;span style="color: #19177C"&gt;b&lt;/span&gt; &lt;span style="color: #19177C"&gt;c&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;a&lt;/span&gt; &lt;span style="color: #19177C"&gt;b&lt;/span&gt; &lt;span style="color: #19177C"&gt;c&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;spin-delay&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10 &amp;lt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;spin&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2dip &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;15 &amp;lt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;spin&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;  dip &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;spin&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; cleave &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Display&lt;/h2&gt;&lt;p&gt;Each "spin" of the slot machine will be printed out.  Using &lt;a href="http://ascii-table.com/ansi-escape-sequences.php"&gt;ANSI escape sequences&lt;/a&gt;, we move the cursor to the top left ("0,0") of the screen and then issue a clear screen instruction.  Then we print out the current display and flush the output to screen:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;print-spin&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;a&lt;/span&gt; &lt;span style="color: #19177C"&gt;b&lt;/span&gt; &lt;span style="color: #19177C"&gt;c&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;a&lt;/span&gt; &lt;span style="color: #19177C"&gt;b&lt;/span&gt; &lt;span style="color: #19177C"&gt;c&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;\e[0;0H\e[2J&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Welcome to the Factor slot machine!&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print nl&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  +--------+&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  | CASINO |&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  |--------| *&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    3dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  |%c |%c |%c | |\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  |--------|/&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  |    [_] |&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;  +--------+&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print flush &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Playing&lt;/h2&gt;&lt;p&gt;The player will have won if, after all the spins, the "pay line" shows three of the same characters:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;winner?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;a&lt;/span&gt; &lt;span style="color: #19177C"&gt;b&lt;/span&gt; &lt;span style="color: #19177C"&gt;c&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    3array &lt;/span&gt;all-equal?&lt;span style="color: #008000"&gt; nl &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;You WIN!&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;You LOSE!&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;?&lt;span style="color: #008000"&gt; print nl &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Playing the slot machine consists of spinning the wheels 20 times, displaying each spin to the user, then checking if the user has won the game.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;play-slots&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #880000"&gt;f f f &lt;/span&gt;&lt;span style="color: #666666"&gt;20 &lt;/span&gt;&lt;span style="color: #008000"&gt;iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;spin-slots&lt;span style="color: #008000"&gt; &lt;/span&gt;print-spin&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;winner?&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Since our casino wants the user to keep playing, we make it really easy to just hit ENTER to continue:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;continue?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Press ENTER to play again.&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write flush readln &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And, to finish it off, we define a "MAIN" entry point that will be run when the script is executed:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;main-slots&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;play-slots&lt;span style="color: #008000"&gt; &lt;/span&gt;continue?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; loop &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;MAIN:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;main-slots&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/slot-machine/slot-machine.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1622382874929462087?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1622382874929462087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1622382874929462087' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1622382874929462087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1622382874929462087'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/12/slot-machines.html' title='Slot Machines'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-dA0sVlrHL5w/Tv5r12ptH0I/AAAAAAAAANc/vK4pThlKSVo/s72-c/slot-machine.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4829063496613704678</id><published>2011-12-28T12:56:00.000-08:00</published><updated>2011-12-28T13:00:08.310-08:00</updated><title type='text'>Elementology</title><content type='html'>&lt;p&gt;&lt;b&gt;Question:&lt;/b&gt; What do the words &lt;i&gt;bamboo&lt;/i&gt;, &lt;i&gt;crunchy&lt;/i&gt;, &lt;i&gt;finance&lt;/i&gt;, &lt;i&gt;genius&lt;/i&gt;, and &lt;i&gt;tenacious&lt;/i&gt; have in common?  I'll give you a hint: its the same thing they have in common with the words &lt;i&gt;who&lt;/i&gt;, &lt;i&gt;what&lt;/i&gt;, &lt;i&gt;when&lt;/i&gt;, &lt;i&gt;where&lt;/i&gt;, and &lt;i&gt;how&lt;/i&gt;?&lt;/p&gt;&lt;p&gt;Stumped? Well, it's not that these are all English words.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Answer:&lt;/b&gt; All of these words can be spelled using elements from the periodic table!&lt;/p&gt;&lt;p&gt;I was recently inspired by the &lt;a href="http://www.thinkgeek.com/tshirts-apparel/unisex/sciencemath/ea07/?srp=2"&gt;Periodic GeNiUS T-shirt&lt;/a&gt; from &lt;a href="http://www.thinkgeek.com"&gt;ThinkGeek&lt;/a&gt; and a &lt;a href="http://www.lmntology.com/"&gt;website&lt;/a&gt; that can "make any words out of elements in the periodic table".  I thought it would be fun to use &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; to see how many other words can be spelled using the symbols for chemical elements.&lt;/p&gt;&lt;img src="https://lh4.googleusercontent.com/-9qDpR0RJ1TU/TvuCTMQYv2I/AAAAAAAAANU/bMWVhe6zpTk/s800/periodic_genius.jpg" /&gt;&lt;p&gt;First, we need a list of elements:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;elements&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;H{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;H&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Hydrogen&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;He&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Helium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Li&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Lithium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Be&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Beryllium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;B&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Boron&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Carbon&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;...&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uut&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununtrium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uuq&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununquadium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uup&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununpentium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uuh&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununhexium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uus&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununseptium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Uuo&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Ununoctium&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;lower&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Next, a word that checks if a particular substring is the symbol of an element:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;element?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;from&lt;/span&gt; &lt;span style="color: #19177C"&gt;to&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    2dup length &lt;/span&gt;&lt;span style="color: #666666"&gt;&amp;gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; 3drop &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; subseq &lt;/span&gt;elements&lt;span style="color: #008000"&gt; &lt;/span&gt;key?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We know that symbols are only ever one, two, or three characters.  A word is considered "periodic" if it can be composed of any number of (possibly repeating) element symbols.  We build a recursive solution that starts with the first character and continues as long as element symbols are a match or until the end of the word is reached:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(periodic?)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #19177C"&gt;from&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; swap length &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 2 3 &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                dupd &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;[&lt;span style="color: #008000"&gt; pick &lt;/span&gt;element?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;(periodic?)&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;]&lt;span style="color: #008000"&gt; with &lt;/span&gt;any?&lt;span style="color: #008000"&gt; nip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;2||&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;periodic?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;gt;lower&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;(periodic?)&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;It's easy to get a list of dictionary words from most Unix systems:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;dict-words&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/usr/share/dict/words&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;ascii&lt;span style="color: #008000"&gt; &lt;/span&gt;file-lines&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And then a list of all "periodic words":&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;periodic-words&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;dict-words&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;periodic?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; filter &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;So, how many words are "periodic words"?  About 13.7% of them.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;dict-words&lt;span style="color: #008000"&gt; length &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;235886&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;scratchpad&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;periodic-words&lt;span style="color: #008000"&gt; length &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;32407&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/periodic-words/periodic-words.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4829063496613704678?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4829063496613704678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4829063496613704678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4829063496613704678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4829063496613704678'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/12/elementology.html' title='Elementology'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-9qDpR0RJ1TU/TvuCTMQYv2I/AAAAAAAAANU/bMWVhe6zpTk/s72-c/periodic_genius.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-2229474219053878456</id><published>2011-11-10T14:45:00.001-08:00</published><updated>2011-12-06T20:49:01.676-08:00</updated><title type='text'>wc -l</title><content type='html'>&lt;p&gt;The &lt;code&gt;wc&lt;/code&gt; program is a utility that can count the number of lines in a file.  It has a number of options that are described on its &lt;a href="http://linux.die.net/man/1/wc"&gt;man page&lt;/a&gt; that can change its function to count characters or word or produce the length of the longest line.&lt;/p&gt;&lt;p&gt;For the last month, Joe Groff has been improving the performance of &lt;a href="http://factorcode.org"&gt;Factor's&lt;/a&gt; I/O libraries.  Yesterday, we were &lt;a href="https://github.com/slavapestov/factor/issues/376"&gt;investigating&lt;/a&gt; slow performance when doing lots of small reads from a file.  Joe was able to make a number of nice speedups, which will be in the next release of Factor.&lt;/p&gt;&lt;p&gt;After suggesting that we use &lt;code&gt;wc -l&lt;/code&gt; as a benchmark to aspire to, we came up with several approaches with varying performance.  I want to demonstrate these, using timing information from running it on my computer.  Although the Factor image file is binary data, we are going to count the number of newline characters in it.&lt;/p&gt;&lt;blockquote&gt;&lt;i&gt;Note: some of these require the latest development version of Factor to run.&lt;/i&gt;&lt;/blockquote&gt;&lt;p&gt;Our "gold standard" will be &lt;code&gt;wc -l&lt;/code&gt;, which takes just over 0.1 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ time wc -l factor.image&lt;br /&gt; 6149212 factor.image&lt;br /&gt;&lt;br /&gt;real 0m0.111s&lt;br /&gt;user 0m0.090s&lt;br /&gt;sys  0m0.020s&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Our first attempt in Factor is the shortest amount of code but takes 5.8 seconds (you can time this by running "&lt;code&gt;USE: system [ image wc-file-lines ] time&lt;/code&gt;"):&lt;p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-file-lines&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;file-lines&lt;span style="color: #008000"&gt; length &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We don't really need the lines, just their count, so perhaps just increment &lt;code&gt;each-line&lt;/code&gt; in a loop.  This is an improvement at just over 3 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-each-line&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; each-line&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Trying to use &lt;code&gt;read-until&lt;/code&gt; to look for the next newline, is a bit slower at 3.4 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-read-until&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; read-until &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;]&lt;span style="color: #008000"&gt; loop&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Instead of reading each line at a time, we can just read 65,536 byte blocks and count the number of newlines.  This takes about 1.5 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-each-block&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: \n &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; count &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt; each-block&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Since we are only counting characters in each block, we don't need to allocate and copy the bytes out of the I/O buffer.  Instead, we can look at a &lt;code&gt;slice&lt;/code&gt;.  This takes about 1 second:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-each-block-slice&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: \n &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; count &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;each-block-slice&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The stream functions (such as &lt;code&gt;read&lt;/code&gt;) operate on an &lt;code&gt;input-stream&lt;/code&gt; dynamic variable, which introduces some overhead.  If we remove that, the compiler can eliminate some of the dynamic dispatches. taking 0.320 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-fast&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;file-reader&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: \n &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; count &lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;each-stream-block-slice&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-disposal&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;If we make an assumption that the number of lines in a file will fit into a &lt;code&gt;fixnum&lt;/code&gt;, then we can get a bit faster at 0.240 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-faster&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;file-reader&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: \n &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; count &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;fixnum&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;each-stream-block-slice&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-disposal&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And, if we cheat and just run the &lt;code&gt;wc -l&lt;/code&gt; process directly, we can get to 0.210 seconds:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-system&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;wc -l &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; prepend &lt;/span&gt;utf8&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        readln &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;split&lt;span style="color: #008000"&gt; harvest first &lt;/span&gt;string&amp;gt;number&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-process-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Overall, not too bad! &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; is getting within shouting distance of programs written in "faster" languages.  Probably with a few more hours, we could close the gap, but thats enough for today.&lt;/p&gt;&lt;i&gt;Update: using &lt;a href="http://en.wikipedia.org/wiki/SIMD"&gt;SIMD&lt;/a&gt;, Joe was able to get the time down to 0.120 seconds!&lt;/i&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;aligned-slices&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;head&lt;/span&gt; &lt;span style="color: #19177C"&gt;tail&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;   dup length &lt;/span&gt;&lt;span style="color: #666666"&gt;15 &lt;/span&gt;&lt;span style="color: #008000"&gt;bitnot bitand cut-slice &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wc-simd&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;       &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;file-reader&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;amp;dispose&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;           &lt;/span&gt;aligned-slices&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;uchar-16&lt;span style="color: #008000"&gt; &lt;/span&gt;cast-array&lt;span style="color: #008000"&gt; swap&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10 &lt;/span&gt;uchar-16-with&lt;span style="color: #008000"&gt; &lt;/span&gt;v=&lt;span style="color: #008000"&gt; &lt;/span&gt;vcount&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;fixnum &lt;/span&gt;]&lt;span style="color: #008000"&gt; reduce&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;           &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10 = &lt;/span&gt;]&lt;span style="color: #008000"&gt; count &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;fixnum &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;bi*&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;       &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;each-stream-block-slice&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-destructors&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-2229474219053878456?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/2229474219053878456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=2229474219053878456' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2229474219053878456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2229474219053878456'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/11/wc-l.html' title='wc -l'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1188864881111214394</id><published>2011-10-26T11:34:00.000-07:00</published><updated>2011-10-26T11:34:09.318-07:00</updated><title type='text'>Disassemble</title><content type='html'>&lt;p&gt;A neat trick that &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; provides is the ability to disassemble functions into the machine code that is generated by the compiler.  In 2008, Slava Pestov &lt;a href="http://factor-language.blogspot.com/2008/02/invoking-gdb-disassembler-to.html"&gt;created a disassembler&lt;/a&gt;, and has improved it a bit since then (switching to &lt;a href="http://udis86.sourceforge.net/"&gt;udis86&lt;/a&gt; for its implementation).&lt;/p&gt;&lt;h2&gt;Constant Folding&lt;/h2&gt;&lt;p&gt;The compiler performs constant folding, using the &lt;a href="http://docs.factorcode.org/content/vocab-compiler.tree.debugger.html"&gt;compiler.tree.debugger&lt;/a&gt; vocabulary, you can output the optimized form of a quotation:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 2 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;optimized.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Using the disassembler, you can see the machine code this generates:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 2 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;disassemble&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;011c1a5530: 4983c608        add r14, 0x8&lt;br /&gt;011c1a5534: 49c70640000000  mov qword [r14], 0x40&lt;br /&gt;011c1a553b: c3              ret &lt;br /&gt;011c1a553c: 0000            add [rax], al&lt;br /&gt;011c1a553e: 0000            add [rax], al&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Local Variables&lt;/h2&gt;&lt;p&gt;One of the questions that comes up sometimes is whether &lt;a href="http://docs.factorcode.org/content/article-locals.html"&gt;local variables&lt;/a&gt; affect performance.  We can examine two words that add numbers together, one using locals and one just using the stack:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;foo&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #19177C"&gt;y&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;z&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;bar&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #19177C"&gt;y&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;z&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;x&lt;span style="color: #008000"&gt; &lt;/span&gt;y&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The "optimized output" looks a little different:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; \ &lt;/span&gt;foo&lt;span style="color: #008000"&gt; &lt;/span&gt;optimized.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; \ &lt;/span&gt;bar&lt;span style="color: #008000"&gt; &lt;/span&gt;optimized.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;COMPLEX SHUFFLE&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;COMPLEX SHUFFLE&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;R&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;But, the machine code that is generated is identical:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; \ &lt;/span&gt;foo&lt;span style="color: #008000"&gt; &lt;/span&gt;disassemble&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;01115de7b0: 488d1d05000000  lea rbx, [rip+0x5]&lt;br /&gt;01115de7b7: e9e49439ff      jmp 0x110977ca0 (+)&lt;br /&gt;01115de7bc: 0000            add [rax], al&lt;br /&gt;01115de7be: 0000            add [rax], al&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; \ &lt;/span&gt;bar&lt;span style="color: #008000"&gt; &lt;/span&gt;disassemble&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;01115ef620: 488d1d05000000  lea rbx, [rip+0x5]&lt;br /&gt;01115ef627: e9748638ff      jmp 0x110977ca0 (+)&lt;br /&gt;01115ef62c: 0000            add [rax], al&lt;br /&gt;01115ef62e: 0000            add [rax], al&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Dynamic Variables&lt;/h2&gt;&lt;p&gt;Another frequently used feature is &lt;a href="http://docs.factorcode.org/content/article-namespaces.html"&gt;dynamic variables&lt;/a&gt;, implemented by the &lt;code&gt;namespaces&lt;/code&gt; vocabulary.   For example, the definition of the &lt;code&gt;print&lt;/code&gt; word looks for the current value of the &lt;code&gt;output-stream&lt;/code&gt; variable and then calls &lt;code&gt;stream-print&lt;/code&gt; on it:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; \ print &lt;/span&gt;see&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;namespaces&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;print&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; output-stream get stream-print &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The optimized output inlines the implementation of &lt;a href="http://docs.factorcode.org/content/word-get%2Cnamespaces.html"&gt;get&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Hello, world&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;optimized.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Hello, world&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; \ output-stream &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;context-object&lt;span style="color: #008000"&gt; assoc-stack&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    stream-print&lt;/span&gt;&lt;br /&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;You can inspect the machine code generated, seeing references to the factor words that are being called:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Hello, world&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;disassemble&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;011c0c6c40: 4c8d1df9ffffff        lea r11, [rip-0x7]&lt;br /&gt;011c0c6c47: 6820000000            push dword 0x20&lt;br /&gt;011c0c6c4c: 4153                  push r11&lt;br /&gt;011c0c6c4e: 4883ec08              sub rsp, 0x8&lt;br /&gt;011c0c6c52: 4983c618              add r14, 0x18&lt;br /&gt;011c0c6c56: 48b8dbc5a31a01000000  mov rax, 0x11aa3c5db&lt;br /&gt;011c0c6c60: 498946f0              mov [r14-0x10], rax&lt;br /&gt;011c0c6c64: 498b4500              mov rax, [r13+0x0]&lt;br /&gt;011c0c6c68: 488b4040              mov rax, [rax+0x40]&lt;br /&gt;011c0c6c6c: 498906                mov [r14], rax&lt;br /&gt;011c0c6c6f: 48b86c91810e01000000  mov rax, 0x10e81916c&lt;br /&gt;011c0c6c79: 498946f8              mov [r14-0x8], rax&lt;br /&gt;011c0c6c7d: e8de4e36ff            call 0x11b42bb60 (assoc-stack)&lt;br /&gt;011c0c6c82: 4883c418              add rsp, 0x18&lt;br /&gt;011c0c6c86: 488d1d05000000        lea rbx, [rip+0x5]&lt;br /&gt;011c0c6c8d: e94e5264ff            jmp 0x11b70bee0 (stream-print)&lt;br /&gt;011c0c6c92: 0000                  add [rax], al&lt;br /&gt;011c0c6c94: 0000                  add [rax], al&lt;br /&gt;011c0c6c96: 0000                  add [rax], al&lt;br /&gt;011c0c6c98: 0000                  add [rax], al&lt;br /&gt;011c0c6c9a: 0000                  add [rax], al&lt;br /&gt;011c0c6c9c: 0000                  add [rax], al&lt;br /&gt;011c0c6c9e: 0000                  add [rax], al&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1188864881111214394?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1188864881111214394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1188864881111214394' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1188864881111214394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1188864881111214394'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/10/disassemble.html' title='Disassemble'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4915996263601311634</id><published>2011-10-12T22:59:00.000-07:00</published><updated>2011-10-13T08:48:20.306-07:00</updated><title type='text'>Optimizing 2^x</title><content type='html'>&lt;p&gt;A great little article was posted last year about &lt;a href="http://falasol.net/2-pow-x-optimization-for-double-type"&gt;optimizing 2^x for doubles&lt;/a&gt; (by approximation).  The author gets 40+% performance improvements in C#.  I wondered if we could get similar improvements in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The basic idea is to use the fact that a number, &lt;code&gt;a&lt;sup&gt;b+c&lt;/sup&gt;&lt;/code&gt; can be factored into &lt;code&gt;a&lt;sup&gt;b&lt;/sup&gt; * a&lt;sup&gt;c&lt;/sup&gt;&lt;/code&gt;.  If we separate a floating point number into two components: an integer and a fractional part, we can show that:&lt;/p&gt;&lt;blockquote&gt;&lt;code&gt;2&lt;sup&gt;n&lt;/sup&gt; = 2&lt;sup&gt;integer(n)&lt;/sup&gt; * 2&lt;sup&gt;fractional(n)&lt;/sup&gt;&lt;/code&gt;.&lt;/blockquote&gt;&lt;p&gt;We are going to approximate this value by using a lookup table to compute the fractional part (within a specified precision).  For example, to compute within a 0.001 precision, we need 1000 lookup values, essentially performing this calculation:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;2&lt;sup&gt;n&lt;/sup&gt; = ( 1 &lt;&lt; Int(n) ) * Table[ (int) ( Frac(n) * 1000 ) ];&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Implementation&lt;/h2&gt;&lt;p&gt;So, we need a word that can split a floating point number into those two values:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;float&amp;gt;parts&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;float&lt;/span&gt; &lt;span style="color: #19177C"&gt;int&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &amp;gt;integer &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Instead of one table with 1000 values, we will copy the original authors decision to use three lookup tables for additional precision.  The following code calculates these lookup tables:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS1&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS2&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS1&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 * &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS3&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS1&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;3 * &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;BITS1&lt;span style="color: #008000"&gt; shift &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION2&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;BITS2&lt;span style="color: #008000"&gt; shift &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION3&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;BITS3&lt;span style="color: #008000"&gt; shift &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;MASK&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;FRAC1&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;/ ^ &lt;/span&gt;]&lt;span style="color: #008000"&gt; with map &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;FRAC2&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION2&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;/ ^ &lt;/span&gt;]&lt;span style="color: #008000"&gt; with map &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;FRAC3&lt;span style="color: #008000"&gt; &lt;/span&gt;$[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;PRECISION1&lt;span style="color: #008000"&gt; iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;PRECISION3&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;/ ^ &lt;/span&gt;]&lt;span style="color: #008000"&gt; with map &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The function &lt;code&gt;pow2&lt;/code&gt; looks pretty similar to our original mathematical definition:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;pow2&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;2^n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &amp;gt;float &lt;/span&gt;2^int&lt;span style="color: #008000"&gt; &lt;/span&gt;2^frac&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;* &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;float &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The guts of the implementation is in the &lt;code&gt;2^int&lt;/code&gt; and &lt;code&gt;2^frac&lt;/code&gt; words:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;2^int&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;2^int&lt;/span&gt; &lt;span style="color: #19177C"&gt;frac&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;float&amp;gt;parts&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap shift &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        over &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &amp;lt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;bi*&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; when&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap neg shift &lt;/span&gt;&lt;span style="color: #666666"&gt;1.0 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; if swap &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;2^frac&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;frac&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;2^frac&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;PRECISION3&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;* &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;fixnum&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS2&lt;span style="color: #008000"&gt; neg shift &lt;/span&gt;FRAC1&lt;span style="color: #008000"&gt; &lt;/span&gt;nth-unsafe&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;BITS1&lt;span style="color: #008000"&gt; neg shift &lt;/span&gt;MASK&lt;span style="color: #008000"&gt; bitand &lt;/span&gt;FRAC2&lt;span style="color: #008000"&gt; &lt;/span&gt;nth-unsafe&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;MASK&lt;span style="color: #008000"&gt; bitand &lt;/span&gt;FRAC3&lt;span style="color: #008000"&gt; &lt;/span&gt;nth-unsafe&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; tri &lt;/span&gt;&lt;span style="color: #666666"&gt;* * &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Testing&lt;/h2&gt;&lt;p&gt;Let's try it and see how well it works for small values:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 1.5 ^ &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;2.82842712474619&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1.5 &lt;/span&gt;pow2&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;2.82842712474619&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;It seem's to work, how about larger values:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 16.3 ^ &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;80684.28027297248&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;16.3 &lt;/span&gt;pow2&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;80684.28026255539&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The error is clearly detectable, but to test that it really works the way we expect it too, we will need to calculate relative error:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;relative-error&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;approx&lt;/span&gt; &lt;span style="color: #19177C"&gt;value&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;relative-error&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;&lt;span style="color: #008000"&gt;abs &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;&lt;span style="color: #666666"&gt;/ &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Our test case will generate random values, compute 2&lt;sup&gt;x&lt;/sup&gt; using our approximation and verify the relative error is less than 0.000000001 when compared with the correct result:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;t &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;10000 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;-20 20 &lt;/span&gt;uniform-random-float&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; replicate&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;pow2&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;&lt;span style="color: #666666"&gt;^ &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;relative-error&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    supremum &lt;/span&gt;1e-9&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt;&lt;br /&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;unit-test&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And to verify performance, we will benchmark it against the built-in (and more accurate &lt;code&gt;^&lt;/code&gt; word):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;pow2-test&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;new&lt;/span&gt; &lt;span style="color: #19177C"&gt;old&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;pow2&lt;span style="color: #008000"&gt; drop &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; each &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;benchmark&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;^ &lt;/span&gt;&lt;span style="color: #008000"&gt;drop &lt;/span&gt;]&lt;span style="color: #008000"&gt; with &lt;/span&gt;[&lt;span style="color: #008000"&gt; each &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;benchmark&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We got almost a 40% performance improvement at the cost of a small loss of precision - not bad! &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10000 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;-20 20 &lt;/span&gt;uniform-random-float&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; replicate&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;pow2-test&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;/ &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;float &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;0.6293153754782392&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/fast-pow/fast-pow.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4915996263601311634?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4915996263601311634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4915996263601311634' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4915996263601311634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4915996263601311634'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/10/optimizing-2x.html' title='Optimizing 2^x'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1324844737429529998</id><published>2011-09-25T16:18:00.000-07:00</published><updated>2011-09-25T17:08:20.335-07:00</updated><title type='text'>Approximating Pi</title><content type='html'>&lt;p&gt;A few days ago, it was &lt;a href="http://blog.wolfram.com/2011/09/15/from-pi-to-puzzles/"&gt;announced&lt;/a&gt; on the Wolfram Blog that a 13-year-old had made a record calculating 458 million terms for the continued fraction of &lt;code&gt;pi&lt;/code&gt;.  In the spirit of that, I thought I would show how to solve a question that sometimes gets asked at interviews:&lt;/p&gt;&lt;blockquote&gt;&lt;i&gt;Given that Pi can be estimated using the function 4 * (1 - 1/3 + 1/5 - 1/7 + ...) with more terms giving greater accuracy, write a function that calculates Pi to an accuracy of 5 decimal places.&lt;/i&gt;&lt;/blockquote&gt;&lt;p&gt;Using &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;, we can calculate the &lt;code&gt;nth&lt;/code&gt; approximation of &lt;code&gt;pi&lt;/code&gt; using &lt;a href="http://docs.factorcode.org/content/article-math-vectors-arithmetic.html"&gt;vector arithmetic&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;approximate-pi&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;approx&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[1,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;v*n&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;v-n&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;n/v&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;odd?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; neg &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;]&lt;span style="color: #008000"&gt; map-index sum &lt;/span&gt;&lt;span style="color: #666666"&gt;4 * &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This isn't ideal if we want to try an increasing number of terms (looking for a particularly accuracy), since a lot of the the work would be redone unnecessarily.  Instead, we can write a word that adds successive terms until the difference between the previous approximation and the current approximation is less than our requested accuracy.&lt;/p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-term&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;approx&lt;/span&gt; &lt;span style="color: #19177C"&gt;i&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;approx&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 * 1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;odd?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; neg &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;&lt;span style="color: #666666"&gt;4.0 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;&lt;span style="color: #666666"&gt;/ + &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;find-pi-to&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;accuracy&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #19177C"&gt;approx&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 4.0 &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        dup pick &lt;/span&gt;next-term&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        swap abs &lt;/span&gt;accuracy&lt;span style="color: #008000"&gt; &amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2dip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; loop &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To show its performance, we can &lt;a href="http://docs.factorcode.org/content/word-time,tools.time.html"&gt;time&lt;/a&gt; it:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.00001 &lt;/span&gt;find-pi-to&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;time&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;Running&lt;span style="color: #008000"&gt; &lt;/span&gt;time:&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.026030341 &lt;/span&gt;seconds&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;3.141597653564762&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;An equivalent function in Python might look like this:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #0000FF"&gt;find_pi_to&lt;/span&gt;(accuracy):&lt;br /&gt;    i &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;&lt;br /&gt;    approx &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #666666"&gt;4.0&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000; font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;:&lt;br /&gt;        term &lt;span style="color: #666666"&gt;=&lt;/span&gt; (&lt;span style="color: #666666"&gt;2&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt; i) &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; i &lt;span style="color: #666666"&gt;%&lt;/span&gt; &lt;span style="color: #666666"&gt;2&lt;/span&gt; &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;:&lt;br /&gt;            term &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt;term&lt;br /&gt;        new &lt;span style="color: #666666"&gt;=&lt;/span&gt; approx &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #666666"&gt;4.0/&lt;/span&gt;term&lt;br /&gt;        &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #008000"&gt;abs&lt;/span&gt;(new &lt;span style="color: #666666"&gt;-&lt;/span&gt; approx) &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; accuracy:&lt;br /&gt;            approx &lt;span style="color: #666666"&gt;=&lt;/span&gt; new&lt;br /&gt;            &lt;span style="color: #008000; font-weight: bold"&gt;break&lt;/span&gt;&lt;br /&gt;        i &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;&lt;br /&gt;        approx &lt;span style="color: #666666"&gt;=&lt;/span&gt; new&lt;br /&gt;    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; approx&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;But, if we time this version (not counting startup or compile time), it takes 0.134 seconds.  Doing the math shows that Factor is 5 times faster than Python in this case.  Not bad.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1324844737429529998?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1324844737429529998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1324844737429529998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1324844737429529998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1324844737429529998'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/approximating-pi.html' title='Approximating Pi'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-3916570492262559343</id><published>2011-09-22T17:32:00.000-07:00</published><updated>2011-09-22T19:52:02.557-07:00</updated><title type='text'>Really Big Numbers</title><content type='html'>&lt;p&gt;&lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; supports both &lt;code&gt;fixnum&lt;/code&gt; (fixed size integers, typically 32- or 64-bit values) and &lt;code&gt;bignum&lt;/code&gt; (arbitrarily large integers).  Recently, I discovered that Factor did not have support for calculating the &lt;a href="http://en.wikipedia.org/wiki/Natural_logarithm"&gt;logarithm&lt;/a&gt; of &lt;i&gt;really big numbers&lt;/i&gt; (those larger than 2&lt;sup&gt;1024&lt;/sup&gt;).&lt;/p&gt;&lt;p&gt;You can define a simple factorial function:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;factorial&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n!&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[1,b]&lt;span style="color: #008000"&gt; product &lt;/span&gt;]&lt;span style="color: #008000"&gt; if-zero &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;But if you tried to calculate the logarithm of &lt;code&gt;1000 factorial&lt;/code&gt;, it produces the wrong answer.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1000 &lt;/span&gt;factorial&lt;span style="color: #008000"&gt; &lt;/span&gt;log&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;1/0.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The reason for this is that Factor attempts to convert a &lt;code&gt;bignum&lt;/code&gt; into a double-precision floating point number and take the logarithm of that.  Unfortunately, the value in this case is too large. What do other languages do in this case?  &lt;p&gt;&lt;p&gt;We could look at Ruby, but it has the same problem as Factor:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #666666"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #880000"&gt;Math&lt;/span&gt;&lt;span style="color: #666666"&gt;::&lt;/span&gt;log((&lt;span style="color: #666666"&gt;1.&lt;/span&gt;.&lt;span style="color: #666666"&gt;1000&lt;/span&gt;)&lt;span style="color: #666666"&gt;.&lt;/span&gt;inject(&lt;span style="color: #19177C"&gt;:*&lt;/span&gt;))&lt;br /&gt;(irb):&lt;span style="color: #666666"&gt;8&lt;/span&gt;: warning: Bignum out of Float range&lt;br /&gt;&lt;span style="color: #666666"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #880000"&gt;Infinity&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;However, you can get the &lt;a href="http://www.wolframalpha.com/input/?i=log%28factorial%281000%29%29"&gt;right answer&lt;/a&gt; in Python:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #666666"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #0000FF"&gt;factorial&lt;/span&gt;(n):&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;    r &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;    &lt;span style="color: #008000; font-weight: bold"&gt;while&lt;/span&gt; n &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #666666"&gt;0&lt;/span&gt;:&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;        r &lt;span style="color: #666666"&gt;*=&lt;/span&gt; n&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;        n &lt;span style="color: #666666"&gt;-=&lt;/span&gt; &lt;span style="color: #666666"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; r&lt;br /&gt;&lt;span style="color: #666666"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; math&lt;span style="color: #666666"&gt;.&lt;/span&gt;log(factorial(&lt;span style="color: #666666"&gt;1000&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #666666"&gt;5912.128178488163&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;If you look under the covers, you will see that Python handles this case by calling &lt;a href="http://linux.die.net/man/3/frexp"&gt;frexp&lt;/a&gt; to split a value into a fraction (&lt;code&gt;x&lt;/code&gt;) and a power of two (&lt;code&gt;exp&lt;/code&gt;). The original value can be calculated as &lt;code&gt;x*2&lt;sup&gt;exp&lt;/sup&gt;&lt;/code&gt;.  Using this, the logarithm can be computed as &lt;code&gt;log(x) + log(2) * exp&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;After discussing this on &lt;a href="http://concatenative.org/wiki/view/Concatenative%20IRC%20channel"&gt;#concatenative&lt;/a&gt;, Joe Groff and I came up with a solution for this.  I'm not going to go over all the details, but if you're curious, you can look at the &lt;a href="https://github.com/slavapestov/factor/issues/160"&gt;discussion&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;First, we implemented a cross-platform version of &lt;code&gt;frexp&lt;/code&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;GENERIC:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;frexp&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;y&lt;/span&gt; &lt;span style="color: #19177C"&gt;exp&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;M:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;float&lt;/span&gt; &lt;span style="color: #0000FF"&gt;frexp&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;fp-special?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;unless*&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        double&amp;gt;bits&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt; &lt;/span&gt;800f,ffff,ffff,ffff&lt;span style="color: #008000"&gt; bitand&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;&lt;span style="color: #666666"&gt;0.5 &lt;/span&gt;&lt;span style="color: #008000"&gt;double&amp;gt;bits bitor bits&amp;gt;double&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;-52 &lt;/span&gt;&lt;span style="color: #008000"&gt;shift &lt;/span&gt;&lt;span style="color: #666666"&gt;HEX: 7ff &lt;/span&gt;&lt;span style="color: #008000"&gt;bitand &lt;/span&gt;&lt;span style="color: #666666"&gt;1022 - &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;M:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;integer&lt;/span&gt; &lt;span style="color: #0000FF"&gt;frexp&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0.0 0 &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        dup &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &amp;gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; abs &lt;/span&gt;&lt;span style="color: #666666"&gt;-1 &lt;/span&gt;]&lt;span style="color: #008000"&gt; if swap dup log2 &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;&lt;span style="color: #666666"&gt;52 &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;&lt;span style="color: #008000"&gt;shift &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt; &lt;/span&gt;000f,ffff,ffff,ffff&lt;span style="color: #008000"&gt; bitand&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;&lt;span style="color: #666666"&gt;0.5 &lt;/span&gt;&lt;span style="color: #008000"&gt;double&amp;gt;bits bitor bits&amp;gt;double&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;* &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; if-zero &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Next, we added support for &lt;code&gt;log&lt;/code&gt; and &lt;code&gt;log10&lt;/code&gt; of &lt;code&gt;bignum&lt;/code&gt;.  If the number can be represented as a float, we continue to process it as before, but if it is larger, we calculate it similar to Python (with some caching of the &lt;code&gt;log(2)&lt;/code&gt; and &lt;code&gt;log10(2)&lt;/code&gt; values for performance):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;most-negative-finite-float&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt; &lt;/span&gt;-1.ffff,ffff,ffff,fp1023&lt;span style="color: #008000"&gt; &amp;gt;integer &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;most-positive-finite-float&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt;  &lt;/span&gt;1.ffff,ffff,ffff,fp1023&lt;span style="color: #008000"&gt; &amp;gt;integer &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;log-2&lt;span style="color: #008000"&gt;   &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt; &lt;/span&gt;1.62e42fefa39efp-1&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;CONSTANT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;log10-2&lt;span style="color: #008000"&gt; &lt;/span&gt;HEX:&lt;span style="color: #008000"&gt; &lt;/span&gt;1.34413509f79ffp-2&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(representable-as-float?)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;most-negative-finite-float&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;most-positive-finite-float&lt;span style="color: #008000"&gt; &lt;/span&gt;between?&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(bignum-log)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #19177C"&gt;log-quot:&lt;/span&gt;&lt;span style="color: #0000FF"&gt; (&lt;/span&gt; &lt;span style="color: #19177C"&gt;x&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;y&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt; &lt;span style="color: #19177C"&gt;log-2&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;log&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        dup &lt;/span&gt;(representable-as-float?)&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &amp;gt;float &lt;/span&gt;@&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;frexp&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;@&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;* &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;bi*&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; call &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;M:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;bignum&lt;/span&gt; &lt;span style="color: #0000FF"&gt;log&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;log&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;log-2&lt;span style="color: #008000"&gt; &lt;/span&gt;(bignum-log)&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;M:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;bignum&lt;/span&gt; &lt;span style="color: #0000FF"&gt;log10&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;log10&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;log10-2&lt;span style="color: #008000"&gt; &lt;/span&gt;(bignum-log)&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And now, in the listener you can get the answer!&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1000 &lt;/span&gt;factorial&lt;span style="color: #008000"&gt; &lt;/span&gt;log&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;5912.128178488163&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This change is now in the Factor &lt;a href="https://github.com/slavapestov/factor"&gt;repository&lt;/a&gt; (if you'd like to update), and will be in the next release.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-3916570492262559343?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/3916570492262559343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=3916570492262559343' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/3916570492262559343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/3916570492262559343'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/really-big-numbers.html' title='Really Big Numbers'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-8260918038389270076</id><published>2011-09-20T16:13:00.000-07:00</published><updated>2011-09-21T08:59:47.466-07:00</updated><title type='text'>Enigma Machines</title><content type='html'>&lt;p&gt;I noticed a fun blog post about &lt;a href="http://www.stealthcopter.com/blog/2011/05/recreating-the-enigma-in-python/"&gt;recreating the Enigma machine&lt;/a&gt; in Python.  For those who need a refresher, an &lt;a href="http://en.wikipedia.org/wiki/Enigma_machine"&gt;Enigma machine&lt;/a&gt; was an encryption device used before and during World War II. I thought it would be fun to implement this in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Build It&lt;/h2&gt;&lt;p&gt;Our alphabet will be the 26 letters in the &lt;a href="http://en.wikipedia.org/wiki/English_alphabet"&gt;English alphabet&lt;/a&gt;, indexed from 0 to 25 ("a" to "z"):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;alphabet&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;26 &lt;/span&gt;&lt;span style="color: #008000"&gt;iota &amp;gt;array &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The Enigma machine is made up of a number of "cogs", which contain an encoding.  We will create a cog using a randomized alphabet:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;cog&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;cog&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;lt;alphabet&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;randomize&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We need to create a utility function to remove a random element from a sequence:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;remove-random&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; length &lt;/span&gt;random&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;[&lt;span style="color: #008000"&gt; nth &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; remove-nth &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2bi &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;A special rotor called a "reflector" connected pairs of outputs, ensuring that encryption and decryption were the same process.  It also gave the Enigma machine the property that no letter encrypted to itself (a flaw which was used to help break the code).  We can create a reflector by taking the alphabet, and randomly exchanging pairs of elements:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;reflector&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;reflector&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;lt;alphabet&amp;gt;&lt;span style="color: #008000"&gt; dup length iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;empty?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;remove-random&lt;span style="color: #008000"&gt; &lt;/span&gt;remove-random&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; pick exchange &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; until drop &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can now create an Enigma machine with a number of cogs and a reflector:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;TUPLE:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;enigma&lt;/span&gt; &lt;span style="color: #19177C"&gt;cogs&lt;/span&gt; &lt;span style="color: #19177C"&gt;prev-cogs&lt;/span&gt; &lt;span style="color: #19177C"&gt;reflector&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;enigma&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;num-cogs&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;enigma&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;cog&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; replicate dup clone &lt;/span&gt;&amp;lt;reflector&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;enigma&lt;span style="color: #008000"&gt; boa &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We need a way to check for special characters (those not in the 26 letter alphabet):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;special?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;25 &amp;gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &amp;lt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi or &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We need a utility function to change several elements of a sequence at the same time:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;change-nths&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;indices&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #19177C"&gt;quot:&lt;/span&gt;&lt;span style="color: #0000FF"&gt; (&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; change-nth &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2curry each &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Encoding a piece of text is where all the work is performed.  The main strategy is to apply each character (that isn't special) through the cogs and then the reflector to find the encoded character, and then cycle the cogs to prepare for the next character.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;encode&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;text&lt;/span&gt; &lt;span style="color: #19177C"&gt;enigma&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;cipher-text&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;ln!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;enigma&lt;span style="color: #008000"&gt; &lt;/span&gt;cogs&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;cogs&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;enigma&lt;span style="color: #008000"&gt; &lt;/span&gt;reflector&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;reflector&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;text&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;lower&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: a &lt;/span&gt;&lt;span style="color: #008000"&gt;mod dup &lt;/span&gt;special?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;ln&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;ln!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;cogs&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; nth &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;reflector&lt;span style="color: #008000"&gt; nth&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;cogs&lt;span style="color: #008000"&gt; reverse &lt;/span&gt;[&lt;span style="color: #008000"&gt; index &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: a &lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;cogs&lt;span style="color: #008000"&gt; length iota &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;6 * 1 + &lt;/span&gt;ln&lt;span style="color: #008000"&gt; mod &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; filter&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;cogs&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; unclip prefix &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;change-nths&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;Note: this converts the text to lowercase before encoding.  The &lt;code&gt;encode&lt;/code&gt; word could be expanded to support uppercase, but its much simpler this way.&lt;/i&gt;&lt;/blockquote&gt;&lt;p&gt;If we make a word to reset the cogs back to the original configuration, we can verify that the encrypted text can be decrypted back to the original.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;reset-cogs&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;enigma&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;enigma&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;prev-cogs&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;&amp;gt;cogs&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Try It&lt;/h2&gt;&lt;p&gt;We can experiment with this in the Listener, creating a 4-cog Enigma machine and then encoding, resetting, and encoding again:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;&amp;lt;enigma&amp;gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;hello, world&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; over &lt;/span&gt;encode&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; print &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep&lt;/span&gt;&lt;br /&gt;luhhn,&lt;span style="color: #008000"&gt; &lt;/span&gt;xnzha&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; over &lt;/span&gt;reset-cogs&lt;span style="color: #008000"&gt; &lt;/span&gt;encode&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;hello,&lt;span style="color: #008000"&gt; &lt;/span&gt;world&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/enigma/enigma.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-8260918038389270076?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/8260918038389270076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=8260918038389270076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/8260918038389270076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/8260918038389270076'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/enigma-machines.html' title='Enigma Machines'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4016796807957845533</id><published>2011-09-18T08:53:00.000-07:00</published><updated>2011-09-18T09:46:57.099-07:00</updated><title type='text'>Most Pressed Keys</title><content type='html'>&lt;p&gt;Mahdi Yusuf made a fun &lt;a href="http://www.mahdiyusuf.com/post/9947002105/most-pressed-keys-and-programming-syntaxes"&gt;blog post&lt;/a&gt; about which keys get pressed the most in various programming languages.  I thought I would generate one for &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;:&lt;/p&gt;&lt;img src="https://lh5.googleusercontent.com/-GB1kt7i8ucE/TnYS6qmADUI/AAAAAAAAANA/kOojbhSgpwU/factor-heatmap-small.png" /&gt;&lt;p&gt;This was assembled by taking all the source code (not documentation or tests) from &lt;code&gt;core/&lt;/code&gt; and &lt;code&gt;basis/&lt;/code&gt; in the Factor &lt;a href="https://github.com/slavapestov/factor"&gt;codebase&lt;/a&gt; and passing it through &lt;a href="http://www.patrick-wied.at/projects/heatmap-keyboard/"&gt;heatmap.js&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4016796807957845533?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4016796807957845533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4016796807957845533' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4016796807957845533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4016796807957845533'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/most-pressed-keys.html' title='Most Pressed Keys'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-GB1kt7i8ucE/TnYS6qmADUI/AAAAAAAAANA/kOojbhSgpwU/s72-c/factor-heatmap-small.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4600537455313903188</id><published>2011-09-11T08:51:00.000-07:00</published><updated>2011-09-11T09:10:35.845-07:00</updated><title type='text'>Manipulating Files</title><content type='html'>&lt;p&gt;Java has had historically frustrating API's for interacting with files.  In Java 7, these API's were cleaned up a little bit.  A blog post &lt;a href="http://java.dzone.com/articles/manipulating-files-java-7"&gt;demonstrates&lt;/a&gt; some examples of using these new API's.  I would say, though, that &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; demonstrates a much simpler cross-platform API:&lt;/p&gt;&lt;h2&gt;Creating and Deleting Files&lt;/h2&gt;&lt;p&gt;To create a file, simply:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to/file&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;touch-file&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To update file permissions (on unix systems), you can use the &lt;a href="http://docs.factorcode.org/content/article-unix-file-permissions.html"&gt;io.files.info.unix&lt;/a&gt; vocabulary:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to/file&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;OCT: 666 &lt;/span&gt;set-file-permissions&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;Note: it would be nice to support parsing "rw-rw-rw-" and "g+x" and similar permission strings, and probably not very difficult.&lt;/i&gt;&lt;/blockquote&gt;&lt;p&gt;To delete a file, simply:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to/file&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;delete-file&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Copying and Moving Files&lt;/h2&gt;&lt;p&gt;To copy a file from one path to another:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/from&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;copy-file&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To copy a file, and preserve its file permissions:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/from&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;copy-file-and-info&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To copy a file into a directory:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/dir1/file&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/dir2&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;copy-file-into&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To move a file from one path to another:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/from&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/path/to&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;move-file&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To move a file into a directory:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/dir1/file&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;/dir2&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;move-file-into&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4600537455313903188?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4600537455313903188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4600537455313903188' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4600537455313903188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4600537455313903188'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/manipulating-files.html' title='Manipulating Files'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-6848231831550391720</id><published>2011-09-06T19:14:00.000-07:00</published><updated>2011-09-06T19:14:21.460-07:00</updated><title type='text'>echo</title><content type='html'>&lt;p&gt;One of the most basic unix utilities is &lt;a href="http://manpages.ubuntu.com/manpages/lucid/man1/echo.1.html"&gt;echo&lt;/a&gt;, which is used to "display a line of text". Below, I show how to implement this in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The usage for &lt;code&gt;echo&lt;/code&gt; is usually written like this:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;echo [-n] [string ...]&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The &lt;code&gt;-n&lt;/code&gt; option is to "&lt;i&gt;not print the trailing newline character&lt;/i&gt;".  We can make a word that checks the first argument for &lt;code&gt;-n&lt;/code&gt;, and returns a boolean and the remaining arguments for formatting:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;-n?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;args&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #19177C"&gt;args&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; first &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;-n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep over &lt;/span&gt;[&lt;span style="color: #008000"&gt; rest &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Since the string arguments are separated by a single blank space, we can &lt;a href="http://docs.factorcode.org/content/word-join,sequences.html"&gt;join&lt;/a&gt; and &lt;a href="http://docs.factorcode.org/content/word-write,io.html"&gt;write&lt;/a&gt; them, optionally printing a trailing newline.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;echo-args&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;args&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;-n?&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; join write &lt;/span&gt;[&lt;span style="color: #008000"&gt; nl &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can define a "main" word that allows our vocabulary to be directly &lt;a href="http://docs.factorcode.org/content/word-run%2Cvocabs.loader.html"&gt;run&lt;/a&gt; or &lt;a href="http://docs.factorcode.org/content/article-tools.deploy.usage.html"&gt;deployed&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;run-echo&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;command-line&lt;span style="color: #008000"&gt; get &lt;/span&gt;[&lt;span style="color: #008000"&gt; nl &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;echo-args&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; if-empty &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;MAIN:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;run-echo&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/unix-tools/echo/echo.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-6848231831550391720?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/6848231831550391720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=6848231831550391720' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/6848231831550391720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/6848231831550391720'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/echo.html' title='echo'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-882990994417167589</id><published>2011-09-03T11:25:00.000-07:00</published><updated>2011-09-03T11:25:07.774-07:00</updated><title type='text'>Fun with WAV</title><content type='html'>&lt;p&gt;Last year, a  "&lt;a href="http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/"&gt;Fun with wav&lt;/a&gt;" post got a lot of visibility.  The author was trying to extract the header from a audio file in the &lt;a href="http://en.wikipedia.org/wiki/WAV"&gt;WAV format&lt;/a&gt; and output the sum of the remaining data in the file.  He gives the disclaimer several times that this was a specific hack and not a generalized solution.&lt;/p&gt;&lt;p&gt;Although the original solution was in C, he &lt;a href="http://www.reddit.com/r/programming/comments/dr5pv/when_c_is_easier_cleaner_funnier_than_ruby/"&gt;received&lt;/a&gt; other possible solutions on Reddit. The "winner" by &lt;a href="http://codegolf.com/"&gt;code golf&lt;/a&gt; rules is probably &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;data &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #880000"&gt;ARGF&lt;/span&gt;&lt;span style="color: #666666"&gt;.&lt;/span&gt;read&lt;br /&gt;keys &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;%w[id totallength wavefmt format&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;          pcm channels frequency bytes_per_second&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;          bytes_by_capture bits_per_sample&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;          data bytes_in_data sum&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;]&lt;/span&gt;&lt;br /&gt;values &lt;span style="color: #666666"&gt;=&lt;/span&gt; data&lt;span style="color: #666666"&gt;.&lt;/span&gt;unpack &lt;span style="color: #BA2121"&gt;&amp;#39;Z4 i Z8 i s s i i s s Z4 i s*&amp;#39;&lt;/span&gt;&lt;br /&gt;sum &lt;span style="color: #666666"&gt;=&lt;/span&gt; values&lt;span style="color: #666666"&gt;.&lt;/span&gt;drop(&lt;span style="color: #666666"&gt;12&lt;/span&gt;)&lt;span style="color: #666666"&gt;.&lt;/span&gt;map(&lt;span style="color: #666666"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #19177C"&gt;:abs&lt;/span&gt;)&lt;span style="color: #666666"&gt;.&lt;/span&gt;inject(&lt;span style="color: #19177C"&gt;:+&lt;/span&gt;)&lt;br /&gt;keys&lt;span style="color: #666666"&gt;.&lt;/span&gt;zip(values&lt;span style="color: #666666"&gt;.&lt;/span&gt;take(&lt;span style="color: #666666"&gt;12&lt;/span&gt;) &lt;span style="color: #666666"&gt;&amp;lt;&amp;lt;&lt;/span&gt; sum) {&lt;span style="color: #666666"&gt;|&lt;/span&gt;k, v&lt;span style="color: #666666"&gt;|&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #008000"&gt;puts&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #BB6688; font-weight: bold"&gt;#{&lt;/span&gt;k&lt;span style="color: #666666"&gt;.&lt;/span&gt;ljust &lt;span style="color: #666666"&gt;17&lt;/span&gt;&lt;span style="color: #BB6688; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;: &lt;/span&gt;&lt;span style="color: #BB6688; font-weight: bold"&gt;#{&lt;/span&gt;v&lt;span style="color: #BB6688; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Build It&lt;/h2&gt;&lt;p&gt;While not attempting to "golf", I wanted to show how this might be implemented in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.  First, some imports:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;alien.c-types&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;classes.struct&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;io.encodings.binary&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io.files&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;specialized-arrays&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;FROM:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt; =&amp;gt;&lt;span style="color: #008000"&gt; map-sum &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;wavsum&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Each WAV file begins with a "master RIFF chunk" followed by format information and the sampled data.  We could read each field specifically, or we can capture this header information directly into a packed structure (I &lt;a href="https://github.com/mrjbq7/re-factor/blob/4a92988078e0f96e372e0915a3bbbd0682c97c71/classes/struct/packed/packed.factor"&gt;added support&lt;/a&gt; for these in January and recently merged it into the main Factor repository).&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;PACKED-STRUCT:&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;header&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;id&lt;span style="color: #008000"&gt; &lt;/span&gt;char[4]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;totallength&lt;span style="color: #008000"&gt; &lt;/span&gt;int&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;wavefmt&lt;span style="color: #008000"&gt; &lt;/span&gt;char[8]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;format&lt;span style="color: #008000"&gt; &lt;/span&gt;int&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;pcm&lt;span style="color: #008000"&gt; short &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;channels&lt;span style="color: #008000"&gt; short &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;frequency&lt;span style="color: #008000"&gt; &lt;/span&gt;int&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_per_second&lt;span style="color: #008000"&gt; &lt;/span&gt;int&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_by_capture&lt;span style="color: #008000"&gt; short &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bits_per_sample&lt;span style="color: #008000"&gt; short &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;data&lt;span style="color: #008000"&gt; &lt;/span&gt;char[4]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_in_data&lt;span style="color: #008000"&gt; &lt;/span&gt;int&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can easily read from an input stream directly into this structure:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;read-header&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;header&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;header&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;heap-size&lt;span style="color: #008000"&gt; read &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;memory&amp;gt;struct&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The original solution then produced a sum of the remaining file, treated as a sequence of shorts (16-bit integers).&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;SPECIALIZED-ARRAY:&lt;span style="color: #008000"&gt; short&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;sum-contents&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;sum&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    contents &lt;/span&gt;short-array-cast&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; abs &lt;/span&gt;]&lt;span style="color: #008000"&gt; map-sum &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Producing a "wavsum" from a file:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;wavsum&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;header&lt;/span&gt; &lt;span style="color: #19177C"&gt;sum&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;read-header&lt;span style="color: #008000"&gt; &lt;/span&gt;sum-contents&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Try It&lt;/h2&gt;&lt;p&gt;We can try it on a sample wav file that I included with the vocabulary and we get the same output as the Ruby and C versions:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;vocab:wavsum/truck.wav&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;wavsum&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi@&lt;/span&gt;&lt;br /&gt;S{&lt;span style="color: #008000"&gt; &lt;/span&gt;header&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;id&lt;span style="color: #008000"&gt; &lt;/span&gt;char-array{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;82 73 70 70 &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;totallength&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;66888 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;wavefmt&lt;span style="color: #008000"&gt; &lt;/span&gt;char-array{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;87 65 86 69 102 109 116 32 &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;format&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;50 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;pcm&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;channels&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;frequency&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;22050 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_per_second&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;10752 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_by_capture&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;512 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bits_per_sample&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;data&lt;span style="color: #008000"&gt; &lt;/span&gt;char-array{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;32 0 -12 3 &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;bytes_in_data&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;16777223 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;392717699&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;It might be useful to add some validation to this example (much like the original C version) for such things as endianness and the 16-bit WAV format.  Alternatively, we could improve it to be more general to handle 8-bit or 24-bit encodings, as well as other header formats (not just the "extended WAV" format).&lt;/p&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/wavsum/wavsum.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-882990994417167589?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/882990994417167589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=882990994417167589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/882990994417167589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/882990994417167589'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/09/fun-with-wav.html' title='Fun with WAV'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1293068373201239945</id><published>2011-08-28T10:22:00.000-07:00</published><updated>2011-08-28T10:30:26.868-07:00</updated><title type='text'>Thesaurus</title><content type='html'>&lt;p&gt;Steve Hanov blogged about building a &lt;a href="http://stevehanov.ca/blog/index.php?id=123"&gt;thesaurus&lt;/a&gt; using a "zero load time" file formats.  Below, we translate his implementation into &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can &lt;a href="http://www.hanovsolutions.com/thesaurus.dat"&gt;download&lt;/a&gt; the 11 MB thesaurus data file we will be using (containing over 100,000 words and their lists of related words).  It is implemented as a single file with a custom binary file format that looks like this:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;b&gt;[ header ]&lt;/b&gt;&lt;br /&gt;4 bytes: number of words&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[ index section ]&lt;/b&gt;&lt;br /&gt;&lt;i&gt;# The words are listed in alphabetical order, so you&lt;br /&gt;# can look one up using binary search.&lt;/i&gt;&lt;br /&gt;for each word:&lt;br /&gt;    4 byte pointer to word record&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[ word section ]&lt;/b&gt;&lt;br /&gt;for each word:&lt;br /&gt;   null terminated text&lt;br /&gt;   4 bytes: number of related words&lt;br /&gt;   for each link:&lt;br /&gt;       pointer to linked word record&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Build It&lt;/h2&gt;The data file consists of 4 byte "pointers" and null-terminated strings.  We can build words to read an integer or a string from a particular location in the file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;read-int&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;ptr&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    seek-absolute seek-input &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;&lt;span style="color: #008000"&gt;read &lt;/span&gt;le&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;read-string&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;ptr&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;string&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    seek-absolute seek-input &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;\0&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; read-until drop &amp;gt;string &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The number of words in the thesaurus is at the beginning of the file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;#words&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;read-int&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The position of each word is found by reading the "nth" index: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;word-position&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;ptr&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 * 4 + &lt;/span&gt;read-int&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The "nth" word is the string found at the specified word position: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;nth-word&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;word-position&lt;span style="color: #008000"&gt; &lt;/span&gt;read-string&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Now for the fun part.  Knowing that the index is sorted, we can build a word that performs a binary search for a particular word using the index. &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;find-word&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;#words&lt;span style="color: #008000"&gt; &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;high!&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;-1 &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;low!&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;candidate!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;high&lt;span style="color: #008000"&gt; &lt;/span&gt;low&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- 1 &amp;gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;high&lt;span style="color: #008000"&gt; &lt;/span&gt;low&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ 2 &lt;/span&gt;&lt;span style="color: #008000"&gt;/i &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;probe&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;probe&lt;span style="color: #008000"&gt; &lt;/span&gt;nth-word&lt;span style="color: #008000"&gt; &lt;/span&gt;candidate!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;candidate&lt;span style="color: #008000"&gt; &lt;/span&gt;word&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;+eq+&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;probe&lt;span style="color: #008000"&gt; &lt;/span&gt;high!&lt;span style="color: #008000"&gt; &lt;/span&gt;probe&lt;span style="color: #008000"&gt; &lt;/span&gt;low!&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;+lt+&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;probe&lt;span style="color: #008000"&gt; &lt;/span&gt;low!&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;probe&lt;span style="color: #008000"&gt; &lt;/span&gt;high!&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;}&lt;span style="color: #008000"&gt; case&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; while &lt;/span&gt;candidate&lt;span style="color: #008000"&gt; &lt;/span&gt;word&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;high&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Once we found the word that we are looking for, we can read its related words. &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;find-related&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;word&lt;span style="color: #008000"&gt; &lt;/span&gt;find-word&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;word-position&lt;span style="color: #008000"&gt; &lt;/span&gt;word&lt;span style="color: #008000"&gt; length &lt;/span&gt;&lt;span style="color: #666666"&gt;+ 1 + &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;ptr&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;ptr&lt;span style="color: #008000"&gt; &lt;/span&gt;read-int&lt;span style="color: #008000"&gt; &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;#related&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;ptr&lt;span style="color: #008000"&gt; &lt;/span&gt;#related&lt;span style="color: #008000"&gt; &lt;/span&gt;[1,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;v*n&lt;span style="color: #008000"&gt; &lt;/span&gt;n+v&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;read-int&lt;span style="color: #008000"&gt; &lt;/span&gt;read-string&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;if*&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Putting this all together, we can construct a  &lt;a href="http://docs.factorcode.org/content/word-__lt__file-reader__gt__%2Cio.files.html"&gt;file reader&lt;/a&gt; from the thesaurus file, a convenience word to run a quotation with the thesaurus as its input stream, and our "related words" function. &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;thesaurus-reader&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;reader&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;vocab:thesaurus/thesaurus.dat&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;binary&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;file-reader&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;with-thesaurus&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;quot&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;thesaurus-reader&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip with-input-stream &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;; inline&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;related-words&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;word&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;find-related&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-thesaurus&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Try It&lt;/h2&gt;If it is all working properly, you should be able to lookup the words that are related to any word that is in our thesaurus file. &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scratchpad&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;food&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;related-words&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;aliment&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;bread&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;chow&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;comestibles&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;commons&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;eatables&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;eats&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;edibles&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;feed&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;foodstuff&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;foodstuffs&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;grub&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;meat&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;nourishment&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;nurture&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;nutriment&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;pabulum&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;pap&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;provender&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;provisions&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;rations&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;scoff&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;subsistence&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;sustenance&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;tuck&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;viands&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;victuals&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;As for performance, it takes just over one millisecond on my laptop to lookup a single word.  Not too shabby!  The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/thesaurus/thesaurus.factor"&gt;Github&lt;/a&gt;.   &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1293068373201239945?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1293068373201239945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1293068373201239945' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1293068373201239945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1293068373201239945'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/thesaurus.html' title='Thesaurus'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-5005028177114014942</id><published>2011-08-24T12:38:00.000-07:00</published><updated>2011-08-24T12:38:09.705-07:00</updated><title type='text'>Successor</title><content type='html'>&lt;p&gt;A few days ago, I wrote about &lt;a href="http://re-factor.blogspot.com/2011/08/human-numbers.html"&gt;translating the humanize function&lt;/a&gt; from the &lt;a href="http://devongovett.github.com/slang/"&gt;slang.js&lt;/a&gt; "string utility" library into &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;.  While looking through the other functions defined in that library, I came across the &lt;a href="http://devongovett.github.com/slang/#section-30"&gt;successor&lt;/a&gt; function.&lt;/p&gt;&lt;p&gt;The "successor" of a string is defined to be a kind of "alphanum increment".  It's easiest to show a few examples of how it works:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;)         &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;)         &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;abcd&amp;quot;&lt;/span&gt;)      &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;abce&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;THX1138&amp;quot;&lt;/span&gt;)   &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;THX1139&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;&amp;lt;&amp;lt;koala&amp;gt;&amp;gt;&amp;quot;&lt;/span&gt;) &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;&amp;lt;&amp;lt;koalb&amp;gt;&amp;gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;1999zzz&amp;quot;&lt;/span&gt;)   &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;2000aaa&amp;quot;&lt;/span&gt;&lt;br /&gt;successor(&lt;span style="color: #BA2121"&gt;&amp;quot;ZZZ9999&amp;quot;&lt;/span&gt;)   &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;AAAA0000&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We are going to implement this in Factor, using the &lt;a href="http://devongovett.github.com/slang/#section-30"&gt;slang.js documentation&lt;/a&gt; as a guide:&lt;/p&gt;&lt;blockquote&gt;&lt;i&gt; &lt;p&gt;"Returns the successor to str. The successor is calculated by incrementing characters starting from the rightmost alphanumeric (or the rightmost character if there are no alphanumerics) in the string. Incrementing a digit always results in another digit, and incrementing a letter results in another letter of the same case.&lt;/p&gt;&lt;p&gt;If the increment generates a carry, the character to the left of it is incremented. This process repeats until there is no carry, adding an additional character if necessary."&lt;/p&gt;&lt;/i&gt;&lt;/blockquote&gt;To start, we should handle the "carry" logic.  There are two kinds of carries: digits and letters.  Both involve checking if a character has exceeded a range (resetting it to the beginning of the range if it has).  We can build a word that does this, returning the new character value as well as a boolean flag indicating if a carry occurred:&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;carry&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt&lt;/span&gt; &lt;span style="color: #19177C"&gt;last&lt;/span&gt; &lt;span style="color: #19177C"&gt;first&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;&amp;gt; &lt;/span&gt;&lt;span style="color: #008000"&gt;dup &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;?&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Using this to carry digits is pretty easy (using the &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt; range):&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-digit&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: 9 CHAR: 0 &lt;/span&gt;carry&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;To carry letters, we need to make sure that the carry preserves the original case (uppercase or lowercase) of the letter:&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-letter&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;ch&amp;gt;lower&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: z CHAR: a &lt;/span&gt;carry&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;LETTER?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;ch&amp;gt;upper&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;And, finally, to generalize this to all characters, we check if it is a digit or a letter and dispatch to the proper function, or pass the character through if it is neither:&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-char&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #19177C"&gt;ch&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;digit?&lt;span style="color: #008000"&gt;  &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;next-digit&lt;span style="color: #008000"&gt;  &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;Letter?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;next-letter&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;t &lt;/span&gt;&lt;span style="color: #008000"&gt;swap &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; cond &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;This leaves the core of the algorithm, which starts at the end of the string, incrementing each character (continuing if the carry flag is true), and then handling the case where we need to carry the first character:&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(successor)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup length &lt;/span&gt;&lt;span style="color: #880000"&gt;t &lt;/span&gt;[&lt;span style="color: #008000"&gt; over &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &amp;gt; &lt;/span&gt;&lt;span style="color: #008000"&gt;dupd and &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        drop &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;&lt;span style="color: #008000"&gt;dup pick &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;next-char&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; change-nth&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; while nip &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup first prefix &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;successor&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;empty?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;(successor)&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/successor/successor.factor"&gt;Github&lt;/a&gt;, and compares favorably at 30 lines of code versus the original 50.  The &lt;code&gt;(successor)&lt;/code&gt; function uses a fair amount of stack shuffling, can you improve it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-5005028177114014942?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/5005028177114014942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=5005028177114014942' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5005028177114014942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5005028177114014942'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/successor.html' title='Successor'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-3323031387067942682</id><published>2011-08-20T21:40:00.000-07:00</published><updated>2011-08-20T23:06:51.051-07:00</updated><title type='text'>Unique</title><content type='html'>A few days ago, I noticed this example from the &lt;a href="http://racket-lang.org/"&gt;Racket&lt;/a&gt; website, for reporting "each unique line from &lt;code&gt;stdin&lt;/code&gt;": &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #408080; font-style: italic"&gt;;; Report each unique line from stdin&lt;/span&gt;&lt;br /&gt;(&lt;span style="color: #008000; font-weight: bold"&gt;let&lt;/span&gt; (&lt;span style="color: #19177C"&gt;[saw&lt;/span&gt; (&lt;span style="color: #19177C"&gt;make-hash&lt;/span&gt;)&lt;span style="color: #19177C"&gt;]&lt;/span&gt;)&lt;br /&gt;  (&lt;span style="color: #19177C"&gt;for&lt;/span&gt; (&lt;span style="color: #19177C"&gt;[line&lt;/span&gt; (&lt;span style="color: #19177C"&gt;in-lines&lt;/span&gt;)&lt;span style="color: #19177C"&gt;]&lt;/span&gt;)&lt;br /&gt;    (&lt;span style="color: #008000"&gt;unless&lt;/span&gt; (&lt;span style="color: #19177C"&gt;hash-ref&lt;/span&gt; &lt;span style="color: #19177C"&gt;saw&lt;/span&gt; &lt;span style="color: #19177C"&gt;line&lt;/span&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;#f&lt;/span&gt;)&lt;br /&gt;      (&lt;span style="color: #19177C"&gt;displayln&lt;/span&gt; &lt;span style="color: #19177C"&gt;line&lt;/span&gt;))&lt;br /&gt;    (&lt;span style="color: #19177C"&gt;hash-set!&lt;/span&gt; &lt;span style="color: #19177C"&gt;saw&lt;/span&gt; &lt;span style="color: #19177C"&gt;line&lt;/span&gt; &lt;span style="color: #880000"&gt;#t&lt;/span&gt;)))&lt;/pre&gt;&lt;/blockquote&gt;We can implement the same functionality in &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt;, reading each unique line from an input stream: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;unique-lines&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    lines &lt;/span&gt;members&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; print &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The &lt;a href="http://docs.factorcode.org/content/word-lines,io.html"&gt;lines&lt;/a&gt; word acts on the "current input stream", so we can use a &lt;a href="http://docs.factorcode.org/content/word-with-file-reader,io.files.html"&gt;file reader&lt;/a&gt; as an input stream to print out all unique lines in a file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;unique-file&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;utf8&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;unique-lines&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-file-reader&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;If we wanted to make this print and flush each unique line of input as it is read, we could have used the &lt;a href="http://docs.factorcode.org/content/word-each-line,io.html"&gt;each-line&lt;/a&gt; word to implement it in a line-by-line fashion: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;unique-lines&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;HS{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; clone &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        dup pick &lt;/span&gt;in?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; over &lt;/span&gt;adjoin&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; print flush &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; each-line drop &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-3323031387067942682?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/3323031387067942682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=3323031387067942682' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/3323031387067942682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/3323031387067942682'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/unique.html' title='Unique'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-5627709560747217628</id><published>2011-08-14T19:21:00.000-07:00</published><updated>2011-08-14T19:21:33.655-07:00</updated><title type='text'>Human Numbers</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I noticed a project on Github called &lt;a href="http://devongovett.github.com/slang/"&gt;slang.js&lt;/a&gt;.  It includes a number of "string utility" functions that might be useful to Javascript developers.  One that struck me as interesting was the &lt;a href="http://devongovett.github.com/slang/#section-25"&gt;humanize&lt;/a&gt; function for turning numbers into "humanized" strings such as "1st, 2nd, 3rd or 4th".&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Note: this function is sometimes called "ordinalize" - for example, in the &lt;a href="https://docs.djangoproject.com/en/dev/ref/contrib/humanize/"&gt;django.contrib.humanize&lt;/a&gt; module or the &lt;a href="https://bitbucket.org/ixmatus/inflector/overview"&gt;inflector&lt;/a&gt; python project.&lt;/i&gt;&lt;/blockquote&gt;We are going to translate this original version into &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;function&lt;/span&gt; humanize(number) {&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt;(number &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;100&lt;/span&gt; &amp;gt;&lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;11&lt;/span&gt; &lt;span style="color: #666666;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; number &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;100&lt;/span&gt; &lt;span style="color: #666666;"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;13&lt;/span&gt;)&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;+&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"th"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;switch&lt;/span&gt;(number &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;10&lt;/span&gt;) {&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;case&lt;/span&gt; &lt;span style="color: #666666;"&gt;1:&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;+&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"st"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;case&lt;/span&gt; &lt;span style="color: #666666;"&gt;2:&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;+&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"nd"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;case&lt;/span&gt; &lt;span style="color: #666666;"&gt;3:&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;+&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"rd"&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;+&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"th"&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;If we keep the same structure (although, without the advantage that early returns can provide), it looks like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;humanize&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;100 &lt;/span&gt;&lt;span style="color: green;"&gt;mod &lt;/span&gt;&lt;span style="color: #666666;"&gt;11 13 &lt;/span&gt;between?&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;10 &lt;/span&gt;&lt;span style="color: green;"&gt;mod &lt;/span&gt;{&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"st"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"nd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"rd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;}&lt;span style="color: green;"&gt; case&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; if &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;number&amp;gt;string&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; append &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;bi*&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;And, then build some tests to make sure it works.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"1st"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"2nd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"3rd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"4th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;4 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"11th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;11 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"12th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;12 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"13th"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;13 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"21st"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;21 &lt;/span&gt;humanize&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-5627709560747217628?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/5627709560747217628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=5627709560747217628' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5627709560747217628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5627709560747217628'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/human-numbers.html' title='Human Numbers'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-5743537390043391071</id><published>2011-08-10T16:15:00.000-07:00</published><updated>2011-08-10T16:15:48.727-07:00</updated><title type='text'>Printf</title><content type='html'>The venerable &lt;a href="http://linux.die.net/man/3/printf"&gt;printf&lt;/a&gt; function is available in most languages.  Used for "formatted printing", it allows you to convert most basic data types to a string.  Several years ago, I contributed an implementation for &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt; that currently lives in the &lt;a href="http://docs.factorcode.org/content/article-formatting.html"&gt;formatting&lt;/a&gt; vocabulary.  Using it looks a bit like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;12 &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"There are %d monkeys"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;printf&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;There are 12 monkeys&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Implementation&lt;/h2&gt;One of the neat things about this version, is that the format string is parsed and code to format the arguments is generated at compile-time.  Below, I've created a simplified version of &lt;a href="http://docs.factorcode.org/content/word-printf,formatting.html"&gt;printf&lt;/a&gt; to show how this works.  &lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;USING:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;io&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;io.streams.string&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;kernel&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;macros&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;make&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math.parser&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;peg.ebnf&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;present&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;quotations&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;sequences&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;strings&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;We use the &lt;a href="http://docs.factorcode.org/content/article-peg.ebnf.html"&gt;peg.ebnf&lt;/a&gt; vocabulary to parse the format string into a sequence of quotations (either strings or format instructions).  Each quotation uses the &lt;a href="http://docs.factorcode.org/content/article-namespaces-make.html"&gt;make&lt;/a&gt; vocabulary to add these strings to a sequence (to be written out):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;EBNF:&lt;span style="color: #008000"&gt; &lt;/span&gt;parse-printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;fmt-%&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;fmt-c&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; 1string &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;fmt-s&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;present&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;fmt-d&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &amp;gt;integer &lt;/span&gt;number&amp;gt;string&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;fmt-f&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;f&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &amp;gt;float &lt;/span&gt;number&amp;gt;string&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;fmt-x&lt;span style="color: #008000"&gt;      &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;gt;hex&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;unknown&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;(.)*&lt;span style="color: #008000"&gt;  &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &amp;gt;string throw &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;strings&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;fmt-c|fmt-s&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;numbers&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;fmt-d|fmt-f|fmt-x&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;formats&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%&amp;quot;&lt;/span&gt;~&lt;span style="color: #008000"&gt; &lt;/span&gt;(strings|numbers|fmt-%|unknown)&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;plain-text&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;(!(&amp;quot;%&amp;quot;).)+&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &amp;gt;string &lt;/span&gt;1quotation&lt;span style="color: #008000"&gt; &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;text&lt;span style="color: #008000"&gt;       &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;(formats|plain-text)*&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                   &lt;/span&gt;=&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;[[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; \ &lt;/span&gt;,&lt;span style="color: #008000"&gt; suffix &lt;/span&gt;]&lt;span style="color: #008000"&gt; map &lt;/span&gt;]]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;;EBNF&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can see the EBNF output by trying it in the &lt;a article-listener.html="" content="" docs.factorcode.org="" href="http://draft.blogger.com/blogger.g?blogID=8513438391157777465" http:=""&gt;listener&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"There are %d monkeys"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;parse-printf&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;V{&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"There are "&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &amp;gt;integer &lt;/span&gt;number&amp;gt;string&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;" monkeys"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The "printf" &lt;a href="http://docs.factorcode.org/content/article-macros.html"&gt;macro&lt;/a&gt; takes the parsed output, reverses it (so the elements to be formatted can be passed on the stack in their natural order), applies each format quotation to the elements on the stack, and then writes them back in the original order.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;MACRO:&lt;/span&gt; &lt;span style="color: blue;"&gt;printf&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;format-string&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;parse-printf&lt;span style="color: green;"&gt; reverse &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; concat-as &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;make&lt;span style="color: green;"&gt; reverse &lt;/span&gt;[&lt;span style="color: green;"&gt; write &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; curry &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can use &lt;a href="http://docs.factorcode.org/content/word-expand-macros,macros.expander.html"&gt;expand-macros&lt;/a&gt; to see the code the macro generates:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"There are %d monkeys"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;printf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;expand-macros&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;" monkeys"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &amp;gt;integer &lt;/span&gt;number&amp;gt;string&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"There are "&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;,&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;make&lt;span style="color: green;"&gt; reverse &lt;/span&gt;[&lt;span style="color: green;"&gt; write &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;br /&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Implementing &lt;a href="http://docs.factorcode.org/content/word-sprintf,formatting.html"&gt;sprintf&lt;/a&gt; is easy using &lt;a href="http://docs.factorcode.org/content/article-io.streams.string.html"&gt;string streams&lt;/a&gt; to capture the output into a string object:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;sprintf&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;format-string&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;result&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;printf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;with-string-writer&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Tests&lt;/h2&gt;We can write some unit tests to show that it works:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;""&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;""&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"asdf"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"asdf"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"10"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;10 &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%d"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"-10"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;-10 &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%d"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"ff"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;HEX: ff &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%x"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Hello, World!"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Hello, World!"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%s"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"printf test"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"printf test"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"char a = 'a'"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;CHAR: a "char %c = 'a'"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"0 message(s)"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;0 &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"message"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%d %s(s)"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"10%"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;10 &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"%d%%"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"[monkey]"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"monkey"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"[%s]"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;sprintf&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This implementation doesn't support various format parameters such as width, alignment, padding characters, uppercase/lowercase, decimal digits, or scientific notation.  Nor does it support formatting sequences and assocs, like the &lt;a href="http://docs.factorcode.org/content/word-printf,formatting.html"&gt;official version&lt;/a&gt;.  However, adding those features is straightforward once you understand the basic mechanics.&lt;/p&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/printf-example/printf-example.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-5743537390043391071?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/5743537390043391071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=5743537390043391071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5743537390043391071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5743537390043391071'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/printf.html' title='Printf'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1935907149981967011</id><published>2011-08-06T08:36:00.000-07:00</published><updated>2011-08-06T17:28:51.849-07:00</updated><title type='text'>FizzBuzz</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;The "new classic" programming test seems to be the FizzBuzz problem.  I think it was first proposed in a &lt;a href="http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html"&gt;blog post&lt;/a&gt; from 2007.&lt;br /&gt;&lt;br /&gt;Now that it has garnered so much awareness (even videos on YouTube!), it's probably not a good interview question anymore.  However, now that implementations have been &lt;a href="http://rosettacode.org/wiki/FizzBuzz"&gt;written in many languages&lt;/a&gt;, it can be used to learn and compare the syntax of new languages.&lt;br /&gt;&lt;h2&gt;Implementation&lt;/h2&gt;We can see how it works in &lt;a href="http://python.org/"&gt;Python&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: green;"&gt;range&lt;/span&gt;(&lt;span style="color: #666666;"&gt;1&lt;/span&gt;,&lt;span style="color: #666666;"&gt;101&lt;/span&gt;):&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #aa22ff; font-weight: bold;"&gt;not&lt;/span&gt; i &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;15&lt;/span&gt;:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"FizzBuzz"&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;elif&lt;/span&gt; &lt;span style="color: #aa22ff; font-weight: bold;"&gt;not&lt;/span&gt; i &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;3&lt;/span&gt;:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;elif&lt;/span&gt; &lt;span style="color: #aa22ff; font-weight: bold;"&gt;not&lt;/span&gt; i &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: #666666;"&gt;5&lt;/span&gt;:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;else&lt;/span&gt;:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; i&lt;/pre&gt;&lt;/blockquote&gt;A similar version in &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #19177c;"&gt;=&amp;gt;&lt;/span&gt;(&lt;span style="color: #19177c;"&gt;defn&lt;/span&gt; &lt;span style="color: #19177c;"&gt;multiple?&lt;/span&gt; &lt;span style="color: #19177c;"&gt;[n&lt;/span&gt; &lt;span style="color: #19177c;"&gt;div]&lt;/span&gt;&lt;br /&gt;    (&lt;span style="color: green;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;0&lt;/span&gt; (&lt;span style="color: green;"&gt;mod&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: #19177c;"&gt;div&lt;/span&gt;)))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #19177c;"&gt;=&amp;gt;&lt;/span&gt;(&lt;span style="color: #19177c;"&gt;doseq&lt;/span&gt; &lt;span style="color: #19177c;"&gt;[i&lt;/span&gt; (&lt;span style="color: #19177c;"&gt;range&lt;/span&gt; &lt;span style="color: #666666;"&gt;1&lt;/span&gt; &lt;span style="color: #666666;"&gt;101&lt;/span&gt;)&lt;span style="color: #19177c;"&gt;]&lt;/span&gt;&lt;br /&gt;     (&lt;span style="color: green;"&gt;cond&lt;/span&gt; (&lt;span style="color: green;"&gt;and&lt;/span&gt; (&lt;span style="color: #19177c;"&gt;multiple?&lt;/span&gt; &lt;span style="color: #19177c;"&gt;i&lt;/span&gt; &lt;span style="color: #666666;"&gt;3&lt;/span&gt;)(&lt;span style="color: #19177c;"&gt;multiple?&lt;/span&gt; &lt;span style="color: #19177c;"&gt;i&lt;/span&gt; &lt;span style="color: #666666;"&gt;5&lt;/span&gt;))&lt;br /&gt;             (&lt;span style="color: #19177c;"&gt;println&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"FizzBuzz"&lt;/span&gt;)&lt;br /&gt;           (&lt;span style="color: #19177c;"&gt;multiple?&lt;/span&gt; &lt;span style="color: #19177c;"&gt;i&lt;/span&gt; &lt;span style="color: #666666;"&gt;3&lt;/span&gt;)&lt;br /&gt;             (&lt;span style="color: #19177c;"&gt;println&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;)&lt;br /&gt;           (&lt;span style="color: #19177c;"&gt;multiple?&lt;/span&gt; &lt;span style="color: #19177c;"&gt;i&lt;/span&gt; &lt;span style="color: #666666;"&gt;5&lt;/span&gt;)&lt;br /&gt;             (&lt;span style="color: #19177c;"&gt;println&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;)&lt;br /&gt;       &lt;span style="color: #19177c;"&gt;:else&lt;/span&gt; (&lt;span style="color: #19177c;"&gt;println&lt;/span&gt; &lt;span style="color: #19177c;"&gt;i&lt;/span&gt;)))&lt;/pre&gt;&lt;/blockquote&gt;And, finally, a version in &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;100 &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;{&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;15 &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"FizzBuzz"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;5 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;present&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;}&lt;span style="color: green;"&gt; cond print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Improvements&lt;/h2&gt;Let's see if we can improve the &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt; version a bit.  First, we can "factor out" the FizzBuzz logic into its own function (showing how it would look if you were to code this directly into &lt;a href="http://docs.factorcode.org/content/article-listener.html"&gt;the listener&lt;/a&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;fizzbuzz&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;{&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;15 &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"FizzBuzz"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;&lt;span style="color: #666666;"&gt;5 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                       &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;present&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;}&lt;span style="color: green;"&gt; cond print &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;scratchpad&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;100 &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;fizzbuzz&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;To avoid all the &lt;code&gt;dup&lt;/code&gt; and &lt;code&gt;drop&lt;/code&gt; words, we could build a variation of &lt;a href="http://docs.factorcode.org/content/word-cond,combinators.html"&gt;cond&lt;/a&gt; that acts a bit like a &lt;a href="http://docs.factorcode.org/content/word-case,combinators.html"&gt;case&lt;/a&gt;.  The "cond-case" word was &lt;a href="http://www.mail-archive.com/factor-talk@lists.sourceforge.net/msg05285.html"&gt;suggested&lt;/a&gt; on the &lt;a href="https://lists.sourceforge.net/lists/listinfo/factor-talk%20Factor%20mailing%20list"&gt;Factor mailing list&lt;/a&gt;, and this is one variant of it:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;MACRO:&lt;/span&gt; &lt;span style="color: blue;"&gt;cond-case&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;assoc&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        dup &lt;/span&gt;callable?&lt;span style="color: green;"&gt; not &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;[&lt;span style="color: green;"&gt; first &lt;/span&gt;[&lt;span style="color: green;"&gt; dup &lt;/span&gt;]&lt;span style="color: green;"&gt; prepose &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;[&lt;span style="color: green;"&gt; second &lt;/span&gt;[&lt;span style="color: green;"&gt; drop &lt;/span&gt;]&lt;span style="color: green;"&gt; prepose &lt;/span&gt;]&lt;span style="color: green;"&gt; bi 2array&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;]&lt;span style="color: green;"&gt; when&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; map &lt;/span&gt;[&lt;span style="color: green;"&gt; cond &lt;/span&gt;]&lt;span style="color: green;"&gt; curry &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Using &lt;code&gt;cond-case&lt;/code&gt;, we can improve the original version:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;fizzbuzz&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;{&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;15 &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"FizzBuzz"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;5 &lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;&lt;span style="color: green;"&gt;     &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;present&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;cond-case&lt;span style="color: green;"&gt; print &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;If we realize that the check for divisible by 15 is the same as checking for divisible by 3 &lt;i&gt;and&lt;/i&gt; divisible by 5, we can implement it slightly differently, without a &lt;code&gt;cond&lt;/code&gt; or &lt;code&gt;case&lt;/code&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;fizz&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str/f&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Fizz"&lt;/span&gt;&lt;span style="color: green;"&gt; and &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;buzz&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str/f&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #666666;"&gt;5 &lt;/span&gt;divisor?&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Buzz"&lt;/span&gt;&lt;span style="color: green;"&gt; and &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;fizzbuzz&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    dup &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;fizz&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;buzz&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; bi &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;""&lt;/span&gt;&lt;span style="color: green;"&gt; append-as&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;present&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; nip &lt;/span&gt;]&lt;span style="color: green;"&gt; if-empty print &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Is it better?  Can you think of any way to make it simpler?  Perhaps by using or inventing some higher-level concepts like we did with &lt;code&gt;cond-case&lt;/code&gt;?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1935907149981967011?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1935907149981967011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1935907149981967011' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1935907149981967011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1935907149981967011'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/08/fizzbuzz.html' title='FizzBuzz'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-5268777042990462284</id><published>2011-07-29T14:56:00.000-07:00</published><updated>2011-07-29T14:56:03.198-07:00</updated><title type='text'>Robohash</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;A few days ago, I read about &lt;a href="http://robohash.org/"&gt;Robohash&lt;/a&gt;, a website for creating unique images (of robots) from any text.  The author was thinking of using it for icons on a forum, but there are probably other use-cases for this.  For example, as a variation of the &lt;a href="http://mattt.github.com/Chroma-Hash/"&gt;color password hash&lt;/a&gt; to help users avoid typos in their passwords or, perhaps, as a visual representation of a user-submitted "secret code".&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;USING:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;images.http&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;kernel&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;sequences&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;urls&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;urls.encoding&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;First, we need to create URLs of the form &lt;code&gt;http://robohash.org/YOUR_TEXT&lt;/code&gt;, as instructed:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;robohash-url&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;url&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;url-encode&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"http://robohash.org/"&lt;/span&gt;&lt;span style="color: green;"&gt; prepend &lt;/span&gt;&amp;gt;url&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Next, we would like to support the different "image sets" that Robohash supports.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;(robohash)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: #19177c;"&gt;type&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;image&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;robohash-url&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"set"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;bi*&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;load-http-image&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Using this, we can create image loaders for each set (currently three sets: "set1", "set2", and "set3"):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;robohash1&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;image&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"set1"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;(robohash)&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;robohash2&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;image&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"set2"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;(robohash)&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;robohash3&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;image&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"set3"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;(robohash)&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can try it out and see that it &lt;a href="http://robohash.org/hello%20world?set=set1"&gt;works&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;img src="https://lh4.googleusercontent.com/-z_QDvk0bKnA/ThuhEUPfxWI/AAAAAAAAAMM/WQTKC6pH3f0/robohash.png" /&gt;&lt;/blockquote&gt;Robohash also supports custom backgrounds, changing image sizes, and varying image formats (e.g., JPG or BMP).  Adding support for that is an exercise to the reader.&lt;br /&gt;&lt;br /&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/robohash/robohash.factor"&gt;Github&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-5268777042990462284?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/5268777042990462284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=5268777042990462284' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5268777042990462284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5268777042990462284'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/robohash.html' title='Robohash'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-z_QDvk0bKnA/ThuhEUPfxWI/AAAAAAAAAMM/WQTKC6pH3f0/s72-c/robohash.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-9159687884677316353</id><published>2011-07-23T13:58:00.000-07:00</published><updated>2011-07-23T15:54:39.112-07:00</updated><title type='text'>Majority Vote</title><content type='html'>A &lt;a href="http://www.cs.utexas.edu/~moore/best-ideas/mjrty/index.html"&gt;Linear Time Majority Vote Algorithm&lt;/a&gt; was invented in 1980 by &lt;a href="http://en.wikipedia.org/wiki/Bob_Boyer"&gt;Bob Boyer&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/J_Strother_Moore"&gt;J Strother Moore&lt;/a&gt; (inventors of the popular &lt;a href="http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm"&gt;Boyer-Moore string search algorithm&lt;/a&gt;).  Not seeing this available in &lt;a href="http://www.factorcode.org/"&gt;Factor&lt;/a&gt;, I thought to contribute one.&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Note: this is also called the "Moore’s Voting Algorithm".&lt;/i&gt;&lt;/blockquote&gt;The algorithm simply looks at each element of the sequence:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #ececec; border: 1px #cccccc solid; padding: 10px;"&gt;Keep a candidate element and a counter (initially unknown and zero, respectively).&lt;br /&gt;&lt;br /&gt;As we move across the sequence, look at each element:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If the counter is 0: the element is the candidate and the counter is 1.&lt;/li&gt;&lt;li&gt;If the counter is not 0: increment if the element is the candidate, decrement if not.&lt;/li&gt;&lt;/ul&gt;When we are done, the candidate is the majority element, if there is a majority.&lt;/div&gt;&lt;br /&gt;Using this specification, we can implement the algorithm:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;majority&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;elt/f&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        over &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; 2nip &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            pick &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 + &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;]&lt;span style="color: #008000"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;A few simple tests show that this is working:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #880000;"&gt;f &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;majority&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #880000;"&gt;f &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 2 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;majority&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 1 2 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;majority&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #880000;"&gt;f &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 1 2 2 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;majority&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 1 2 2 2 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;majority&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;unit-test&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;This is perhaps not quite &lt;i&gt;idiomatic&lt;/i&gt; Factor, can you improve it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-9159687884677316353?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/9159687884677316353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=9159687884677316353' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/9159687884677316353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/9159687884677316353'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/majority-vote.html' title='Majority Vote'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1577346302471569746</id><published>2011-07-19T14:05:00.000-07:00</published><updated>2011-07-19T14:05:32.644-07:00</updated><title type='text'>One-Liners</title><content type='html'>Inspired by a &lt;a href="http://freegeek.in/blog/2011/06/10-clojure-one-liners/"&gt;blog post&lt;/a&gt; about "one-liners" in Clojure, I thought I'd demonstrate a few small pieces of Factor code doing some similar things:&lt;br /&gt;&lt;br /&gt;Using the &lt;a href="http://docs.factorcode.org/content/word-map,sequences.html"&gt;map&lt;/a&gt; word, we can apply a "doubling" &lt;a href="http://docs.factorcode.org/content/article-quotations.html"&gt;quotation&lt;/a&gt; to each element.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;4 8 15 16 23 42 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 * &lt;/span&gt;]&lt;span style="color: green;"&gt; map &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;8 16 30 32 46 84 &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;We can easily calculate the &lt;a href="http://docs.factorcode.org/content/word-sum,sequences.html"&gt;sum&lt;/a&gt; of a sequence (here the numbers 1 through 1000):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1000 &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; sum &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;500500&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;We check if &lt;a href="http://docs.factorcode.org/content/word-any__que__,sequences.html"&gt;any&lt;/a&gt; of a list of words are &lt;a href="http://docs.factorcode.org/content/word-subseq__que__,sequences.html"&gt;within&lt;/a&gt; a string:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"factor"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"concatenative"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"stack-based"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"factor is awesome"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;subseq?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;any?&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can easily read the &lt;a href="http://docs.factorcode.org/content/word-file-contents,io.files.html"&gt;file-contents&lt;/a&gt;, or &lt;a href="http://docs.factorcode.org/content/word-file-lines,io.files.html"&gt;file-lines&lt;/a&gt;, with a specified encoding (e.g., UTF-8):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"/path/to/file.txt"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;utf8&lt;span style="color: green;"&gt; &lt;/span&gt;file-contents&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Sing the four verses to the "Happy Birthday" song:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;4 &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Happy Birthday "&lt;/span&gt;&lt;span style="color: green;"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                   &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 = &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"dear NAME"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"to You"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;?&lt;span style="color: green;"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;br /&gt;Happy&lt;span style="color: green;"&gt; &lt;/span&gt;Birthday&lt;span style="color: green;"&gt; &lt;/span&gt;to&lt;span style="color: green;"&gt; &lt;/span&gt;You&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;Happy&lt;span style="color: green;"&gt; &lt;/span&gt;Birthday&lt;span style="color: green;"&gt; &lt;/span&gt;to&lt;span style="color: green;"&gt; &lt;/span&gt;You&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;Happy&lt;span style="color: green;"&gt; &lt;/span&gt;Birthday&lt;span style="color: green;"&gt; &lt;/span&gt;dear&lt;span style="color: green;"&gt; &lt;/span&gt;NAME&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;Happy&lt;span style="color: green;"&gt; &lt;/span&gt;Birthday&lt;span style="color: green;"&gt; &lt;/span&gt;to&lt;span style="color: green;"&gt; &lt;/span&gt;You&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Use &lt;a href="http://docs.factorcode.org/content/word-filter,sequences.html"&gt;filter&lt;/a&gt; (or even &lt;a href="http://docs.factorcode.org/content/word-partition,sequences.html"&gt;partition&lt;/a&gt;) with some selection criteria:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;49 58 76 82 88 90 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;60 &lt;/span&gt;&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; filter &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;76 82 88 90 &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Use the &lt;a href="http://docs.factorcode.org/content/vocab-http.client.html"&gt;http.client&lt;/a&gt; vocabulary to access a web service, and then the &lt;a href="http://docs.factorcode.org/content/vocab-xml.html"&gt;xml&lt;/a&gt; vocabulary to parse the result from a string.  You could use the &lt;a href="http://docs.factorcode.org/content/vocab-json.reader.html"&gt;json.reader&lt;/a&gt; vocabulary to parse JSON responses.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"http://search.twitter.com/search.atom?q=factor"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;http-get&lt;span style="color: green;"&gt; nip &lt;/span&gt;string&amp;gt;xml&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Check the HTTP headers to find the version of a server used by a web server:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"http://apple.com"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;http-get&lt;span style="color: green;"&gt; drop&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;header&amp;gt;&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"server"&lt;/span&gt;&lt;span style="color: green;"&gt; swap at &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121;"&gt;"Apache/2.2.3 (Oracle)"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Use &lt;a href="http://docs.factorcode.org/content/word-infimum,sequences.html"&gt;infimum&lt;/a&gt; and &lt;a href="http://docs.factorcode.org/content/word-supremum,sequences.html"&gt;supremum&lt;/a&gt; to find the minimum and maximum, respectively, of a list (alternatively, you could use my &lt;a href="http://re-factor.blogspot.com/2011/02/maximumminimum.html"&gt;maximum/minimum functions&lt;/a&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;14 36 -7 46 98 &lt;/span&gt;}&lt;span style="color: green;"&gt; infimum &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;-7&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;14 36 -7 46 98 &lt;/span&gt;}&lt;span style="color: green;"&gt; supremum &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;98&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Parse a string into groups of two characters, then interpret those as hex values of characters, mapping the output as a string:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"474e552773204e6f7420556e6978"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 &lt;/span&gt;&amp;lt;groups&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;16 &lt;/span&gt;base&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;""&lt;/span&gt;&lt;span style="color: green;"&gt; map-as &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121;"&gt;"GNU's Not Unix"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Use &lt;a href="http://docs.factorcode.org/content/vocab-concurrency.combinators.html"&gt;concurrency.combinators&lt;/a&gt; to perform certain tasks in parallel with &lt;a href="http://docs.factorcode.org/content/article-concurrency.futures.html"&gt;futures&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 0 -1 &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;2 + &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;parallel-map&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 2 1 &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1577346302471569746?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1577346302471569746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1577346302471569746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1577346302471569746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1577346302471569746'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/one-liners.html' title='One-Liners'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4763856041461172602</id><published>2011-07-15T09:56:00.000-07:00</published><updated>2011-07-15T10:03:17.258-07:00</updated><title type='text'>Detecting Plagiarism</title><content type='html'>About a month ago, Tom Moertel wrote a &lt;a href="http://blog.moertel.com/articles/2011/06/16/writing-a-simple-plagiarism-detector-in-haskell"&gt;simple plagiarism detector&lt;/a&gt; in Haskell.  I wanted to replicate his functionality using &lt;a href="http://www.factorcode.org/"&gt;Factor&lt;/a&gt;, to contrast the two solutions.&lt;br /&gt;&lt;br /&gt;The strategy in this plagiarism detector is fairly simple: calculate "long enough" &lt;a href="http://en.wikipedia.org/wiki/N-gram"&gt;n-grams&lt;/a&gt; that should be fairly unique and see if they are present in a particular piece of "suspect text", converting the common pieces into UPPERCASE so that we can visually see what might be plagiarized.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;USING:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;command-line&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;grouping&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;io&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;io.encodings.utf8&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;io.files&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;kernel&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math.parser&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math.ranges&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;namespaces&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;regexp&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;sequences&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue; font-weight: bold;"&gt;sets&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;splitting&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;unicode.case&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;unicode.categories&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;unicode.data&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;IN:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;plagiarism&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;We can split text (using the&amp;nbsp;&lt;a href="http://docs.factorcode.org/content/vocab-grouping.html"&gt;grouping&lt;/a&gt;&amp;nbsp;vocabulary)&amp;nbsp;into consecutive groups of "n" words:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;n-grams&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;blank?&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;split-when&lt;span style="color: green;"&gt; harvest &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&amp;lt;clumps&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;bi*&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Given a piece of text suspected to be plagiarized and some sources to compare against, we can compute the common n-grams between the two pieces of text:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;common-n-grams&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;suspect&lt;/span&gt; &lt;span style="color: #19177c;"&gt;sources&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n-grams&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;n-grams&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; curry dup &lt;/span&gt;[&lt;span style="color: green;"&gt; map concat &lt;/span&gt;]&lt;span style="color: green;"&gt; curry &lt;/span&gt;bi*&lt;span style="color: green;"&gt; &lt;/span&gt;intersect&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;For each common n-gram found, we use a &lt;a href="http://en.wikipedia.org/wiki/Regular_expression"&gt;regular expression&lt;/a&gt; to find the matching part of the suspect text.  The regular expression we will use, looks something like &lt;i&gt;a space or start of line followed by our n-gram and ending with a space or end of line&lt;/i&gt;, allowing varying whitespace between words, being case insensitive, and ignoring non-letters within a word:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;n-gram&amp;gt;regexp&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;regexp&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;Letter?&lt;span style="color: green;"&gt; not &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;split-when&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"[\\W\\S]"&lt;/span&gt;&lt;span style="color: green;"&gt; join &lt;/span&gt;]&lt;span style="color: green;"&gt; map&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"\\s+"&lt;/span&gt;&lt;span style="color: green;"&gt; join &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"(\\s|^)"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"(\\s|$)"&lt;/span&gt;&lt;span style="color: green;"&gt; surround&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"i"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&amp;lt;optioned-regexp&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;The &lt;a href="http://docs.factorcode.org/content/vocab-sequences.html"&gt;sequences&lt;/a&gt; vocabulary contains a &lt;a href="http://docs.factorcode.org/content/word-change-nth,sequences.html"&gt;change-nth&lt;/a&gt; word to modify a particular element in a sequence.  We can create a word to modify several elements easily:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;change-nths&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;indices&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq&lt;/span&gt; &lt;span style="color: #19177c;"&gt;quot:&lt;/span&gt;&lt;span style="color: blue;"&gt; (&lt;/span&gt; &lt;span style="color: #19177c;"&gt;elt&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;elt'&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; change-nth &lt;/span&gt;]&lt;span style="color: green;"&gt; 2curry each &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;; inline&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Using &lt;code&gt;change-nths&lt;/code&gt; and the "n-gram regexp", we can &lt;a href="http://docs.factorcode.org/content/word-ch__gt__upper,unicode.data.html"&gt;ch&amp;gt;upper&lt;/a&gt; each matching portion of text:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;upper-matches&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;str&lt;/span&gt; &lt;span style="color: #19177c;"&gt;regexp&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;[a,b)&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; dip &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;ch&amp;gt;upper&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;change-nths&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;each-match&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Using these building blocks, we can build a simple plagiarism detector:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Compute the common n-grams between suspect and source texts&lt;/li&gt;&lt;li&gt;Create a regular expression for each common n-gram&lt;/li&gt;&lt;li&gt;For each match, change the matching characters to uppercase&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;detect-plagiarism&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;suspect&lt;/span&gt; &lt;span style="color: #19177c;"&gt;sources&lt;/span&gt; &lt;span style="color: #19177c;"&gt;n&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;suspect'&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;[&lt;span style="color: green;"&gt; dupd &lt;/span&gt;]&lt;span style="color: green;"&gt; dip &lt;/span&gt;common-n-grams&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        dupd &lt;/span&gt;n-gram&amp;gt;regexp&lt;span style="color: green;"&gt; &lt;/span&gt;upper-matches&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; each &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;A "main method" enables this program to run from the command line:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;run-plagiarism&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;command-line&lt;span style="color: green;"&gt; get dup length &lt;/span&gt;&lt;span style="color: #666666;"&gt;3 &amp;lt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        drop &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"USAGE: plagiarism N suspect.txt source.txt..."&lt;/span&gt;&lt;span style="color: green;"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;[&lt;span style="color: green;"&gt; rest &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;utf8&lt;span style="color: green;"&gt; &lt;/span&gt;file-contents&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; map unclip swap &lt;/span&gt;]&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;[&lt;span style="color: green;"&gt; first &lt;/span&gt;string&amp;gt;number&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; bi &lt;/span&gt;detect-plagiarism&lt;span style="color: green;"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; if &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;MAIN:&lt;/span&gt; &lt;span style="color: blue;"&gt;run-plagiarism&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can see it work by trying to find common 4-grams on some simple text (in this case, I added the word "really"):&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"this is a really long piece of text"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"this is a long piece of text"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;&lt;span style="color: #666666;"&gt;4 &lt;/span&gt;detect-plagiarism&lt;span style="color: green;"&gt; print&lt;/span&gt;&lt;br /&gt;this&lt;span style="color: green;"&gt; &lt;/span&gt;is&lt;span style="color: green;"&gt; &lt;/span&gt;a&lt;span style="color: green;"&gt; &lt;/span&gt;really&lt;span style="color: green;"&gt; &lt;/span&gt;LONG&lt;span style="color: green;"&gt; &lt;/span&gt;PIECE&lt;span style="color: green;"&gt; &lt;/span&gt;OF&lt;span style="color: green;"&gt; &lt;/span&gt;TEXT&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;It's fast enough for small examples, but not that fast for complete novels, particularly when run on texts with many common n-grams.  One idea for improving the speed might be to examine the &lt;code&gt;common-n-grams&lt;/code&gt; algorithm to return sequences of "n or more".  This way, if the text contains a common 7-gram, and you are looking at common 4-grams, then it would have one entry instead of three.&lt;br /&gt;&lt;br /&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/plagiarism/plagiarism.factor"&gt;Github&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4763856041461172602?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4763856041461172602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4763856041461172602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4763856041461172602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4763856041461172602'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/detecting-plagiarism.html' title='Detecting Plagiarism'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-5005080008204125709</id><published>2011-07-12T20:57:00.000-07:00</published><updated>2011-07-12T21:09:44.478-07:00</updated><title type='text'>Concatenative Thinking</title><content type='html'>&lt;p&gt;I've written about the &lt;a href="http://re-factor.blogspot.com/2011/04/verbosity.html"&gt;conciseness&lt;/a&gt; of &lt;a href="http://www.factorcode.org/"&gt;Factor&lt;/a&gt; before.  Yesterday, I noticed a link to a functional programming tutorial called &lt;a href="http://www.ibm.com/developerworks/library/j-ft1/"&gt;"Functional Thinking"&lt;/a&gt; that was posted two months ago.&lt;/p&gt;&lt;p&gt;The tutorial develops a program for classifying numbers based on the sum of its factors into &lt;i&gt;perfect&lt;/i&gt;, &lt;i&gt;abundant&lt;/i&gt;, or &lt;i&gt;deficient&lt;/i&gt; numbers.  The program goes through three improvements, ending up at this "best" solution in Java (using the &lt;a href="http://functionaljava.org/"&gt;Functional Java&lt;/a&gt; library):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;FNumberClassifier&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #b00040;"&gt;boolean&lt;/span&gt; &lt;span style="color: blue;"&gt;isFactor&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #b00040;"&gt;int&lt;/span&gt; number&lt;span style="color: #666666;"&gt;,&lt;/span&gt; &lt;span style="color: #b00040;"&gt;int&lt;/span&gt; potential_factor&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;%&lt;/span&gt; potential_factor &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #666666;"&gt;0;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; List&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; factors&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;final&lt;/span&gt; &lt;span style="color: #b00040;"&gt;int&lt;/span&gt; number&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;range&lt;/span&gt;&lt;span style="color: #666666;"&gt;(1,&lt;/span&gt; number&lt;span style="color: #666666;"&gt;+1).&lt;/span&gt;&lt;span style="color: #7d9029;"&gt;filter&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;new&lt;/span&gt; F&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color: #666666;"&gt;,&lt;/span&gt; Boolean&lt;span style="color: #666666;"&gt;&amp;gt;()&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; Boolean &lt;span style="color: blue;"&gt;f&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;final&lt;/span&gt; Integer i&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; number &lt;span style="color: #666666;"&gt;%&lt;/span&gt; i &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #666666;"&gt;0;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666;"&gt;});&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #b00040;"&gt;int&lt;/span&gt; &lt;span style="color: blue;"&gt;sum&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;List&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; factors&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; factors&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #7d9029;"&gt;foldLeft&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;fj&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #7d9029;"&gt;function&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #7d9029;"&gt;Integers&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #7d9029;"&gt;add&lt;/span&gt;&lt;span style="color: #666666;"&gt;,&lt;/span&gt; &lt;span style="color: #666666;"&gt;0);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #b00040;"&gt;boolean&lt;/span&gt; &lt;span style="color: blue;"&gt;isPerfect&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #b00040;"&gt;int&lt;/span&gt; number&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;sum&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;factors&lt;span style="color: #666666;"&gt;(&lt;/span&gt;number&lt;span style="color: #666666;"&gt;))&lt;/span&gt; &lt;span style="color: #666666;"&gt;-&lt;/span&gt; number &lt;span style="color: #666666;"&gt;==&lt;/span&gt; number&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #b00040;"&gt;boolean&lt;/span&gt; &lt;span style="color: blue;"&gt;isAbundant&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #b00040;"&gt;int&lt;/span&gt; number&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;sum&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;factors&lt;span style="color: #666666;"&gt;(&lt;/span&gt;number&lt;span style="color: #666666;"&gt;))&lt;/span&gt; &lt;span style="color: #666666;"&gt;-&lt;/span&gt; number &lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; number&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #b00040;"&gt;boolean&lt;/span&gt; &lt;span style="color: blue;"&gt;isDeficient&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #b00040;"&gt;int&lt;/span&gt; number&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;sum&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;factors&lt;span style="color: #666666;"&gt;(&lt;/span&gt;number&lt;span style="color: #666666;"&gt;))&lt;/span&gt; &lt;span style="color: #666666;"&gt;-&lt;/span&gt; number &lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt; number&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;While the proffered solution is much (much) better than the original "imperative" solution, I thought I would show what it could look like in Factor:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;factor?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;m&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    mod &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;factors&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;[1,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;factor?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; with filter &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;perfect?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;factors&lt;span style="color: #008000"&gt; sum &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; tri &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;abundant?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;factors&lt;span style="color: #008000"&gt; sum &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;&amp;gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; tri &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;deficient?&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;?&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;factors&lt;span style="color: #008000"&gt; sum &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;- &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;&amp;lt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; tri &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;What do you think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-5005080008204125709?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/5005080008204125709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=5005080008204125709' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5005080008204125709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/5005080008204125709'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/concatenative-thinking.html' title='Concatenative Thinking'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1994345702466239697</id><published>2011-07-10T11:18:00.000-07:00</published><updated>2011-07-10T20:50:36.818-07:00</updated><title type='text'>Substrings</title><content type='html'>One year ago, I wrote about some &lt;a href="http://re-factor.blogspot.com/2010/07/new-combinatoric-functions.html"&gt;new combinatoric functions&lt;/a&gt; that I wrote.  I had a recent need for a couple of "substring" functions.  Since I couldn't find them in &lt;a href="http://www.factorcode.org/"&gt;Factor's&lt;/a&gt; standard library, I thought I would contribute these:&lt;br /&gt;&lt;h2&gt;all-subseqs&lt;/h2&gt;Our first word takes a sequence, and then returns all (consecutive) subsequences that can be found.  In Factor, the &lt;a href="http://docs.factorcode.org/content/vocab-grouping.html"&gt;grouping&lt;/a&gt; vocabulary provides a &lt;a href="http://docs.factorcode.org/content/word-clump%2Cgrouping.html"&gt;clumping&lt;/a&gt; feature that splits a sequence into overlapping, fixed-length, subsequences.  We can use this to find clumps of every possible length to solve this problem:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;USING:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;grouping&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;kernel&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math.ranges&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;sequences&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;all-subseqs&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seqs&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    dup length &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&amp;lt;clumps&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; with map concat &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;You can see how this works:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abcd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;all-subseqs&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"a"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"b"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"c"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"d"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"ab"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"bc"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"cd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abc"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"bcd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abcd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;i&gt;Note: we specifically don't include the "empty" string in the results.&lt;/i&gt;&lt;br /&gt;&lt;h2&gt;longest-subseq&lt;/h2&gt;&lt;p&gt;Several &lt;a href="http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring"&gt;algorithms and implementations&lt;/a&gt; can be found for the &lt;a href="http://en.wikipedia.org/wiki/Longest_common_substring_problem"&gt;longest common substring problem&lt;/a&gt;.  Basically, we want a word that returns the longest (consecutive) substring that is common between two strings.&lt;/p&gt;&lt;p&gt;Using &lt;a href="http://docs.factorcode.org/content/article-locals.html"&gt;locals&lt;/a&gt;, I translated the &lt;a href="http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#Python"&gt;Python solution&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;USING:&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;arrays&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;kernel&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;locals&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;math.ranges&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;sequences&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;::&lt;/span&gt; &lt;span style="color: blue;"&gt;longest-subseq&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq1&lt;/span&gt; &lt;span style="color: #19177c;"&gt;seq2&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;subseq&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;seq1&lt;span style="color: green;"&gt; length &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;len1&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;seq2&lt;span style="color: green;"&gt; length &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;len2&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #666666;"&gt;0 &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;n!&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #666666;"&gt;0 &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;end!&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;len1&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 + &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;len2&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 + 0 &lt;/span&gt;&lt;span style="color: green;"&gt;&amp;lt;array&amp;gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; replicate &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;table&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;len1&lt;span style="color: green;"&gt; &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[|&lt;span style="color: green;"&gt; &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;|&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;len2&lt;span style="color: green;"&gt; &lt;/span&gt;[1,b]&lt;span style="color: green;"&gt; &lt;/span&gt;[|&lt;span style="color: green;"&gt; &lt;/span&gt;y&lt;span style="color: green;"&gt; &lt;/span&gt;|&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 - &lt;/span&gt;seq1&lt;span style="color: green;"&gt; nth&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;y&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 - &lt;/span&gt;seq2&lt;span style="color: green;"&gt; nth &lt;/span&gt;&lt;span style="color: #666666;"&gt;= &lt;/span&gt;[&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                &lt;/span&gt;y&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 - &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 - &lt;/span&gt;table&lt;span style="color: green;"&gt; nth nth &lt;/span&gt;&lt;span style="color: #666666;"&gt;1 + &lt;/span&gt;:&amp;gt;&lt;span style="color: green;"&gt; &lt;/span&gt;len&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                &lt;/span&gt;len&lt;span style="color: green;"&gt; &lt;/span&gt;y&lt;span style="color: green;"&gt; &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;table&lt;span style="color: green;"&gt; nth set-nth&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;                &lt;/span&gt;len&lt;span style="color: green;"&gt; &lt;/span&gt;n&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;&amp;gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;len&lt;span style="color: green;"&gt; &lt;/span&gt;n!&lt;span style="color: green;"&gt; &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;end!&lt;span style="color: green;"&gt; &lt;/span&gt;]&lt;span style="color: green;"&gt; when&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;            &lt;/span&gt;]&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;0 &lt;/span&gt;y&lt;span style="color: green;"&gt; &lt;/span&gt;x&lt;span style="color: green;"&gt; &lt;/span&gt;table&lt;span style="color: green;"&gt; nth set-nth &lt;/span&gt;]&lt;span style="color: green;"&gt; if&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;]&lt;span style="color: green;"&gt; each &lt;/span&gt;end&lt;span style="color: green;"&gt; &lt;/span&gt;n&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #666666;"&gt;- &lt;/span&gt;end&lt;span style="color: green;"&gt; &lt;/span&gt;seq1&lt;span style="color: green;"&gt; subseq &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;Below, you can see how it works:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abc"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"def"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;longest-subseq&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121;"&gt;""&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abcd"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"abcde"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;longest-subseq&lt;span style="color: green;"&gt; &lt;/span&gt;.&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121;"&gt;"abcd"&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;i&gt;Note: don't confuse this with the &lt;a href="http://en.wikipedia.org/wiki/Longest_common_subsequence_problem"&gt;longest common subsequence problem&lt;/a&gt; (see &lt;a href="http://en.wikipedia.org/wiki/Subsequence#Substring_vs._subsequence"&gt;substring vs. subsequence&lt;/a&gt; for more details), which is implemented in Factor by the &lt;a href="http://docs.factorcode.org/content/vocab-lcs.html"&gt;lcs&lt;/a&gt; vocabulary.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-1994345702466239697?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/1994345702466239697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=1994345702466239697' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1994345702466239697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/1994345702466239697'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/substrings.html' title='Substrings'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-6276994497088996471</id><published>2011-07-07T09:04:00.000-07:00</published><updated>2011-07-07T09:04:45.392-07:00</updated><title type='text'>99 Bottles</title><content type='html'>&lt;p&gt;The &lt;a href="http://99-bottles-of-beer.net"&gt;99 Bottles Of Beer&lt;/a&gt; project has an &lt;a href="http://99-bottles-of-beer.net/language-factor-1249.html"&gt;entry&lt;/a&gt; for &lt;a href="http://www.factorcode.org"&gt;Factor&lt;/a&gt;.  Unfortunately, it's for version 0.83 (latest released version is 0.94) and some minor changes have come into the language since then.  Below, I contribute an updated version:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;formatting&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math.ranges&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;verse&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer on the wall, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Take one down and pass it around, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer on the wall.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;verse-1&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;1 bottle of beer on the wall, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;1 bottle of beer.&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Take one down and pass it around, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;no more bottles of beer on the wall.&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;verse-0&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;No more bottles of beer on the wall, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;no more bottles of beer.&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Go to the store and buy some more, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;99 bottles of beer on the wall.&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;99bottles&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;99 2 &lt;/span&gt;[a,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;verse&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;verse-1&lt;span style="color: #008000"&gt; &lt;/span&gt;verse-0&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Shorter?&lt;/h2&gt;&lt;p&gt;We can shorten this a bit by taking a few poetic liberties with the song.  While doing that, we can make it flexible to allow any (positive) number of bottles:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;formatting&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math.ranges&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;verse&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer on the wall, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Take one down and pass it around, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles of beer on the wall.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;last-verse&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Go to the store and buy some more, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;no more bottles of beer on the wall!&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; print &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;bottles&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;[a,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;verse&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;last-verse&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This solution is similar to the one &lt;a href="http://rosettacode.org/wiki/99_Bottles_of_Beer#Factor"&gt;posted&lt;/a&gt; on the Rosetta Code project.&lt;/p&gt;&lt;h2&gt;Longer!&lt;/h2&gt;&lt;p&gt;You might notice that a lot of the text is duplicative, so perhaps we can improve this solution by factoring out parts of the text into small and reusable functions.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;combinators&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;formatting&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;#bottles&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;1 bottle&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;no more bottles&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%d bottles&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;sprintf&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; case &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot; of beer&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; append &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;on-the-wall&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;#bottles&lt;span style="color: #008000"&gt; dup &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%s on the wall, %s.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;take-one-down&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Take one down and pass it around, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;#bottles&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%s on the wall.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;take-bottles&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;zero?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;on-the-wall&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;&lt;span style="color: #008000"&gt;dup &lt;/span&gt;take-one-down&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; until &lt;/span&gt;on-the-wall&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;go-to-store&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Go to the store and buy some more, &amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;#bottles&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%s on the wall.\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;bottles&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;take-bottles&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;go-to-store&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;It's a bit longer than the original and, in several ways, not as easy to understand.  If we wanted to reuse this functionality elsewhere, it's a clear win.  But, if we want to simply generate the "bottles song", perhaps the first or second way is better.&lt;/p&gt;&lt;h2&gt;Extra Credit&lt;/h2&gt;&lt;p&gt;For fun, I thought we could use our computer to sing to us (if you're using Mac OS X):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;99bottles&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-string-writer&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;say \&amp;quot;%s\&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;sprintf&lt;span style="color: #008000"&gt; &lt;/span&gt;try-process&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/99bottles/99bottles.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-6276994497088996471?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/6276994497088996471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=6276994497088996471' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/6276994497088996471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/6276994497088996471'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/99-bottles.html' title='99 Bottles'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-8785916834426967816</id><published>2011-07-04T11:25:00.000-07:00</published><updated>2011-07-04T11:25:30.683-07:00</updated><title type='text'>Fourth of July</title><content type='html'>&lt;p&gt;Today is &lt;a href="http://en.wikipedia.org/wiki/Independence_Day_(United_States)"&gt;Independence Day&lt;/a&gt; in the United States.  Several lists of &lt;a href="http://www.11points.com/Misc/11_Fantastic_Fourth_of_July_Facts"&gt;fantastic facts&lt;/a&gt; are being shared, including that today is the "biggest beer-selling holiday of the year".  However,  while not as fantastic, here are a few fun facts about today that can be derived using &lt;a href="http://www.factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Using the &lt;a href="http://docs.factorcode.org/content/article-calendar.html"&gt;calendar&lt;/a&gt; vocabulary, we can create a &lt;a href="http://docs.factorcode.org/content/word-timestamp,calendar.html"&gt;timestamp&lt;/a&gt; object for today's date:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 7 4 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;timestamp&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;year&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;month&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;7 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;day&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;4 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;gmt-offset&lt;span style="color: #008000"&gt; &lt;/span&gt;T{&lt;span style="color: #008000"&gt; &lt;/span&gt;duration&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;hour&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;-7 &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can see that today is the 185&lt;sup&gt;th&lt;/sup&gt; day of the year:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 7 4 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;day-of-year&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;185&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Today is also the 27&lt;sup&gt;th&lt;/sup&gt; week of the year (using weeks starting on Sunday - there might be a different answer using &lt;a href="http://docs.factorcode.org/content/word-week-of-year-monday,formatting.private.html"&gt;week-of-year-monday&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 7 4 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;week-of-year-sunday&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;27&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This year, July 4&lt;sup&gt;th&lt;/sup&gt; falls on a Monday, but its a different day of the week each year.  We can see which days of the week Independence Day falls on over the last few years:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 2000 &lt;/span&gt;[a,b]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;                   dup &lt;/span&gt;&lt;span style="color: #666666"&gt;7 4 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;day-name&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;%s: %s\n&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;printf&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;]&lt;span style="color: #008000"&gt; each&lt;/span&gt;&lt;br /&gt;2011: Monday&lt;br /&gt;2010: Sunday&lt;br /&gt;2009: Saturday&lt;br /&gt;2008: Friday&lt;br /&gt;2007: Wednesday&lt;br /&gt;2006: Tuesday&lt;br /&gt;2005: Monday&lt;br /&gt;2004: Sunday&lt;br /&gt;2003: Friday&lt;br /&gt;2002: Thursday&lt;br /&gt;2001: Wednesday&lt;br /&gt;2000: Tuesday&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And, finally, the most recent version of Factor (0.94) was &lt;a href="http://factor-language.blogspot.com/2010/09/factor-094-now-available.html"&gt;released&lt;/a&gt; on September 18, 2010, which was 289 days ago.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2011 7 4 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2010 9 18 &lt;/span&gt;&amp;lt;date&amp;gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;               &lt;/span&gt;time-&lt;span style="color: #008000"&gt; &lt;/span&gt;duration&amp;gt;days&lt;span style="color: #008000"&gt; &lt;/span&gt;.&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666"&gt;289&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-8785916834426967816?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/8785916834426967816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=8785916834426967816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/8785916834426967816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/8785916834426967816'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/07/fourth-of-july.html' title='Fourth of July'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-2038974151869655684</id><published>2011-06-29T15:38:00.000-07:00</published><updated>2011-06-30T09:01:48.478-07:00</updated><title type='text'>TF-IDF</title><content type='html'>&lt;p&gt;A few days ago, someone implemented a consice &lt;a href="http://en.wikipedia.org/wiki/Tf%E2%80%93idf"&gt;TF-IDF&lt;/a&gt; ("term frequency - inverse document frequency") search engine in &lt;a href="https://github.com/felipehummel/TinySearchEngine/blob/master/scala/tinySearch.scala"&gt;Scala&lt;/a&gt;.  That was followed by a similarly concise version in &lt;a href="http://thecomputersarewinning.com/post/simple-tfidf-in-clojure"&gt;Clojure&lt;/a&gt;.  I thought to contribute a simple (hopefully also concise) implementation using &lt;a href="http://www.factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;accessors&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;arrays&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;assocs&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;combinators.short-circuit&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;fry&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;io.encodings.utf8&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io.files&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;math.functions&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;math.statistics&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;memoize&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sets&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sorting&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;splitting&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;unicode.case&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;unicode.categories&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;IN:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;tf-idf&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Tokenize&lt;/h2&gt;&lt;p&gt;Since our inputs are going to be text files, our program will need to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Read the file into a string.&lt;/li&gt;&lt;li&gt;Split the string into words.&lt;/li&gt;&lt;li&gt;Eliminate common (or "stop") words.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Fist, let's build a word to split our text on any non-letter or non-number characters.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;split-words&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;string&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;Letter?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;digit?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;1||&lt;span style="color: #008000"&gt; not &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;split-when&lt;span style="color: #008000"&gt; harvest &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We load a list of "stop words" that are to be ignored.  These are typically common occurring words such as "&lt;i&gt;and, in, or, of, the, is&lt;/i&gt;".&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;MEMO:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;stopwords&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;vocab:tf-idf/stopwords.txt&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;utf8&lt;span style="color: #008000"&gt; &lt;/span&gt;file-lines&lt;span style="color: #008000"&gt; &lt;/span&gt;fast-set&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can then tokenize a piece of text, removing all of the "stop words".&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;tokenize&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;string&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;gt;lower&lt;span style="color: #008000"&gt; &lt;/span&gt;split-words&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;stopwords&lt;span style="color: #008000"&gt; &lt;/span&gt;in?&lt;span style="color: #008000"&gt; not &lt;/span&gt;]&lt;span style="color: #008000"&gt; filter &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And, finally, we can create a word to tokenize a series of files into an &lt;code&gt;assoc&lt;/code&gt; mapping &lt;code&gt;path&lt;/code&gt; to &lt;code&gt;words&lt;/code&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;tokenize-files&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;paths&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;utf8&lt;span style="color: #008000"&gt; &lt;/span&gt;file-contents&lt;span style="color: #008000"&gt; &lt;/span&gt;tokenize&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; map&amp;gt;assoc &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Index&lt;/h2&gt;&lt;p&gt;To implement our search engine, we need to build an index that maps each &lt;code&gt;word&lt;/code&gt; to list of &lt;code&gt;(path, count)&lt;/code&gt; pairs.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;index1&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #19177C"&gt;words&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #19177C"&gt;index&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;histogram&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; pick swap 2array &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;index-all&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;index&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;index1&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map values &lt;/span&gt;assoc-merge&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The tokenized files and our index will form the basis for a "database":&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;TUPLE:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;db&lt;/span&gt; &lt;span style="color: #19177C"&gt;docs&lt;/span&gt; &lt;span style="color: #19177C"&gt;index&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;&amp;lt;db&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;paths&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;tokenize-files&lt;span style="color: #008000"&gt; dup &lt;/span&gt;index-all&lt;span style="color: #008000"&gt; &lt;/span&gt;db&lt;span style="color: #008000"&gt; boa &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;TF-IDF&lt;/h2&gt;&lt;p&gt;The "inverse document frequency" is calculated by the &lt;a href="http://docs.factorcode.org/content/word-log,math.functions.html"&gt;log&lt;/a&gt; of the total number of documents divided by number of documents where a particular word appears.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;idf&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;term&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;idf&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; nip &lt;/span&gt;docs&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;index&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; at &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2bi &lt;/span&gt;[&lt;span style="color: #008000"&gt; assoc-size &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi@ &lt;/span&gt;&lt;span style="color: #666666"&gt;/ &lt;/span&gt;log&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Using this, we can create a "TF-IDF" scores by multiplying the number of times a term appears in each document by the previously calculated "inverse document frequency":&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;tf-idf&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;term&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;scores&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;index&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; at &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;idf&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2bi &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;* &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Search&lt;/h2&gt;&lt;p&gt;Our search engine is now just a matter of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Splitting an input query into terms.&lt;/li&gt;&lt;li&gt;Calculating the "TF-IDF" score for each term.&lt;/li&gt;&lt;li&gt;Normalizing the scores across documents.&lt;/li&gt;&lt;li&gt;Sorting the scores from highest to lowest.&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;scores&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;query&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;scores&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;split-words&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;tf-idf&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map &lt;/span&gt;assoc-merge&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(normalize)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;value&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;docs&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; at &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;idf&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 ^ &lt;/span&gt;]&lt;span style="color: #008000"&gt; map-sum &lt;/span&gt;sqrt&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;normalize&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;scores&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;scores&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; sum over &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;(normalize)&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;/ &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;search&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;query&lt;/span&gt; &lt;span style="color: #19177C"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;scores&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;scores&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &lt;/span&gt;normalize&lt;span style="color: #008000"&gt; &lt;/span&gt;sort-values&lt;span style="color: #008000"&gt; reverse &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Notes&lt;/h2&gt;&lt;i&gt;The implementation above uses an &lt;code&gt;assoc-merge&lt;/code&gt; utility word that performs a "union", for each key collecting a list of all values.&lt;/i&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;(assoc-merge)&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc1&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc2&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc1&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    over &lt;/span&gt;[&lt;span style="color: #008000"&gt; push-at &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-assoc&lt;span style="color: #008000"&gt; assoc-each &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;assoc-merge&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;seq&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;merge&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; clone &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;(assoc-merge)&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; reduce &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;i&gt;Also, searching for words that don't exist produces a "divide by zero" error.  Making it more robust requires some changes to either catch and ignore that error or to "add 1" to the denominator of the "IDF" formula.&lt;/i&gt;&lt;br /&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/tf-idf/tf-idf.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-2038974151869655684?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/2038974151869655684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=2038974151869655684' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2038974151869655684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2038974151869655684'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/06/tf-idf.html' title='TF-IDF'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4809284967045365134</id><published>2011-06-10T21:23:00.000-07:00</published><updated>2011-07-11T17:36:05.899-07:00</updated><title type='text'>Yahoo! Finance</title><content type='html'>&lt;p&gt;Many programmers work for publicly traded companies, and probably spend more time than they realize watching their (or their friends) company's stock prices.  To make that easier, I wanted to implement a simple wrapper to retrieve prices from &lt;a href="http://draft.blogger.com/finance.yahoo.com"&gt;Yahoo! Finance&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Quotes&lt;/h2&gt;&lt;p&gt;You can use a "quotes.csv" interface to retrieve current price information.  The way it works is to perform an HTTP request to a specially formatted URL that looks like:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;http://finance.yahoo.com/d/quotes.csv?s=SYMBOLS&amp;amp;f=FIELDS&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;In the URL, &lt;code&gt;SYMBOLS&lt;/code&gt; is a list of symbols separated by "&lt;code&gt;+&lt;/code&gt;" and &lt;code&gt;FIELDS&lt;/code&gt; is a list of letters and numbers (from the following table) representing fields to be requested.&lt;/p&gt;&lt;blockquote&gt;&lt;style type="text/css"&gt;/* &lt;![CDATA[ */table#data, table#data td{    border-color: #c0c0c0;    border-style: solid;}table#data{    border-width: 0 0 1px 1px;    border-spacing: 0;    border-collapse: collapse;}table#data td{    margin: 0;    padding: 2px;    border-width: 1px 1px 0 0;}/* ]]&gt; */&lt;/style&gt;&lt;br /&gt;&lt;table id="data"&gt;&lt;tbody&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;a&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Ask&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;a2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Average Daily Volume&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;a5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Ask Size&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;b&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Bid&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;b2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Ask (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;b3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Bid (Real-time)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;b4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Book Value&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;b6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Bid Size&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change &amp;amp; Percent Change&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;c1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;c3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Commission&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;c6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change (Real-time)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;c8&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;After Hours Change (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;d&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Dividend/Share&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;d1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade Date&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;d2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Trade Date&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;e&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Earnings/Share&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;e1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Error Indication (returned for symbol changed / invalid)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;e7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;EPS Estimate Current Year&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;e8&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;EPS Estimate Next Year&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;e9&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;EPS Estimate Next Quarter&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;f6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Float Shares&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;g&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s Low&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;h&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s High&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;j&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;52-week Low&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;k&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;52-week High&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;g1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Gain Percent&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;g3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Annualized Gain&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;g4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Gain&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;g5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Gain Percent (Real-time)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;g6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Gain (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;i&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;More Info&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;i5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Order Book (Real-time)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;j1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Market Capitalization&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;j3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Market Cap (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;j4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;EBITDA&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;j5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change From 52-week Low&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;j6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Percent Change From 52-week Low&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;k1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade (Real-time) With Time&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;k2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change Percent (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;k3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade Size&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;k4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change From 52-week High&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;k5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Percent Change From 52-week High&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;l&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade (With Time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;l1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade (Price Only)&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;l2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;High Limit&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;l3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Low Limit&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;m&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s Range&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;m2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s Range (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;m3&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;50-day Moving Average&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;m4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;200-day Moving Average&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;m5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change From 200-day Moving Average&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;m6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Percent Change From 200-day Moving Average&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;m7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change From 50-day Moving Average&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;m8&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Percent Change From 50-day Moving Average&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;n&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Name&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;n4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Notes&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;o&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Open&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;p&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Previous Close&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;p1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Price Paid&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;p2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Change in Percent&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;p5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Price/Sales&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;p6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Price/Book&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;q&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Ex-Dividend Date&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;r&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;P/E Ratio&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;r1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Dividend Pay Date&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;r2&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;P/E Ratio (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;r5&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;PEG Ratio&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;r6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Price/EPS Estimate Current Year&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;r7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Price/EPS Estimate Next Year&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;s&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Symbol&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;s1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Shares Owned&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;s7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Short Ratio&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;t1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Last Trade Time&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;t6&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Trade Links&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;t7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Ticker Trend&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;t8&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;1 yr Target Price&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;v&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Volume&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;v1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Value&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;v7&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Holdings Value (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;w&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;52-week Range&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;w1&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s Value Change&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;w4&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Day’s Value Change (Real-time)&lt;/td&gt;  &lt;td&gt;&lt;strong&gt;x&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Stock Exchange&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;strong&gt;y&lt;/strong&gt;&lt;/td&gt;  &lt;td&gt;Dividend Yield&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/blockquote&gt;&lt;p&gt;Using this URL format, we can build a word that retrieves current quotes for a list of symbols:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;quotes&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;symbols&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;csv&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"http://finance.yahoo.com/d/quotes.csv"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&amp;gt;url&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        swap &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"+"&lt;/span&gt;&lt;span style="color: green;"&gt; join &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"s"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;        &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"sbal1v"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"f"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;http-get&lt;span style="color: green;"&gt; nip &amp;gt;string &lt;/span&gt;string&amp;gt;csv&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Symbol"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Bid"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Ask"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Last"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"Volume"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt; prefix &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;With the &lt;a href="http://docs.factorcode.org/content/vocab-strings.tables.html"&gt;strings.table&lt;/a&gt; vocabulary, we can format the response as a table:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;( scratchpad )&lt;span style="color: green;"&gt; &lt;/span&gt;{&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"MSFT"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"GOOG"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"AAPL"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;}&lt;span style="color: green;"&gt; &lt;/span&gt;quotes&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;               &lt;/span&gt;format-table&lt;span style="color: green;"&gt; &lt;/span&gt;[&lt;span style="color: green;"&gt; print &lt;/span&gt;]&lt;span style="color: green;"&gt; each&lt;/span&gt;&lt;br /&gt;Symbol Bid    Ask    Last    Volume&lt;br /&gt;MSFT   23.64  23.69  23.705  49327104&lt;br /&gt;GOOG   505.00 509.05 509.505 2440475&lt;br /&gt;AAPL   N/A    334.80 325.90  15504200&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Historical Prices&lt;/h2&gt;&lt;p&gt;You can also retrieve historical prices using a "table.csv" interface.  Similar to retrieving quotes, you make an HTTP request to a special URL:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;http://ichart.finance.yahoo.com/table.csv?s=SYMBOL&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;In the URL, &lt;code&gt;SYMBOL&lt;/code&gt; is the symbol that you are requesting prices for, and you can further limit the response using additional parameters:&lt;/p&gt;&lt;p&gt;Start date for historical prices:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;a&lt;/strong&gt; - Month number, starting with 0 for January.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;b&lt;/strong&gt; - Day number, eg, 1 for the first of the month.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;c&lt;/strong&gt; - Year.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;End date for historical prices (default is the most current available closing price):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;d&lt;/strong&gt; - Month number, starting with 0 for January.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;e&lt;/strong&gt; - Day number, eg, 1 for the first of the month.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;f&lt;/strong&gt; - Year.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And finally, the frequency of historical prices:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;g&lt;/strong&gt; - Possible values are 'd' for daily (the default), 'w' for weekly, and 'm' for monthly.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With this knowledge, we can build a word to retrieve historical prices from January 1, 2009 until the current day.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: green; font-weight: bold;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;historical-prices&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;(&lt;/span&gt; &lt;span style="color: #19177c;"&gt;symbol&lt;/span&gt; &lt;span style="color: blue;"&gt;--&lt;/span&gt; &lt;span style="color: #19177c;"&gt;csv&lt;/span&gt; &lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"http://ichart.finance.yahoo.com/table.csv"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&amp;gt;url&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;       swap &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"s"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;       &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"0"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"a"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;       &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"1"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"b"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;       &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"2009"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: #ba2121;"&gt;"c"&lt;/span&gt;&lt;span style="color: green;"&gt; &lt;/span&gt;set-query-param&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;    &lt;/span&gt;http-get&lt;span style="color: green;"&gt; nip &lt;/span&gt;string&amp;gt;csv&lt;span style="color: green;"&gt; &lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;To use it, and demonstrate the impact that &lt;a href="http://finance.yahoo.com/q?s=AAPL&amp;amp;ql=1"&gt;AAPL&lt;/a&gt; has had over the last few years, we can &lt;a href="http://re-factor.blogspot.com/2011/03/google-charts.html"&gt;chart&lt;/a&gt; the daily closing prices (remembering to reverse the order of the prices, oldest to newest):&lt;/p&gt;&lt;img src="https://lh3.googleusercontent.com/-ZYLODYaMKEA/TfLr1bVjRBI/AAAAAAAAAKg/WROXkcJrCMc/historical-prices.png" /&gt;&lt;br /&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/yahoo/finance/finance.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4809284967045365134?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4809284967045365134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4809284967045365134' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4809284967045365134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4809284967045365134'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/06/yahoo-finance.html' title='Yahoo! Finance'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-ZYLODYaMKEA/TfLr1bVjRBI/AAAAAAAAAKg/WROXkcJrCMc/s72-c/historical-prices.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-56928916307299547</id><published>2011-05-17T11:53:00.000-07:00</published><updated>2011-05-17T11:53:58.834-07:00</updated><title type='text'>Fibonacci Wars</title><content type='html'>&lt;p&gt;Inspired by a recent &lt;a href="http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/"&gt;article&lt;/a&gt; about the "worst algorithm in the world" for calculating &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Fibonacci numbers&lt;/a&gt; using &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt;, I wanted to show a few implementations in &lt;a href="http://www.factorcode.org"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Recursive&lt;/h2&gt;&lt;p&gt;Most people should be familiar with the simple definition for calculating the Fibonacci numbers:&lt;/p&gt;&lt;blockquote&gt;&lt;img src="https://lh6.googleusercontent.com/_J6Ti4lvPWak/TdAbG3xeOcI/AAAAAAAAAKI/S13guNXfzAk/slow-fib.png" /&gt;&lt;/blockquote&gt;&lt;p&gt;Some recursive implementations of this algorithm suffer from very slow performance due to the nature of hugely recursive functions, making them unsuitable for larger Fibonacci numbers.  Thankfully, it is easy to implement caching using the &lt;a href="http://docs.factorcode.org/content/article-memoize.html"&gt;memoize&lt;/a&gt; vocabulary:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;MEMO:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;slow-fib&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;m&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; throw &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 - &lt;/span&gt;slow-fib&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 - &lt;/span&gt;slow-fib&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; when &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Iterative&lt;/h2&gt;&lt;p&gt;A better way would be to implement an iterative solution, that simply keeps the current and previous Fibonacci number on the stack, adding them the specified number of times:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;okay-fib&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;m&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; throw &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 1 &lt;/span&gt;]&lt;span style="color: #008000"&gt; dip &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; drop &lt;/span&gt;]&lt;span style="color: #008000"&gt; 2bi &lt;/span&gt;]&lt;span style="color: #008000"&gt; times drop &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Magical&lt;/h2&gt;&lt;p&gt;A much better way (introduced by the original article) suggests taking advantage of a matrix expression for the Fibonacci numbers:&lt;/p&gt;&lt;blockquote&gt;&lt;img src="https://lh4.googleusercontent.com/_J6Ti4lvPWak/TdAaytJRkmI/AAAAAAAAAJ8/zvSHBJ967qo/fast-fib.png" /&gt;&lt;/blockquote&gt;&lt;p&gt;Using this, we can implement a faster version in Factor (using &lt;a href="http://docs.factorcode.org/content/article-locals.html"&gt;locals&lt;/a&gt; to make it a bit more readable):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;::&lt;/span&gt; &lt;span style="color: #0000FF"&gt;fast-fib&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;m&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;n&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;m&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;gt;= &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;m&lt;span style="color: #008000"&gt; throw &lt;/span&gt;]&lt;span style="color: #008000"&gt; unless&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;m&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;2 &lt;/span&gt;&amp;gt;base&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;CHAR: 1 &lt;/span&gt;&lt;span style="color: #666666"&gt;= &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; map-as &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;bits&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;a!&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;0 &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;b!&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1 &lt;/span&gt;:&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;c!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;bits&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;a&lt;span style="color: #008000"&gt; &lt;/span&gt;c&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;b&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;b&lt;span style="color: #008000"&gt; sq &lt;/span&gt;c&lt;span style="color: #008000"&gt; sq &lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;a&lt;span style="color: #008000"&gt; sq &lt;/span&gt;b&lt;span style="color: #008000"&gt; sq &lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;a&lt;span style="color: #008000"&gt; &lt;/span&gt;c&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;b&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;]&lt;span style="color: #008000"&gt; if &lt;/span&gt;b!&lt;span style="color: #008000"&gt; &lt;/span&gt;a!&lt;span style="color: #008000"&gt; &lt;/span&gt;a&lt;span style="color: #008000"&gt; &lt;/span&gt;b&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;+ &lt;/span&gt;c!&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;b&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Performance&lt;/h2&gt;&lt;p&gt;Some simple performance numbers show how much faster the "magical" version is, particularly for calculating large Fibonacci numbers (such as the the one-millionth number in the sequence). &lt;/p&gt;&lt;blockquote&gt;&lt;table&gt;&lt;tr&gt; &lt;th&gt;&lt;/th&gt; &lt;th&gt;10,000&lt;/th&gt; &lt;th&gt;100,000&lt;/th&gt; &lt;th&gt;1,000,000&lt;/th&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;&lt;code&gt;slow-fib&lt;/code&gt;&lt;/td&gt; &lt;td align="right"&gt;0.0097&lt;/td&gt; &lt;td align="center"&gt;--&lt;/td&gt; &lt;td align="center"&gt;--&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;&lt;code&gt;okay-fib&lt;/code&gt;&lt;/td&gt; &lt;td align="right"&gt;0.0053&lt;/td&gt; &lt;td align="right"&gt;0.2560&lt;/td&gt; &lt;td align="right"&gt;25.9608&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;&lt;code&gt;fast-fib&lt;/code&gt;&lt;/td&gt; &lt;td align="right"&gt;0.0001&lt;/td&gt; &lt;td align="right"&gt;0.0076&lt;/td&gt; &lt;td align="right"&gt;0.4851&lt;/td&gt; &lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;p&gt;It's worth pointing out that Factor is about as fast as Python 2.6 for the "magical" calculation.  In Python 2.7 and later, certain improvements were made to their large number support, resulting in Python being about 3x faster.&lt;/p&gt;&lt;p&gt;However, if you want real performance, you can use C and the &lt;a href="http://gmplib.org/"&gt;GNU Multiple Precision Arithmetic Library&lt;/a&gt; to implement the iterative algorithm (about &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/fast-fib/fib1.c"&gt;3 times faster&lt;/a&gt; than Factor), the magical algorithm (about &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/fast-fib/fib3.c"&gt;28 times faster&lt;/a&gt; than Factor), or use the builtin &lt;a href="http://gmplib.org/manual/Number-Theoretic-Functions.html#index-mpz_005ffib_005fui-401"&gt;mpz_fib_ui&lt;/a&gt; function (about &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/fast-fib/fib2.c"&gt;44 times faster&lt;/a&gt; than Factor).&lt;/p&gt;&lt;p&gt;The code for this (as well as several version in C) are on my &lt;a href="https://github.com/mrjbq7/re-factor/tree/master/fast-fib"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-56928916307299547?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/56928916307299547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=56928916307299547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/56928916307299547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/56928916307299547'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/05/fibonacci-wars.html' title='Fibonacci Wars'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_J6Ti4lvPWak/TdAbG3xeOcI/AAAAAAAAAKI/S13guNXfzAk/s72-c/slow-fib.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-4121769665307359979</id><published>2011-05-15T10:15:00.000-07:00</published><updated>2011-05-15T10:15:15.441-07:00</updated><title type='text'>Google Search</title><content type='html'>&lt;p&gt;A couple months ago, I implemented wrappers for the &lt;a href="http://re-factor.blogspot.com/2011/03/google-charts.html"&gt;Google Charts&lt;/a&gt; and &lt;a href="http://re-factor.blogspot.com/2011/03/google-translate.html"&gt;Google Translate&lt;/a&gt; API's.  Today, I'd like to implement a wrapper for Google Search.&lt;/p&gt;&lt;h2&gt;Search&lt;/h2&gt;&lt;p&gt;First, we should build a word that, given a query, returns a URL to retrieve Google Search results (formatted as &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt;):&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;search-url&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;query&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;url&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;URL&amp;quot;&lt;span style="color: #008000"&gt; &lt;/span&gt;http://ajax.googleapis.com/ajax/services/search/web&amp;quot;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;v&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;set-query-param&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        swap &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;set-query-param&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;8&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;rsz&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;set-query-param&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;start&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;set-query-param&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can define a &lt;a href="http://docs.factorcode.org/content/article-tuples.html"&gt;tuple class&lt;/a&gt; to hold the attributes every search result should have:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;TUPLE:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;search-result&lt;/span&gt; &lt;span style="color: #19177C"&gt;cacheUrl&lt;/span&gt; &lt;span style="color: #19177C"&gt;GsearchResultClass&lt;/span&gt; &lt;span style="color: #19177C"&gt;visibleUrl&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #19177C"&gt;title&lt;/span&gt; &lt;span style="color: #19177C"&gt;content&lt;/span&gt; &lt;span style="color: #19177C"&gt;unescapedUrl&lt;/span&gt; &lt;span style="color: #19177C"&gt;url&lt;/span&gt; &lt;span style="color: #19177C"&gt;titleNoFormatting&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Using some code to &lt;a href="http://re-factor.blogspot.com/2011/01/setting-attributes.html"&gt;set attributes dynamically&lt;/a&gt;, we can perform a Google Search, and parse the results into a sequence of &lt;code&gt;search-result&lt;/code&gt; objects.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;http-search&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;query&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;results&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;search-url&lt;span style="color: #008000"&gt; &lt;/span&gt;http-get&lt;span style="color: #008000"&gt; nip &lt;/span&gt;json&amp;gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;responseData&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;results&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; swap at &lt;/span&gt;]&lt;span style="color: #008000"&gt; each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; \ &lt;/span&gt;search-result&lt;span style="color: #008000"&gt; &lt;/span&gt;from-slots&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Display&lt;/h2&gt;&lt;p&gt;We can build some simple words that can be used to format the output of a search:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;write-heading&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;font-size&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;14 &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;background&lt;span style="color: #008000"&gt; &lt;/span&gt;COLOR:&lt;span style="color: #008000"&gt; &lt;/span&gt;light-gray&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;format&lt;span style="color: #008000"&gt; nl &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;write-title&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;foreground&lt;span style="color: #008000"&gt; &lt;/span&gt;COLOR:&lt;span style="color: #008000"&gt; &lt;/span&gt;blue&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;format&lt;span style="color: #008000"&gt; nl &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;write-content&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #666666"&gt;60 &lt;/span&gt;wrap-string&lt;span style="color: #008000"&gt; print &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;write-url&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;str&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    dup &lt;/span&gt;&amp;gt;url&lt;span style="color: #008000"&gt; &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;font-name&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;monospace&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;foreground&lt;span style="color: #008000"&gt; &lt;/span&gt;COLOR:&lt;span style="color: #008000"&gt; &lt;/span&gt;dark-green&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;write-object&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-style&lt;span style="color: #008000"&gt; nl &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And then create a word to perform a search and display the results.  If you are using my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/webbrowser/webbrowser.factor"&gt;webbrowser&lt;/a&gt; vocabulary, you can open the URL's in a webbrowser directly from Factor.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;http-search.&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;query&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Search results for &amp;#39;%s&amp;#39;&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;sprintf&lt;span style="color: #008000"&gt; &lt;/span&gt;write-heading&lt;span style="color: #008000"&gt; nl &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;http-search&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;titleNoFormatting&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;write-title&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;content&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;write-content&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;            &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;unescapedUrl&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;write-url&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;}&lt;span style="color: #008000"&gt; cleave nl&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; each &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Try it out&lt;/h2&gt;&lt;p&gt;If everything works correctly, you should be able to perform a search in the Listener (e.g., searching for "factor"):&lt;/p&gt;&lt;img src="https://lh6.googleusercontent.com/_J6Ti4lvPWak/TcNpkIEuOvI/AAAAAAAAAJY/couvO294FLI/http-search.png" /&gt;&lt;br /&gt;&lt;p&gt;Some things we might do to improve this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;add paging, to the next or previous page of search results&lt;/li&gt;&lt;li&gt;highlight in bold the searched words in the content&lt;/li&gt;&lt;li&gt;unescape the HTML entities in the content&lt;/li&gt;&lt;li&gt;build a lightweight GUI to render the results&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The code for this is on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/google/search/search.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-4121769665307359979?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/4121769665307359979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=4121769665307359979' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4121769665307359979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/4121769665307359979'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/05/google-search.html' title='Google Search'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_J6Ti4lvPWak/TcNpkIEuOvI/AAAAAAAAAJY/couvO294FLI/s72-c/http-search.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-444659298760985836</id><published>2011-05-05T21:38:00.000-07:00</published><updated>2011-05-05T21:45:13.854-07:00</updated><title type='text'>Open URL (in Listener)</title><content type='html'>&lt;p&gt;In January, I implemented a cross-platform &lt;a href="http://re-factor.blogspot.com/2011/01/open-url.html"&gt;open-url&lt;/a&gt; feature to allow opening URLs from Factor.  One major problem was that I couldn't figure out how to make URLs "clickable" in the Listener.&lt;/p&gt;&lt;p&gt;Then, I learned that the &lt;a href="http://docs.factorcode.org/content/vocab-ui.operations.html"&gt;ui.operations&lt;/a&gt; vocabulary allows us to add "capabilities" that get triggered when certain types are rendered in the Listener.  It turns out to be pretty easy, actually:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;url?&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; \ &lt;/span&gt;open-url&lt;span style="color: #008000"&gt; &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;define-operation&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Using that, you can right-click on URL objects, and choose to open them in your web browser:&lt;/p&gt;&lt;img src="https://lh3.googleusercontent.com/_J6Ti4lvPWak/TcNrzKtj9kI/AAAAAAAAAJk/U8U-FS8jRz0/open-url.png" /&gt;&lt;br /&gt;&lt;p&gt;I also made a &lt;a href="https://github.com/slavapestov/factor/commit/927f66f901d181e8900b33321e22b1c9dad7c2c2#basis/help/markup/markup.factor"&gt;small patch&lt;/a&gt; to add this support to URLs that are rendered in the &lt;a href="http://docs.factorcode.org/content/article-help.html"&gt;help system&lt;/a&gt; or in the &lt;a href="http://docs.factorcode.org/content/vocab-slides.html"&gt;slides&lt;/a&gt; vocabulary.&lt;/p&gt;&lt;p&gt;&lt;i&gt;Note: if you want this operation to be the "primary operation" triggered when the URL is left-clicked, you can add &lt;code&gt;{ +primary+ t }&lt;/code&gt; to the hashtable used in the operation's definition.&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-444659298760985836?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/444659298760985836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=444659298760985836' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/444659298760985836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/444659298760985836'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/05/open-url-in-listener.html' title='Open URL (in Listener)'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/_J6Ti4lvPWak/TcNrzKtj9kI/AAAAAAAAAJk/U8U-FS8jRz0/s72-c/open-url.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-2742749323642390726</id><published>2011-05-01T19:49:00.000-07:00</published><updated>2011-05-01T19:49:35.818-07:00</updated><title type='text'>Reddit Stats</title><content type='html'>&lt;p&gt;I thought it would be fun to track the development of the &lt;a href="http://factorcode.org"&gt;Factor&lt;/a&gt; programming language using Reddit.  Of course, to do this, I wanted to use Factor.&lt;/p&gt;&lt;p&gt;A few months ago, I implemented a &lt;a href="http://re-factor.blogspot.com/2011/01/reddit-top.html"&gt;Reddit "Top"&lt;/a&gt; program.  We can use the code for that as a basis for showing, using Reddit scores, how the activity (or popularity?) of a couple Factor blogs have changed over the last few years:&lt;/p&gt;&lt;img src="https://lh6.googleusercontent.com/_J6Ti4lvPWak/Tb4XOEh7YNI/AAAAAAAAAI8/FQS2gIeHJyo/blog-scores.png" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Stories&lt;/h2&gt;&lt;p&gt;We start by creating a &lt;code&gt;story&lt;/code&gt; tuple that will hold all of the properties that Reddit returns for each posted link (including the score -- up votes minus down votes -- which we will be using).&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;TUPLE:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;story&lt;/span&gt; &lt;span style="color: #19177C"&gt;author&lt;/span&gt; &lt;span style="color: #19177C"&gt;clicked&lt;/span&gt; &lt;span style="color: #19177C"&gt;created&lt;/span&gt; &lt;span style="color: #19177C"&gt;created_utc&lt;/span&gt; &lt;span style="color: #19177C"&gt;domain&lt;/span&gt; &lt;span style="color: #19177C"&gt;downs&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #19177C"&gt;hidden&lt;/span&gt; &lt;span style="color: #19177C"&gt;id&lt;/span&gt; &lt;span style="color: #19177C"&gt;is_self&lt;/span&gt; &lt;span style="color: #19177C"&gt;levenshtein&lt;/span&gt; &lt;span style="color: #19177C"&gt;likes&lt;/span&gt; &lt;span style="color: #19177C"&gt;media&lt;/span&gt; &lt;span style="color: #19177C"&gt;media_embed&lt;/span&gt; &lt;span style="color: #19177C"&gt;name&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #19177C"&gt;num_comments&lt;/span&gt; &lt;span style="color: #19177C"&gt;over_18&lt;/span&gt; &lt;span style="color: #19177C"&gt;permalink&lt;/span&gt; &lt;span style="color: #19177C"&gt;saved&lt;/span&gt; &lt;span style="color: #19177C"&gt;score&lt;/span&gt; &lt;span style="color: #19177C"&gt;selftext&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #19177C"&gt;selftext_html&lt;/span&gt; &lt;span style="color: #19177C"&gt;subreddit&lt;/span&gt; &lt;span style="color: #19177C"&gt;subreddit_id&lt;/span&gt; &lt;span style="color: #19177C"&gt;thumbnail&lt;/span&gt; &lt;span style="color: #19177C"&gt;title&lt;/span&gt; &lt;span style="color: #19177C"&gt;ups&lt;/span&gt; &lt;span style="color: #19177C"&gt;url&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And a word to parse a "data" result into a story object:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;parse-story&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;assoc&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;obj&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; swap at \ &lt;/span&gt;story&lt;span style="color: #008000"&gt; &lt;/span&gt;from-slots&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Paging&lt;/h2&gt;&lt;p&gt;The &lt;a href="http://code.reddit.com/wiki/API"&gt;Reddit API&lt;/a&gt; provides results as a series of "pages" (until all results are exhausted).  This is pretty similar to how the website works, so it should be fairly easy to understand the mechanics. We will define a &lt;code&gt;page&lt;/code&gt; object that holds the current URL, the results from the current page, and links to the pages before and after the current page:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;TUPLE:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;page&lt;/span&gt; &lt;span style="color: #19177C"&gt;url&lt;/span&gt; &lt;span style="color: #19177C"&gt;results&lt;/span&gt; &lt;span style="color: #19177C"&gt;before&lt;/span&gt; &lt;span style="color: #19177C"&gt;after&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can then build a word to fetch the page (as a JSON response), parse it, and construct a &lt;code&gt;page&lt;/code&gt; object:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;json-page&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;url&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;page&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&amp;gt;url&lt;span style="color: #008000"&gt; dup &lt;/span&gt;http-get&lt;span style="color: #008000"&gt; nip &lt;/span&gt;json&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; swap at &lt;/span&gt;{&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;children&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; swap at &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;parse-story&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;before&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; swap at &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;when-json-null&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;after&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; swap at &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #880000"&gt;f &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;when-json-null&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;}&lt;span style="color: #008000"&gt; cleave \ &lt;/span&gt;page&lt;span style="color: #008000"&gt; boa &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;An easy "paging" mechanism that, given a page of results, can return the next page:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;next-page&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;page&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;page&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;url&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;after&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;after&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;set-query-param&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;json-page&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;And, using the &lt;a href="http://docs.factorcode.org/content/article-namespaces-make.html"&gt;make&lt;/a&gt; vocabulary, construct all the results into a sequence:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;all-pages&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;page&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;results&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;results&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;,&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; dup &lt;/span&gt;after&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; bi &lt;/span&gt;]&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;next-page&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; while drop&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; &lt;/span&gt;make&lt;span style="color: #008000"&gt; concat &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Domain Stats&lt;/h2&gt;&lt;p&gt;We can retrieve all the results and produces a map of years that links were posted to a sum of the scores for each year's links:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;domain-stats&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;domain&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;stats&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;http://api.reddit.com/domain/%s&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;sprintf&lt;span style="color: #008000"&gt; &lt;/span&gt;json-page&lt;span style="color: #008000"&gt; &lt;/span&gt;all-pages&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;created&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;1000 * &lt;/span&gt;millis&amp;gt;timestamp&lt;span style="color: #008000"&gt; &lt;/span&gt;year&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;group-by&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;score&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; map-sum &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-map &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Finally, a word to display a chart of the scores across a given list of domains:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;domains.&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;domains&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;H{&lt;span style="color: #008000"&gt; &lt;/span&gt;}&lt;span style="color: #008000"&gt; clone &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;&amp;#39;[&lt;span style="color: #008000"&gt; &lt;/span&gt;domain-stats&lt;span style="color: #008000"&gt; &lt;/span&gt;[&lt;span style="color: #008000"&gt; swap &lt;/span&gt;_&lt;span style="color: #008000"&gt; &lt;/span&gt;at+&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; assoc-each &lt;/span&gt;]&lt;span style="color: #008000"&gt; each&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; keep &amp;gt;alist &lt;/span&gt;sort-keys&lt;span style="color: #008000"&gt; &lt;/span&gt;&amp;lt;bar&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #666666"&gt;160 &lt;/span&gt;&amp;gt;&amp;gt;height&lt;span style="color: #008000"&gt; &lt;/span&gt;chart.&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The code for this is available on my &lt;a href="https://github.com/mrjbq7/re-factor/blob/master/reddit/reddit.factor"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8513438391157777465-2742749323642390726?l=re-factor.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://re-factor.blogspot.com/feeds/2742749323642390726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8513438391157777465&amp;postID=2742749323642390726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2742749323642390726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8513438391157777465/posts/default/2742749323642390726'/><link rel='alternate' type='text/html' href='http://re-factor.blogspot.com/2011/05/reddit-stats.html' title='Reddit Stats'/><author><name>mrjbq7</name><uri>http://www.blogger.com/profile/06842721076008035602</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-xLwC1PPMlnI/TfL3qtTjptI/AAAAAAAAAKs/wff2BBuKyBw/s1600/ea4776c7b52421a55566eb2a23925c1e'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_J6Ti4lvPWak/Tb4XOEh7YNI/AAAAAAAAAI8/FQS2gIeHJyo/s72-c/blog-scores.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8513438391157777465.post-1428815548229758735</id><published>2011-04-20T09:22:00.000-07:00</published><updated>2011-04-20T09:22:24.682-07:00</updated><title type='text'>iPhone Backups</title><content type='html'>&lt;p&gt;A few weeks ago, I noticed a &lt;a href="https://github.com/timjuravich/relation-text"&gt;project&lt;/a&gt; on Github that extracts text messages from your iPhone and prints them out.  More specifically, it accesses the backups that iTunes makes and queries a &lt;a href="http://sqlite.org/"&gt;SQLite&lt;/a&gt; database to retrieve the messages.  We are going to build something similar using &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;First, some vocabularies we will be using:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;USING:&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;accessors&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;db&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;db.sqlite&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;db.tuples&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;db.types&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io.directories&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;io.files.info&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io.files.unique&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;io.pathnames&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;kernel&lt;/span&gt; &lt;span style="color: #0000FF; font-weight: bold"&gt;sequences&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000FF; font-weight: bold"&gt;sorting&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Database&lt;/h2&gt;&lt;p&gt;We will need a word to choose the most recently modified file in a directory:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;last-modified&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&amp;#39;&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;[&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;        &lt;/span&gt;[&lt;span style="color: #008000"&gt; &lt;/span&gt;file-info&lt;span style="color: #008000"&gt; &lt;/span&gt;modified&amp;gt;&amp;gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;sort-with&lt;span style="color: #008000"&gt; last&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;]&lt;span style="color: #008000"&gt; &lt;/span&gt;with-directory-files&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The iPhone backups are stored (on Mac OS X) in the &lt;code&gt;~/Library/Application Support/MobileSync/Backup&lt;/code&gt; directory.  We can choose the most recent backup:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;last-backup&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;home&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Library/Application Support/MobileSync/Backup&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;append-path&lt;span style="color: #008000"&gt; dup &lt;/span&gt;last-modified&lt;span style="color: #008000"&gt; &lt;/span&gt;append-path&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;The messages are stored in a SQLite database file with the name &lt;code&gt;3d0d7e5fb2ce288813306e4d4636395e047a3d28&lt;/code&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #008000; font-weight: bold"&gt;:&lt;/span&gt; &lt;span style="color: #0000FF"&gt;last-messages&lt;/span&gt;&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #0000FF"&gt;(&lt;/span&gt; &lt;span style="color: #0000FF"&gt;--&lt;/span&gt; &lt;span style="color: #19177C"&gt;path&lt;/span&gt; &lt;span style="color: #0000FF"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;    &lt;/span&gt;last-backup&lt;span style="color: #008000"&gt; &lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;3d0d7e5fb2ce288813306e4d4636395e047a3d28&amp;quot;&l
