<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pavel Fatin</title>
	<atom:link href="http://pavelfatin.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pavelfatin.com</link>
	<description>Blog about human and technology</description>
	<lastBuildDate>Mon, 30 Apr 2012 12:01:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Ninety-nine</title>
		<link>http://pavelfatin.com/ninety-nine/</link>
		<comments>http://pavelfatin.com/ninety-nine/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 10:25:22 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ninety-nine]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[solution]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=478</guid>
		<description><![CDATA[The famous Ninety-Nine Prolog problems (by Werner Hett) transcended their original purpose and became a popular set of exercises for languages other than Prolog. Solving these puzzles (and comparing your solutions with solutions of others) is a good way to “get a feel” for programing language and to explore idiomatic approaches to particular kind of [...]]]></description>
			<content:encoded><![CDATA[<p>The famous <a title="Prolog Problems - Prolog Site" href="https://sites.google.com/site/prologsite/prolog-problems">Ninety-Nine Prolog problems</a> (by Werner Hett) transcended their original purpose and became a popular set of exercises for languages other than <a title="Prolog - Wikipedia" href="http://en.wikipedia.org/wiki/Prolog">Prolog</a>.</p>
<p>Solving these puzzles (and comparing your solutions with solutions of others) is a good way to “get a feel” for programing language and to explore idiomatic approaches to particular kind of problems.</p>
<p>Today we can easily find solutions to the problems in almost any wide-spread programming language. However most of the attempts use a single programing language and provide only one solution to each problem.</p>
<p>By providing multiple types of solutions we can enrich our programming “toolbox” and learn pros and cons of various methods. By using several programming languages simultaneously we can easily correlate different programming paradigms and explore limits of language expressive power.</p>
<p>Here goes my take on Ninety-Nine Problems in:</p>
<ul>
<li><a title="Scala solutions - Ninety-Nine Problems" href="https://github.com/pavelfatin/ninety-nine/tree/master/scala">Scala</a>,</li>
<li><a title="Java solutions - Ninety-Nine Problems" href="https://github.com/pavelfatin/ninety-nine/tree/master/java">Java</a>,</li>
<li><a title="Clojure solutions - Ninety-Nine Problems" href="https://github.com/pavelfatin/ninety-nine/tree/master/clojure">Clojure</a>,</li>
<li><a title="Haskell solutions - Ninety-Nine Problems" href="https://github.com/pavelfatin/ninety-nine/tree/master/haskell">Haskell</a>.</li>
</ul>
<p>All the code is available as a <a title="pavelfatin/ninety-nine - GitHub" href="https://github.com/pavelfatin/ninety-nine">GitHub repository</a>.</p>
<p>See also: <a title="Scala for Project Euler" href="http://pavelfatin.com/scala-for-project-euler/">Scala for Project Euler</a>.</p>
<p><span id="more-478"></span></p>
<h3>Working with lists</h3>
<div id="problem-1" class="problem">
<div class="problem-title">Problem 1</div>
<p>(*) Find the last element of a list.</p>
<pre>
[1 2 3 7 5] -> 5
</pre>
<p><a title="Problem 1 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P01.scala">Scala</a> | <a title="Problem 1 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P01.java">Java</a> | <a title="Problem 1 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P01.clj">Clojure</a> | <a title="Problem 1 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p01.hs">Haskell</a>
</div>
<div id="problem-2" class="problem">
<div class="problem-title">Problem 2</div>
<p>(*) Find the last but one element of a list.</p>
<pre>
[1 2 3 7 5] -> 7
</pre>
<p><a title="Problem 2 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P02.scala">Scala</a> | <a title="Problem 2 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P02.java">Java</a> | <a title="Problem 2 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P02.clj">Clojure</a> | <a title="Problem 2 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p02.hs">Haskell</a>
</div>
<div id="problem-3" class="problem">
<div class="problem-title">Problem 3</div>
<p>(*) Find the K&#8217;th element of a list</p>
<p>The first element in the list is number 1.</p>
<pre>
[1 2 3 7 5] 4 -> 7
</pre>
<p><a title="Problem 3 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P03.scala">Scala</a> | <a title="Problem 3 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P03.java">Java</a> | <a title="Problem 3 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P03.clj">Clojure</a> | <a title="Problem 3 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p03.hs">Haskell</a>
</div>
<div id="problem-4" class="problem">
<div class="problem-title">Problem 4</div>
<p>(*) Find the number of elements of a list.</p>
<pre>
[1 2 3 5 7] -> 5
</pre>
<p><a title="Problem 4 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P04.scala">Scala</a> | <a title="Problem 4 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P04.java">Java</a> | <a title="Problem 4 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P04.clj">Clojure</a> | <a title="Problem 4 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p04.hs">Haskell</a>
</div>
<div id="problem-5" class="problem">
<div class="problem-title">Problem 5</div>
<p>(*) Reverse a list.</p>
<pre>
[1 2 3 7 5] -> [5 7 3 2 1]
</pre>
<p><a title="Problem 5 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P05.scala">Scala</a> | <a title="Problem 5 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P05.java">Java</a> | <a title="Problem 5 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P05.clj">Clojure</a> | <a title="Problem 5 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p05.hs">Haskell</a>
</div>
<div id="problem-6" class="problem">
<div class="problem-title">Problem 6</div>
<p>(*) Find out whether a list is a palindrome.</p>
<p>A palindrome can be read forward or backward.</p>
<pre>
[1 2 3 3 2 1] -> true
</pre>
<p><a title="Problem 6 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P06.scala">Scala</a> | <a title="Problem 6 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P06.java">Java</a> | <a title="Problem 6 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P06.clj">Clojure</a> | <a title="Problem 6 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p06.hs">Haskell</a>
</div>
<div id="problem-7" class="problem">
<div class="problem-title">Problem 7</div>
<p>(**) Flatten a nested list structure.</p>
<p>Transform a list, possibly holding lists as elements into a &#8216;flat&#8217; list by replacing each list with its elements (recursively).</p>
<pre>
[1 [2 3 [5 7] 3] 1] -> [1 2 3 5 7 3 1]
</pre>
<p><a title="Problem 7 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P07.scala">Scala</a> | <a title="Problem 7 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P07.java">Java</a> | <a title="Problem 7 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P07.clj">Clojure</a> | <a title="Problem 7 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p07.hs">Haskell</a>
</div>
<div id="problem-8" class="problem">
<div class="problem-title">Problem 8</div>
<p>(**) Eliminate consecutive duplicates of list elements.</p>
<p>If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.</p>
<pre>
[1 1 1 2 2 3 1 5 5 3 3] -> [1 2 3 1 5 3]
</pre>
<p><a title="Problem 8 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P08.scala">Scala</a> | <a title="Problem 8 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P08.java">Java</a> | <a title="Problem 8 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P08.clj">Clojure</a> | <a title="Problem 8 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p08.hs">Haskell</a>
</div>
<div id="problem-9" class="problem">
<div class="problem-title">Problem 9</div>
<p>(**) Pack consecutive duplicates of list elements into sublists.</p>
<p>If a list contains repeated elements they should be placed in separate sublists.</p>
<pre>
[1 1 1 2 2 3 1 5 5 3 3] -> [[1 1 1] [2 2] [3] [1] [5 5] [3 3]]
</pre>
<p><a title="Problem 9 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P09.scala">Scala</a> | <a title="Problem 9 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P09.java">Java</a> | <a title="Problem 9 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P09.clj">Clojure</a> | <a title="Problem 9 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p09.hs">Haskell</a>
</div>
<div id="problem-10" class="problem">
<div class="problem-title">Problem 10</div>
<p>(*) Run-length encoding of a list.</p>
<p>Use the result of <a title="Problem 9 - Ninety-Nine" href="#problem-9">problem 9</a> to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as terms (<var>N</var> <var>E</var>) where <var>N</var> is the number of duplicates of the element <var>E</var>.</p>
<pre>
[1 1 1 2 2 3 1 5 5 3 3] -> [(3 1) (2 2) (1 3) (1 1) (2 5) (2 3)]
</pre>
<p><a title="Problem 10 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P10.scala">Scala</a> | <a title="Problem 10 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P10.java">Java</a> | <a title="Problem 10 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P10.clj">Clojure</a> | <a title="Problem 10 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p10.hs">Haskell</a>
</div>
<div id="problem-11" class="problem">
<div class="problem-title">Problem 11</div>
<p>(*) Modified run-length encoding.</p>
<p>Modify the result of <a title="Problem 10 - Ninety-Nine" href="#problem-10">problem 10</a> in such a way that if an element has no duplicates it is simply copied into the result list. Only elements with duplicates are transferred as (<var>N</var> <var>E</var>) terms.</p>
<pre>
[1 1 1 2 2 3 1 5 5 3 3] -> [(3 1) (2 2) 3 1 (2 5) (2 3)]
</pre>
<p><a title="Problem 11 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P11.scala">Scala</a> | <a title="Problem 11 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P11.java">Java</a> | <a title="Problem 11 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P11.clj">Clojure</a> | <a title="Problem 11 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p11.hs">Haskell</a>
</div>
<div id="problem-12" class="problem">
<div class="problem-title">Problem 12</div>
<p>(**) Decode a run-length encoded list.</p>
<p>Given a run-length code list generated as specified in <a title="Problem 11 - Ninety-Nine" href="#problem-11">problem 11</a>. Construct its uncompressed version.</p>
<pre>
[(3 1) (2 2) 3 1 (2 5) (2 3)] -> [1 1 1 2 2 3 1 5 5 3 3]
</pre>
<p><a title="Problem 12 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P12.scala">Scala</a> | <a title="Problem 12 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P12.java">Java</a> | <a title="Problem 12 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P12.clj">Clojure</a> | <a title="Problem 12 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p12.hs">Haskell</a>
</div>
<div id="problem-13" class="problem">
<div class="problem-title">Problem 13</div>
<p>(**) Run-length encoding of a list (direct solution).</p>
<p>Implement the so-called run-length encoding data compression method directly. I.e. don&#8217;t explicitly create the sublists containing the duplicates, as in <a title="Problem 9 - Ninety-Nine" href="#problem-9">problem 9</a>, but only count them. As in <a title="Problem 11 - Ninety-Nine" href="#problem-11">problem 11</a>, simplify the result list by replacing the singleton terms (1 <var>X</var>) by <var>X</var>.</p>
<pre>
[1 1 1 2 2 3 1 5 5 3 3] -> [(3 1) (2 2) 3 1 (2 5) (2 3)]
</pre>
<p><a title="Problem 13 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P13.scala">Scala</a> | <a title="Problem 13 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P13.java">Java</a> | <a title="Problem 13 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P13.clj">Clojure</a> | <a title="Problem 13 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p13.hs">Haskell</a>
</div>
<div id="problem-14" class="problem">
<div class="problem-title">Problem 14</div>
<p>(*) Duplicate the elements of a list.</p>
<pre>
[1 2 3 1] -> [1 1 2 2 3 3 1 1]
</pre>
<p><a title="Problem 14 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P14.scala">Scala</a> | <a title="Problem 14 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P14.java">Java</a> | <a title="Problem 14 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P14.clj">Clojure</a> | <a title="Problem 14 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p14.hs">Haskell</a>
</div>
<div id="problem-15" class="problem">
<div class="problem-title">Problem 15</div>
<p>(*) Replicate the elements of a list a given number of times.</p>
<pre>
[1 2 3 1] 3 -> [1 1 1 2 2 2 3 3 3 1 1 1]
</pre>
<p><a title="Problem 15 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P15.scala">Scala</a> | <a title="Problem 15 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P15.java">Java</a> | <a title="Problem 15 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P15.clj">Clojure</a> | <a title="Problem 15 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p15.hs">Haskell</a>
</div>
<div id="problem-16" class="problem">
<div class="problem-title">Problem 16</div>
<p>(**) Drop every <var>N</var>&#8216;th element from a list.</p>
<pre>
[1 2 3 4 5 6 7 8] 3 -> [1 2 4 5 7 8]
</pre>
<p><a title="Problem 16 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P16.scala">Scala</a> | <a title="Problem 16 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P16.java">Java</a> | <a title="Problem 16 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P16.clj">Clojure</a> | <a title="Problem 16 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p16.hs">Haskell</a>
</div>
<div id="problem-17" class="problem">
<div class="problem-title">Problem 17</div>
<p>(*) Split a list into two parts; the length of the first part is given.</p>
<p>Do not use any predefined predicates.</p>
<pre>
[1 2 3 4 5 6 7 8] 3 -> ([1 2 3] [4 5 6 7 8])
</pre>
<p><a title="Problem 17 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P17.scala">Scala</a> | <a title="Problem 17 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P17.java">Java</a> | <a title="Problem 17 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P17.clj">Clojure</a> | <a title="Problem 17 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p17.hs">Haskell</a>
</div>
<div id="problem-18" class="problem">
<div class="problem-title">Problem 18</div>
<p>(**) Extract a slice from a list.</p>
<p>Given two indices, I and K, the slice is the list containing the elements between the <var>I</var>&#8216;th and <var>K</var>&#8216;th element of the original list (both limits included). Start counting the elements with 1.</p>
<pre>
[1 2 3 4 5 6 7 8] 3 7 -> [3 4 5 6 7]
</pre>
<p><a title="Problem 18 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P18.scala">Scala</a> | <a title="Problem 18 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P18.java">Java</a> | <a title="Problem 18 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P18.clj">Clojure</a> | <a title="Problem 18 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p18.hs">Haskell</a>
</div>
<div id="problem-19" class="problem">
<div class="problem-title">Problem 19</div>
<p>(**) Rotate a list <var>N</var> places to the left.</p>
<pre>
[1 2 3 4 5 6 7 8] 3 -> [3 4 5 6 7 8 1 2 3]
</pre>
<p><a title="Problem 19 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P19.scala">Scala</a> | <a title="Problem 19 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P19.java">Java</a> | <a title="Problem 19 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P19.clj">Clojure</a> | <a title="Problem 19 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p19.hs">Haskell</a>
</div>
<div id="problem-20" class="problem">
<div class="problem-title">Problem 20</div>
<p>(*) Remove the <var>K</var>&#8216;th element from a list.</p>
<pre>
[1 2 3 4] 2 -> (2, [1 3 4])
</pre>
<p><a title="Problem 20 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P20.scala">Scala</a> | <a title="Problem 20 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P20.java">Java</a> | <a title="Problem 20 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P20.clj">Clojure</a> | <a title="Problem 20 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p20.hs">Haskell</a>
</div>
<div id="problem-21" class="problem">
<div class="problem-title">Problem 21</div>
<p>(*) Insert an element at a given position into a list.</p>
<pre>
[1 2 3 4] 2 5 -> [1 5 2 3 4]
</pre>
<p><a title="Problem 21 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P21.scala">Scala</a> | <a title="Problem 21 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P21.java">Java</a> | <a title="Problem 21 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P21.clj">Clojure</a> | <a title="Problem 21 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p21.hs">Haskell</a>
</div>
<div id="problem-22" class="problem">
<div class="problem-title">Problem 22</div>
<p>(*) Create a list containing all integers within a given range.</p>
<pre>
4 9 -> [1 2 3 4 5 6 7 8 9]
</pre>
<p><a title="Problem 22 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P22.scala">Scala</a> | <a title="Problem 22 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P22.java">Java</a> | <a title="Problem 22 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P22.clj">Clojure</a> | <a title="Problem 22 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p22.hs">Haskell</a>
</div>
<div id="problem-23" class="problem">
<div class="problem-title">Problem 23</div>
<p>(**) Extract a given number of randomly selected elements from a list.</p>
<pre>
[1 2 3 4 5 6 7 8] 3 -> [7 3 5]
</pre>
<p><a title="Problem 23 - Scala solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/scala/P23.scala">Scala</a> | <a title="Problem 23 - Java solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/java/P23.java">Java</a> | <a title="Problem 23 - Clojure solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/clojure/P23.clj">Clojure</a> | <a title="Problem 23 - Haskell solutions" href="https://github.com/pavelfatin/ninety-nine/blob/master/haskell/p23.hs">Haskell</a>
</div>
<p>To be continued&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/ninety-nine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ToyIDE is released</title>
		<link>http://pavelfatin.com/toyide-is-released/</link>
		<comments>http://pavelfatin.com/toyide-is-released/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 08:45:30 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[autocompletion]]></category>
		<category><![CDATA[bytecode]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[formatting]]></category>
		<category><![CDATA[highlighting]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[toy language]]></category>
		<category><![CDATA[toyide]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=461</guid>
		<description><![CDATA[ToyIDE is an imitation of a full-featured IDE plus a toy language with an interpreter and a compiler. All the parts were built from scratch in Scala, without relying on any existing code or libraries. The project is purely educational. It is a product of a long vacation in the country and a desire to [...]]]></description>
			<content:encoded><![CDATA[<p><a title="ToyIDE" href="http://pavelfatin.com/toyide/">ToyIDE</a> is an imitation of a full-featured IDE plus a <a title="Toy language - Wikipedia" href="http://en.wikipedia.org/wiki/Toy_language">toy language</a> with an interpreter and a compiler. All the parts were built from scratch in <a title="The Scala Programming Language" href="http://www.scala-lang.org/">Scala</a>, without relying on any existing code or libraries.</p>
<p>The project is purely educational. It is a product of a long vacation in the country and a desire to learn how all this stuff really works.</p>
<p>I learned a lot from the project and hope it might be useful to the people who want to know more about <a title="Lexical analysis - Wikipedia" href="http://en.wikipedia.org/wiki/Lexical_analysis">lexers</a>, <a title="Parsing - Wikipedia" href="http://en.wikipedia.org/wiki/Parsing">parsers</a>, <a title="Abstract syntax tree - Wikipedia" href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a>, <a title="Java bytecode - Wikipedia" href="http://en.wikipedia.org/wiki/Java_bytecode">Java bytecode</a> and other similar fun, but tricky things.</p>
<p>Feature list, screenshots, binaries and the source code are available on the <a title="ToyIDE" href="http://pavelfatin.com/toyide/">project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/toyide-is-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scalathon</title>
		<link>http://pavelfatin.com/scalathon/</link>
		<comments>http://pavelfatin.com/scalathon/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 07:15:21 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[scalathon]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=456</guid>
		<description><![CDATA[As a part of JetBrains Scala team I had a chance to visit Scalathon 2011 to represent our project – Scala plugin for IntelliJ IDEA. An initial projector malfunction made me a little bit nervous about speaking without my thoroughly prepared slides, however, everything was resolved and my presentation seemed to went fine. In addition [...]]]></description>
			<content:encoded><![CDATA[<p>As a part of <a title="JetBrains - World's leading vendor of professional development tools" href="http://www.jetbrains.com/">JetBrains</a> Scala team I had a chance to visit <a title="Scalathon 2011 - The international Scala hackathon" href="http://scalathon.org/">Scalathon 2011</a> to represent our project – <a title="Scala Plugin for IntelliJ IDEA" href="http://confluence.jetbrains.net/display/SCA/Scala+Plugin+for+IntelliJ+IDEA">Scala plugin for IntelliJ IDEA</a>. </p>
<p>An initial projector malfunction made me a little bit nervous about speaking without my thoroughly prepared slides, however, everything was resolved and my presentation seemed to went fine.</p>
<p>In addition to <a title="Scalathon videos" href="http://scalathon.org/videos.html">project presentations</a> we had two days for hacking Scala code. It was a pleasure to see so many projects and so much involvement. These people are really passionate about what they do!</p>
<p>As turned out (surprise), many programmers were using IDEA with the Scala plugin as their primary development environment. Usually I encounter only “virtual” plugin users, but there I had a chance to provide a truly personal support. I was both proud of our work and ashamed of whatever bug it may have <img src='http://pavelfatin.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Right before the Scalathon I had been evaluating <a title="ScalaCL compiler plugin" href="http://code.google.com/p/scalacl/wiki/ScalaCLPlugin">ScalaCL compiler plugin</a> for use in our project, so I was really glad to meet <a title="ochafik.com - Olivier Chafik" href="http://ochafik.com/blog/">Olivier Chafik</a> there in person. Our talk shed light on many tricky parts of ScalaCL implementation.</p>
<p>Being among all those people form mailing lists, tweets, blogs, forums and even books makes you feel a part of community (and Scala community is an amazing community to be part of).  I would like to thank all the organizers for their great work!</p>
<p>Here are some <a title="Scalathon 2011 photos (Dropbox)" href="http://www.dropbox.com/gallery/50907173/1/scalathon?h=f38f4e">photos of the Philadelphia, Scalathon, ENIAC and me</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/scalathon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SleepArchiver is open sourced</title>
		<link>http://pavelfatin.com/sleeparchiver-is-open-sourced/</link>
		<comments>http://pavelfatin.com/sleeparchiver-is-open-sourced/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 14:53:38 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[gpl]]></category>
		<category><![CDATA[license]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[sleeparchiver]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=254</guid>
		<description><![CDATA[While I am currently working hard on Scala plugin for IntelliJ IDEA at JetBrains, I have no time to continue development on SleepArchiver. However, there are still many useful features that could be implemented, so I decided to open source SleepArchiver and put the project on SourceForge under GPLv3 license. SleepArchiver at SourceForge.net: Project Source [...]]]></description>
			<content:encoded><![CDATA[<p>While I am currently working hard on <a title="Scala plugin for IntelliJ IDEA" href="http://confluence.jetbrains.net/display/SCA/Scala+Plugin+for+IntelliJ+IDEA">Scala plugin</a> for IntelliJ IDEA at <a title="JetBrains - world’s leading vendor of professional development tools" href="http://www.jetbrains.com/">JetBrains</a>, I have no time to continue development on <a title="SleepArchiver - cross-platform data manager for Sleeptracker watches" href="http://pavelfatin.com/sleeparchiver/">SleepArchiver</a>. However, there are still many useful features that could be implemented, so I decided to open source SleepArchiver and put the project on <a title="SourceForge.net" href="http://sourceforge.net">SourceForge</a> under <a title="GNU General Public License version 3" href="http://www.gnu.org/licenses/gpl.html">GPLv3</a> license.<span id="more-254"></span></p>
<p>SleepArchiver at SourceForge.net:</p>
<ul>
<li><a title="SleepArchiver at SourceForge.net" href="http://sourceforge.net/projects/sleeparchiver/">Project</a></li>
<li><a title="SleepArchiver source code" href="http://sourceforge.net/scm/?type=git&#038;group_id=506842">Source code</a> (<a title="pavelfatin/sleeparchiver - GitHub" href="https://github.com/pavelfatin/sleeparchiver">GitHub mirror</a>)</li>
<li><a title="SleepArchiver bug tracker" href="http://sourceforge.net/tracker/?group_id=506842&#038;atid=2060932">Bug tracker</a></li>
<li><a title="SleepArchiver feature requests" href="http://sourceforge.net/tracker/?group_id=506842&#038;atid=2060935">Feature requests</a></li>
<li><a title="SleepArchiver forum" href="http://sourceforge.net/projects/sleeparchiver/forums/forum/1674560">Forum</a></li>
</ul>
<p>A list of features yet to be implemented:</p>
<ul>
<li>Translate GUI to other languages</li>
<li>Create .deb software package for Ubuntu</li>
<li>Create .dmg image for Mac OS X</li>
<li>Implement data analysis</li>
<li>Add an ability to import data from Sleeptracker bundled software</li>
<li>Write good documentation</li>
<li>&#8230;your most wanted feature <img style="border: none;" alt="Smile" width="15" height="15" src="/wp-includes/images/smilies/icon_smile.gif"/></li>
</ul>
<p>Everyone is welcome to contribute by becoming a developer and <a title="Join SleepArchiver project" href="http://sourceforge.net/projects/sleeparchiver/develop">join the project</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/sleeparchiver-is-open-sourced/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala for Project Euler</title>
		<link>http://pavelfatin.com/scala-for-project-euler/</link>
		<comments>http://pavelfatin.com/scala-for-project-euler/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 19:25:31 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[project euler]]></category>
		<category><![CDATA[puzzle]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[solution]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=177</guid>
		<description><![CDATA[Project Euler is a collection of interesting computational problems intended to be solved with computer programs. Most of the problems challenge your skills in algorithm design rather than your knowledge of mathematics. Thanks to short concrete problems and number-only solutions you don&#8217;t have to thinker with IDEs, GUI designers, programming libraries and frameworks, so Project [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://projecteuler.net/" title="Project Euler">Project Euler</a> is a collection of interesting computational problems intended to be solved with computer programs. Most of the problems challenge your skills in <a href="http://en.wikipedia.org/wiki/Algorithm_design" title="Algorithm design - Wikipedia">algorithm design</a> rather than your knowledge of mathematics.</p>
<p>Thanks to short concrete problems and number-only solutions you don&#8217;t have to thinker with IDEs, GUI designers, programming libraries and frameworks, so Project Euler is an excellent tool for learning a new programming language or improving your core programming skills.<br />
<span id="more-177"></span></p>
<h3>Why use Scala</h3>
<p>Although all general-purpose programming languages are <a href="http://en.wikipedia.org/wiki/Turing_completeness" title="Turing-completeness - Wikipedia">Turing-complete</a> and thus suitable for Project Euler, each language has its own philosophy and set of tools. In spite of programming language &#8220;holy wars&#8221;, the truth is that different tasks demand different tools.</p>
<p>Since Scala is a <a href="http://en.wikipedia.org/wiki/Multi-paradigm_programming_language#Multi-paradigm_programming_language" title="Multi-paradigm programming language - Wikipedia">multi-paradigm</a> programming language, it allows programmers to efficiently express a wide range of common programming patterns. Most Project Euler problems imply advanced transformation of numeric or symbolic data and Scala&#8217;s <a href="http://en.wikipedia.org/wiki/Functional_programming" title="Functional Programming - Wikipedia">functional programming</a> features are the perfect tool for that purpose (moreover, unlike pure functional languages, being a hybrid language, Scala provides <a href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming - Wikipedia">object-oriented</a> capabilities when modeling or simulation is required).</p>
<p>So, what does Scala have to offer for Project Euler? Here is the list of most valuable features:</p>
<ul>
<li>scripting,</li>
<li>type-inference,</li>
<li>first-class functions,</li>
<li>tail call optimization,</li>
<li>lazy evaluation,</li>
<li>excellent collection library,</li>
<li>sequence comprehensions.</li>
</ul>
<p>On the top of everything else, Scala brings enjoyment to your coding. According to <a href="http://therighttool.hammerprinciple.com/" title="The Right Tool - Programming Languages: What tool is right for which job?">The Right Tool</a> Scala is <a href="http://therighttool.hammerprinciple.com/items/scala" title="Scala ranking - The Right Tool">ranked</a> high in the following categories:</p>
<ul>
<li><a href="http://therighttool.hammerprinciple.com/statements/i-enjoy-using-this-language" title='"I enjoy using this language" - The Right Tool'>I enjoy using this language</a> (2/50)</li>
<li><a href="http://therighttool.hammerprinciple.com/statements/i-use-this-language-out-of-choice" title='"I use this language out of choice" - The Right Tool'>I use this language out of choice</a> (1/50)</li>
<li><a href="http://therighttool.hammerprinciple.com/statements/this-language-is-expressive" title='"This language is expressive" - The Right Tool'>This language is expressive</a> (3/50)</li>
<li><a href="http://therighttool.hammerprinciple.com/statements/i-find-code-written-in-this-language-very-elegant" title='"I find code written in this language very elegant" - The Right Tool'>I find code written in this language very elegant</a> (2/50)</li>
</ul>
<p>Thus Scala is the right tool for those who want to mingle the useful with the pleasant.</p>
<h3>Sample solutions</h3>
<p>This section contains solutions to the first 33 problems. You may use them either to size up how well Scala plays in Project Euler, or to compare your own solutions with the samples.</p>
<p>All the code is available as a <a title="pavelfatin/projecteuler - GitHub" href="https://github.com/pavelfatin/projecteuler">GitHub repository</a>.</p>
<p>See also: <a title="Ninety-Nine Problems in Scala, Java, Clojure and Haskell" href="http://pavelfatin.com/ninety-nine/">Ninety-Nine Problems in Scala, Java, Clojure and Haskell</a>.<br />
&nbsp;<br />

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 1</div>
		<div class="problem-description">Add all the natural numbers below one thousand that are multiples of 3 or 5.<a href="http://projecteuler.net/index.php?section=problems&id=1">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = (<span class="scala-number">1</span> until <span class="scala-number">1000</span>).view.filter(n =&gt; n % <span class="scala-number">3</span> == <span class="scala-number">0</span> || n % <span class="scala-number">5</span> == <span class="scala-number">0</span>).sum

assert(r == <span class="scala-number">233168</span>) <span class="scala-comment">// 7 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 2</div>
		<div class="problem-description">Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed four million.<a href="http://projecteuler.net/index.php?section=problems&id=2">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> fs: Stream[Int] = 
  <span class="scala-number">0</span> #:: <span class="scala-number">1</span> #:: fs.zip(fs.tail).map(p =&gt; p._1 + p._2)

<span class="scala-keyword">val</span> r = fs.view.takeWhile(_ &lt;= <span class="scala-number">4000000</span>).filter(_ % <span class="scala-number">2</span> == <span class="scala-number">0</span>).sum

assert(r == <span class="scala-number">4613732</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 3</div>
		<div class="problem-description">Find the largest prime factor of a composite number.<a href="http://projecteuler.net/index.php?section=problems&id=3">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> ps: Stream[Int] = <span class="scala-number">2</span> #:: Stream.from(<span class="scala-number">3</span>).filter(i =&gt;
  ps.takeWhile(j =&gt; j * j &lt;= i).forall(i % _ &gt; <span class="scala-number">0</span>))

<span class="scala-keyword">val</span> n = <span class="scala-number">600851475143L</span>

<span class="scala-keyword">val</span> limit = math.sqrt(n)

<span class="scala-keyword">val</span> r = ps.view.takeWhile(_ &lt; limit).filter(n % _ == <span class="scala-number">0</span>).last

assert(r == <span class="scala-number">6857</span>) <span class="scala-comment">// 265 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 4</div>
		<div class="problem-description">Find the largest palindrome made from the product of two 3-digit numbers.<a href="http://projecteuler.net/index.php?section=problems&id=4">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = (<span class="scala-number">100</span> to <span class="scala-number">999</span>).view
        .flatMap(i =&gt; (i to <span class="scala-number">999</span>).map(i *))
        .filter(n =&gt; n.toString == n.toString.reverse)
        .max

assert(r == <span class="scala-number">906609</span>) <span class="scala-comment">// 102 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 5</div>
		<div class="problem-description">What is the smallest number divisible by each of the numbers 1 to 20?<a href="http://projecteuler.net/index.php?section=problems&id=5">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = Range(<span class="scala-number">20</span>, Int.MaxValue)
        .find(n =&gt; Range(<span class="scala-number">2</span>, <span class="scala-number">21</span>).forall(n % _ == <span class="scala-number">0</span>)).get

assert(r == <span class="scala-number">232792560</span>) <span class="scala-comment">// 23 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 6</div>
		<div class="problem-description">What is the difference between the sum of the squares and the square of the sums?<a href="http://projecteuler.net/index.php?section=problems&id=6">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> numbers = <span class="scala-number">1</span> to <span class="scala-number">100</span>

<span class="scala-keyword">def</span> square(n: Int) = n * n

<span class="scala-keyword">val</span> r = square(numbers.sum) - numbers.map(square).sum

assert(r == <span class="scala-number">25164150</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 7</div>
		<div class="problem-description">Find the 10001<sup>st</sup> prime.<a href="http://projecteuler.net/index.php?section=problems&id=7">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> ps: Stream[Int] = <span class="scala-number">2</span> #:: Stream.from(<span class="scala-number">3</span>).filter(i =&gt;
  ps.takeWhile(j =&gt; j * j &lt;= i).forall(i % _ &gt; <span class="scala-number">0</span>))

<span class="scala-keyword">val</span> r = ps(<span class="scala-number">10000</span>)

assert(r == <span class="scala-number">104743</span>) <span class="scala-comment">// 24 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 8</div>
		<div class="problem-description">Discover the largest product of five consecutive digits in the 1000-digit number.<a href="http://projecteuler.net/index.php?section=problems&id=8">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> s = <span class="scala-string">"""&lt;raw input data&gt;"""</span>

<span class="scala-keyword">val</span> r = s.filter(_.isDigit).map(_.asDigit).sliding(<span class="scala-number">5</span>)
        .map(_.product).max

assert(r == <span class="scala-number">40824</span>) <span class="scala-comment">// 33 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 9</div>
		<div class="problem-description">Find the only Pythagorean triplet, {<var>a</var>, <var>b</var>, <var>c</var>}, for which <var>a</var> + <var>b</var> + <var>c</var> = 1000.<a href="http://projecteuler.net/index.php?section=problems&id=9">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> limit = (<span class="scala-number">1</span> to <span class="scala-number">1000</span>).find(n =&gt; n + math.sqrt(n) &gt;= <span class="scala-number">1000</span>).get

<span class="scala-keyword">val</span> rs = <span class="scala-keyword">for</span>(b &lt;- <span class="scala-number">2</span> until limit; a &lt;- <span class="scala-number">1</span> until b; c = <span class="scala-number">1000</span> - a - b
             <span class="scala-keyword">if</span> a * a + b * b  == c * c) <span class="scala-keyword">yield</span> a * b * c

<span class="scala-keyword">val</span> r = rs(<span class="scala-number">0</span>)

assert(r == <span class="scala-number">31875000</span>) <span class="scala-comment">// 32 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 10</div>
		<div class="problem-description">Calculate the sum of all the primes below two million.<a href="http://projecteuler.net/index.php?section=problems&id=10">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> ps: Stream[Int] = <span class="scala-number">2</span> #:: Stream.from(<span class="scala-number">3</span>).filter(i =&gt;
  ps.takeWhile(j =&gt; j * j &lt;= i).forall(i % _ &gt; <span class="scala-number">0</span>))

<span class="scala-keyword">val</span> r = ps.view.takeWhile(_ &lt; <span class="scala-number">2000000</span>).foldLeft(<span class="scala-number">0L</span>)(_ + _)

assert(r == <span class="scala-number">142913828922L</span>) <span class="scala-comment">// 1 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 11</div>
		<div class="problem-description">What is the greatest product of four numbers on the same straight line in the 20 by 20 grid?<a href="http://projecteuler.net/index.php?section=problems&id=11">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> s = <span class="scala-string">"""&lt;raw input data&gt;"""</span>

<span class="scala-keyword">val</span> ns = s.split(<span class="scala-string">"<span class="scala-escape">\\</span>s+"</span>).map(_.toInt)

<span class="scala-keyword">def</span> m(i: Int, p: Int, c: Int): Int =
  <span class="scala-keyword">if</span>(c &gt; <span class="scala-number">0</span>) ns(i) * m(i + p, p, c - <span class="scala-number">1</span>) <span class="scala-keyword">else</span> <span class="scala-number">1</span>

<span class="scala-keyword">def</span> ms(xs: Seq[Int], ys: Seq[Int], p: Int) =
  ys.flatMap(y =&gt; xs.map(x =&gt; m(<span class="scala-number">20</span> * y + x, p, <span class="scala-number">4</span>)))

<span class="scala-keyword">val</span> ps = ms(<span class="scala-number">0</span> to <span class="scala-number">19</span>, <span class="scala-number">0</span> to <span class="scala-number">15</span>, <span class="scala-number">20</span>) ++ ms(<span class="scala-number">0</span> to <span class="scala-number">15</span>, <span class="scala-number">0</span> to <span class="scala-number">19</span>, <span class="scala-number">1</span>) ++ 
         ms(<span class="scala-number">0</span> to <span class="scala-number">15</span>, <span class="scala-number">0</span> to <span class="scala-number">15</span>, <span class="scala-number">21</span>) ++ ms(<span class="scala-number">3</span> to <span class="scala-number">19</span>, <span class="scala-number">0</span> to <span class="scala-number">15</span>, <span class="scala-number">19</span>)

<span class="scala-keyword">val</span> r = ps.max

assert(r == <span class="scala-number">70600674</span>) <span class="scala-comment">// 4 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 12</div>
		<div class="problem-description">What is the value of the first triangle number to have over five hundred divisors?<a href="http://projecteuler.net/index.php?section=problems&id=12">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> ts: Stream[Int] = 
  <span class="scala-number">0</span> #:: ts.zipWithIndex.map(p =&gt; p._1 + p._2 + <span class="scala-number">1</span>)

<span class="scala-keyword">def</span> p(t: Int) = Range(<span class="scala-number">1</span>, Int.MaxValue)
                .takeWhile(n =&gt; n * n &lt;= t)
                .foldLeft(<span class="scala-number">0</span>)((s, n) =&gt; <span class="scala-keyword">if</span>(t % n == <span class="scala-number">0</span>) s + <span class="scala-number">2</span> <span class="scala-keyword">else</span> s)

<span class="scala-keyword">val</span> r = ts.find(p(_) &gt; <span class="scala-number">500</span>).get

assert(r == <span class="scala-number">76576500</span>) <span class="scala-comment">// 1 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 13</div>
		<div class="problem-description">Find the first ten digits of the sum of one-hundred 50-digit numbers.<a href="http://projecteuler.net/index.php?section=problems&id=13">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> s = <span class="scala-string">"""&lt;raw input data"""</span>

<span class="scala-keyword">val</span> r = s.split(<span class="scala-string">"<span class="scala-escape">\\</span>s+"</span>).map(_.take(<span class="scala-number">11</span>).toLong).sum.toString
        .take(<span class="scala-number">10</span>).toLong

assert(r == <span class="scala-number">5537376230L</span>) <span class="scala-comment">// 2 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 14</div>
		<div class="problem-description">Find the longest sequence using a starting number under one million.<a href="http://projecteuler.net/index.php?section=problems&id=14">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> from(n: Long, c: Int = <span class="scala-number">0</span>): Int = <span class="scala-keyword">if</span>(n == <span class="scala-number">1</span>) c + <span class="scala-number">1</span> <span class="scala-keyword">else</span> 
  from(<span class="scala-keyword">if</span>(n % <span class="scala-number">2</span> == <span class="scala-number">0</span>) n / <span class="scala-number">2</span> <span class="scala-keyword">else</span> <span class="scala-number">3</span> * n + <span class="scala-number">1</span>, c + <span class="scala-number">1</span>)

<span class="scala-keyword">val</span> r = (<span class="scala-number">1</span> until <span class="scala-number">1000000</span>).view.map(n =&gt; (n, from(n)))
  .reduceLeft((a, b) =&gt; <span class="scala-keyword">if</span>(a._2 &gt; b._2) a <span class="scala-keyword">else</span> b)._1

assert(r == <span class="scala-number">837799</span>) <span class="scala-comment">// 1 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 15</div>
		<div class="problem-description">Starting in the top left corner in a 20 by 20 grid, how many routes are there to the bottom right corner?<a href="http://projecteuler.net/index.php?section=problems&id=15">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> f(row: Seq[Long], c: Int): Long = {
  <span class="scala-keyword">var</span> s = <span class="scala-number">0L</span>
  <span class="scala-keyword">val</span> next = row.map { n =&gt; s += n; s }
  <span class="scala-keyword">if</span>(c == <span class="scala-number">0</span>) next.last <span class="scala-keyword">else</span> f(next, c - <span class="scala-number">1</span>)
}

<span class="scala-keyword">def</span> r(n: Int) = f(List.fill(n + <span class="scala-number">1</span>)(<span class="scala-number">1L</span>), n - <span class="scala-number">1</span>)

assert(r(<span class="scala-number">20</span>) == <span class="scala-number">137846528820L</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 16</div>
		<div class="problem-description">What is the sum of the digits of the number 2<sup>1000</sup>?<a href="http://projecteuler.net/index.php?section=problems&id=16">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = BigInt(<span class="scala-number">2</span>).pow(<span class="scala-number">1000</span>).toString.view.map(_.asDigit).sum

assert(r == <span class="scala-number">1366</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 17</div>
		<div class="problem-description">How many letters would be needed to write all the numbers in words from 1 to 1000?<a href="http://projecteuler.net/index.php?section=problems&id=17">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> units = Array(<span class="scala-number">0</span>, <span class="scala-number">3</span>, <span class="scala-number">3</span>, <span class="scala-number">5</span>, <span class="scala-number">4</span>, <span class="scala-number">4</span>, <span class="scala-number">3</span>, <span class="scala-number">5</span>, <span class="scala-number">5</span>, <span class="scala-number">4</span>, <span class="scala-number">3</span>, <span class="scala-number">6</span>, <span class="scala-number">6</span>, <span class="scala-number">8</span>, <span class="scala-number">8</span>, <span class="scala-number">7</span>, 
                  <span class="scala-number">7</span>, <span class="scala-number">9</span>, <span class="scala-number">8</span>, <span class="scala-number">8</span>)

<span class="scala-keyword">val</span> tens = Array(<span class="scala-number">0</span>, <span class="scala-number">0</span>, <span class="scala-number">6</span>, <span class="scala-number">6</span>, <span class="scala-number">5</span>, <span class="scala-number">5</span>, <span class="scala-number">5</span>, <span class="scala-number">7</span>, <span class="scala-number">6</span>, <span class="scala-number">6</span>)    

<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> name: Int =&gt; Int = {
  <span class="scala-keyword">case</span> n <span class="scala-keyword">if</span>(n &lt; <span class="scala-number">20</span>) =&gt; units(n)
  <span class="scala-keyword">case</span> n <span class="scala-keyword">if</span>(n &lt; <span class="scala-number">100</span>) =&gt; 
    tens(n / <span class="scala-number">10</span>) + (<span class="scala-keyword">if</span>(n % <span class="scala-number">10</span> &gt; <span class="scala-number">0</span>) units(n % <span class="scala-number">10</span>) <span class="scala-keyword">else</span> <span class="scala-number">0</span>)
  <span class="scala-keyword">case</span> n <span class="scala-keyword">if</span>(n &lt; <span class="scala-number">1000</span>) =&gt; 
    name(n / <span class="scala-number">100</span>) + <span class="scala-number">7</span> + (<span class="scala-keyword">if</span>(n % <span class="scala-number">100</span> &gt; <span class="scala-number">0</span>) <span class="scala-number">3</span> + name(n % <span class="scala-number">100</span>) <span class="scala-keyword">else</span> <span class="scala-number">0</span>)
  <span class="scala-keyword">case</span> <span class="scala-number">1000</span> =&gt; <span class="scala-number">11</span>
}

<span class="scala-keyword">val</span> r = (<span class="scala-number">1</span> to <span class="scala-number">1000</span>).map(name).sum

assert(r == <span class="scala-number">21124</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 18</div>
		<div class="problem-description">Find the maximum sum travelling from the top of the triangle to the base.<a href="http://projecteuler.net/index.php?section=problems&id=18">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> s = <span class="scala-string">"""&lt;raw input data"""</span>

<span class="scala-keyword">val</span> grid = s.trim.split(<span class="scala-string">"<span class="scala-escape">\n</span>"</span>).map(_.split(<span class="scala-string">"<span class="scala-escape">\\</span>s+"</span>).map(_.toInt))

<span class="scala-keyword">def</span> f(rows: Array[Array[Int]], bottom:Seq[Int]): Int = {
  <span class="scala-keyword">val</span> ms = bottom.zip(bottom.tail).map(p =&gt; p._1 max p._2)
  <span class="scala-keyword">val</span> ss = rows.last.zip(ms).map(p =&gt; p._1 + p._2)
  <span class="scala-keyword">if</span>(ss.size == <span class="scala-number">1</span>) ss.head <span class="scala-keyword">else</span> f(rows.init, ss)
}

<span class="scala-keyword">val</span> r = f(grid.init, grid.last)

assert(r == <span class="scala-number">1074</span>) <span class="scala-comment">// 2 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 19</div>
		<div class="problem-description">How many Sundays fell on the first of the month during the twentieth century?<a href="http://projecteuler.net/index.php?section=problems&id=19">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> lengths = Array(<span class="scala-number">31</span>, <span class="scala-number">0</span>, <span class="scala-number">31</span>, <span class="scala-number">30</span>, <span class="scala-number">31</span>, <span class="scala-number">30</span>, <span class="scala-number">31</span>, <span class="scala-number">31</span>, <span class="scala-number">30</span>, <span class="scala-number">31</span>, <span class="scala-number">31</span>, <span class="scala-number">31</span>)

<span class="scala-keyword">val</span> ls = <span class="scala-keyword">for</span>(y &lt;- <span class="scala-number">1900</span> to <span class="scala-number">2000</span>; m &lt;- <span class="scala-number">1</span> to <span class="scala-number">12</span>) <span class="scala-keyword">yield</span>
  <span class="scala-keyword">if</span>(m == <span class="scala-number">2</span>)
    <span class="scala-keyword">if</span> (<span class="scala-keyword">if</span> (y % <span class="scala-number">100</span> == <span class="scala-number">0</span>) y % <span class="scala-number">400</span> == <span class="scala-number">0</span> <span class="scala-keyword">else</span> y % <span class="scala-number">4</span> == <span class="scala-number">0</span>) <span class="scala-number">29</span> <span class="scala-keyword">else</span> <span class="scala-number">28</span> 
  <span class="scala-keyword">else</span> 
    lengths(m - <span class="scala-number">1</span>)

<span class="scala-keyword">val</span> fs = ls.foldLeft(List(<span class="scala-number">1</span>))((ws, l) =&gt; ((ws.head + l) % <span class="scala-number">7</span>) :: ws)

<span class="scala-keyword">val</span> r = fs.count(_ == <span class="scala-number">0</span>)

assert(r == <span class="scala-number">171</span>) <span class="scala-comment">// 2 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 20</div>
		<div class="problem-description">Find the sum of digits in 100!<a href="http://projecteuler.net/index.php?section=problems&id=20">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> f(n: BigInt): BigInt = <span class="scala-keyword">if</span>(n &lt; <span class="scala-number">2</span>) <span class="scala-number">1</span> <span class="scala-keyword">else</span> n * f(n - <span class="scala-number">1</span>)

<span class="scala-keyword">val</span> r = f(<span class="scala-number">100</span>).toString.view.map(_.asDigit).sum

assert(r == <span class="scala-number">648</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 21</div>
		<div class="problem-description">Evaluate the sum of all amicable pairs under 10000.<a href="http://projecteuler.net/index.php?section=problems&id=21">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> ds = (<span class="scala-number">0</span> until <span class="scala-number">10000</span>).view
         .map(n =&gt; (<span class="scala-number">1</span> to (n / <span class="scala-number">2</span>)).filter(n % _ == <span class="scala-number">0</span>).sum)

<span class="scala-keyword">val</span> as = ds.zipWithIndex.collect { 
  <span class="scala-keyword">case</span> (n, i) <span class="scala-keyword">if</span> n &lt; <span class="scala-number">10000</span> && ds(n) != n && ds(n) == i =&gt; i
}

<span class="scala-keyword">val</span> r = as.sum

assert(r == <span class="scala-number">31626</span>) <span class="scala-comment">// 658 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 22</div>
		<div class="problem-description">What is the total of all the name scores in the file of first names?<a href="http://projecteuler.net/index.php?section=problems&id=22">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = io.Source.fromFile(<span class="scala-string">"names.txt"</span>).mkString.split(<span class="scala-string">","</span>)
        .map(_.init.tail).sorted.map(_.map(_ - <span class="scala-number">64</span>).sum)
        .zipWithIndex.map(p =&gt; p._1 * (p._2 + <span class="scala-number">1</span>)).sum

assert(r == <span class="scala-number">871198282</span>) <span class="scala-comment">// 38 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 23</div>
		<div class="problem-description">Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.<a href="http://projecteuler.net/index.php?section=problems&id=23">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> as = (<span class="scala-number">0</span> to <span class="scala-number">28123</span>).map(n =&gt; (<span class="scala-number">1</span> until n).filter(n % _ == <span class="scala-number">0</span>).sum)
          .zipWithIndex.filter(p =&gt; p._1 &gt; p._2).map(_._2)

<span class="scala-keyword">val</span> exc = as.view.flatMap { a =&gt; 
  as.takeWhile(_ &lt;= (<span class="scala-number">28123</span> - a)).map(a +)
} 

<span class="scala-keyword">val</span> r = (<span class="scala-number">1</span> to <span class="scala-number">28123</span> diff exc).sum 

assert(r == <span class="scala-number">4179871</span>) <span class="scala-comment">// 9 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 24</div>
		<div class="problem-description">What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?<a href="http://projecteuler.net/index.php?section=problems&id=24">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> ps(s: String): Seq[String] = <span class="scala-keyword">if</span>(s.size == <span class="scala-number">1</span>) Seq(s) <span class="scala-keyword">else</span> 
  s.flatMap(c =&gt; ps(s.filterNot(_ == c)).map(c +))

<span class="scala-keyword">val</span> r = ps(<span class="scala-string">"0123456789"</span>)(<span class="scala-number">999999</span>).toLong

assert(r == <span class="scala-number">2783915460L</span>) <span class="scala-comment">// 7 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 25</div>
		<div class="problem-description">What is the first term in the Fibonacci sequence to contain 1000 digits?<a href="http://projecteuler.net/index.php?section=problems&id=25">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> fs: Stream[BigInt] = 
  <span class="scala-number">0</span> #:: <span class="scala-number">1</span> #:: fs.zip(fs.tail).map(p =&gt; p._1 + p._2)

<span class="scala-keyword">val</span> r = fs.view.takeWhile(_.toString.length &lt; <span class="scala-number">1000</span>).size

assert(r == <span class="scala-number">4782</span>) <span class="scala-comment">// 468 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 26</div>
		<div class="problem-description">Find the value of <var>d</var> &lt; 1000 for which 1/<var>d</var> contains the longest recurring cycle.<a href="http://projecteuler.net/index.php?section=problems&id=26">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> ps = (<span class="scala-number">2</span> until <span class="scala-number">1000</span>).map(i =&gt; (<span class="scala-number">1</span> to <span class="scala-number">2000</span>)
         .find(BigInt(<span class="scala-number">10</span>).modPow(_, i) == <span class="scala-number">1</span>)) 

<span class="scala-keyword">val</span> r = <span class="scala-number">2</span> + ps.indexOf(Some(ps.flatten.max)) 

assert(r == <span class="scala-number">983</span>) <span class="scala-comment">// 2 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 27</div>
		<div class="problem-description">Find a quadratic formula that produces the maximum number of primes for consecutive values of&nbsp;<var>n</var>.<a href="http://projecteuler.net/index.php?section=problems&id=27">*</a></div>
	</div>
<pre>
<span class="scala-keyword">lazy</span> <span class="scala-keyword">val</span> ps: Stream[Int] = <span class="scala-number">2</span> #:: Stream.from(<span class="scala-number">3</span>).filter(i =&gt;
  ps.takeWhile(j =&gt; j * j &lt;= i).forall(i % _ &gt; <span class="scala-number">0</span>))

<span class="scala-keyword">def</span> isPrime(n: Int) = ps.view.takeWhile(_ &lt;= n).contains(n)

<span class="scala-keyword">val</span> ns = (-<span class="scala-number">999</span> until <span class="scala-number">1000</span>).flatMap { a =&gt; 
  (-<span class="scala-number">999</span> until <span class="scala-number">1000</span>).map(b =&gt; (a, b, (<span class="scala-number">0</span> to <span class="scala-number">1000</span>).view
    .takeWhile(n =&gt; isPrime(n * n + a * n + b)).size))
}

<span class="scala-keyword">val</span> t = ns.reduceLeft((a, b) =&gt; <span class="scala-keyword">if</span>(a._3 &gt; b._3) a <span class="scala-keyword">else</span> b)

<span class="scala-keyword">val</span> r = t._1 * t._2

assert(r == -<span class="scala-number">59231</span>) <span class="scala-comment">// 6 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 28</div>
		<div class="problem-description">What is the sum of both diagonals in a 1001 by 1001 spiral?<a href="http://projecteuler.net/index.php?section=problems&id=28">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> cs(n: Int, p: Int): Stream[Int] = 
  (n * <span class="scala-number">4</span> + p * <span class="scala-number">10</span>) #:: cs(n + p * <span class="scala-number">4</span>, p + <span class="scala-number">2</span>)

<span class="scala-keyword">val</span> r = <span class="scala-number">1</span> + cs(<span class="scala-number">1</span>, <span class="scala-number">2</span>).take(<span class="scala-number">500</span>).sum

assert(r == <span class="scala-number">669171001</span>) <span class="scala-comment">// 1 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 29</div>
		<div class="problem-description">How many distinct terms are in the sequence generated by <var>a</var><sup><var>b</var></sup> for 2 &#8804; <var>a</var> &#8804; 100 and <br/>2&nbsp;&#8804;&nbsp;<var>b</var>&nbsp;&#8804;&nbsp;100?<a href="http://projecteuler.net/index.php?section=problems&id=29">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> r = (<span class="scala-number">2</span> to <span class="scala-number">100</span>).flatMap(a =&gt; (<span class="scala-number">2</span> to <span class="scala-number">100</span>)
        .map(b =&gt; BigInt(a).pow(b))).distinct.size

assert(r == <span class="scala-number">9183</span>) <span class="scala-comment">// 17 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 30</div>
		<div class="problem-description">Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.<a href="http://projecteuler.net/index.php?section=problems&id=30">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> max(d: Int) = math.pow(<span class="scala-number">10</span>, d).toInt - <span class="scala-number">1</span>

<span class="scala-keyword">def</span> sum(n: Int) = n.toString.map(_.asDigit)
  .map(math.pow(_, <span class="scala-number">5</span>).toInt).sum

<span class="scala-keyword">val</span> limit = Stream.from(<span class="scala-number">1</span>).find(d =&gt; max(d) &gt; sum(max(d))).get

<span class="scala-keyword">val</span> r = (<span class="scala-number">2</span> to max(limit)).view.filter(n =&gt; n == sum(n)).sum

assert(r == <span class="scala-number">443839</span>) <span class="scala-comment">// 2 s</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 31</div>
		<div class="problem-description">Investigating combinations of English currency denominations.<a href="http://projecteuler.net/index.php?section=problems&id=31">*</a></div>
	</div>
<pre>
<span class="scala-keyword">def</span> f(ms: List[Int], n: Int): Int = ms <span class="scala-keyword">match</span> {
  <span class="scala-keyword">case</span> h :: t =&gt;
    <span class="scala-keyword">if</span> (h &gt; n) <span class="scala-number">0</span> <span class="scala-keyword">else</span> <span class="scala-keyword">if</span> (n == h) <span class="scala-number">1</span> <span class="scala-keyword">else</span> f(ms, n - h) + f(t, n)
  <span class="scala-keyword">case</span> _ =&gt; <span class="scala-number">0</span>
}

<span class="scala-keyword">val</span> r = f(List(<span class="scala-number">1</span>, <span class="scala-number">2</span>, <span class="scala-number">5</span>, <span class="scala-number">10</span>, <span class="scala-number">20</span>, <span class="scala-number">50</span>, <span class="scala-number">100</span>, <span class="scala-number">200</span>), <span class="scala-number">200</span>)

assert(r == <span class="scala-number">73682</span>) <span class="scala-comment">// 15 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 32</div>
		<div class="problem-description">Find the sum of all numbers that can be written as pandigital products.<a href="http://projecteuler.net/index.php?section=problems&id=32">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> ms = <span class="scala-keyword">for</span> {
  a &lt;- <span class="scala-number">2</span> to <span class="scala-number">10000</span>; b &lt;- <span class="scala-number">2</span> to <span class="scala-number">10000</span> / a
  m = a * b; s = a.toString + b + m
  <span class="scala-keyword">if</span> s.length == <span class="scala-number">9</span> && (<span class="scala-number">1</span> to <span class="scala-number">9</span>).mkString.forall(s.contains(_))
} <span class="scala-keyword">yield</span> m

<span class="scala-keyword">val</span> r = ms.distinct.sum

assert(r == <span class="scala-number">45228</span>) <span class="scala-comment">// 73 ms</span>
</pre>
</div>

<div class="problem">
	<div class="problem-header">
		<div class="problem-title">Problem 33</div>
		<div class="problem-description">Discover all the fractions with an unorthodox cancelling method.<a href="http://projecteuler.net/index.php?section=problems&id=33">*</a></div>
	</div>
<pre>
<span class="scala-keyword">val</span> rs = <span class="scala-keyword">for</span>(i &lt;- <span class="scala-number">1</span> to <span class="scala-number">9</span>; j &lt;- (i + <span class="scala-number">1</span>) to <span class="scala-number">9</span>; k &lt;- <span class="scala-number">1</span> to <span class="scala-number">9</span>; 
  <span class="scala-keyword">if</span> k * (<span class="scala-number">9</span> * i + j) == <span class="scala-number">10</span> * i * j) <span class="scala-keyword">yield</span> (<span class="scala-number">10</span> * i + j, <span class="scala-number">10</span> * j + k)

<span class="scala-keyword">val</span> p = rs.reduceLeft((n, d) =&gt; (n._1 * d._1, n._2 * d._2))

<span class="scala-keyword">def</span> gcd(n: Int, d: Int): Int = <span class="scala-keyword">if</span> (d == <span class="scala-number">0</span>) n <span class="scala-keyword">else</span> gcd(d, n % d)

<span class="scala-keyword">val</span> r = p._2 / gcd(p._1, p._2)

assert(r == <span class="scala-number">100</span>) <span class="scala-comment">// 5 ms</span>
</pre>
</div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/scala-for-project-euler/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Sleeptracker Pro Review</title>
		<link>http://pavelfatin.com/sleeptracker-pro-review/</link>
		<comments>http://pavelfatin.com/sleeptracker-pro-review/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 03:14:11 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[alarm]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[sleep]]></category>
		<category><![CDATA[sleep cycle]]></category>
		<category><![CDATA[sleep stage]]></category>
		<category><![CDATA[sleeptracker]]></category>
		<category><![CDATA[watch]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=39</guid>
		<description><![CDATA[I bought Sleeptracker Pro gadget from <a title="Innovative Sleep Solutions LLC" href="http://www.sleeptracker.com/">Innovative Sleep Solutions LLC</a> a month ago. The device is a watch, aimed to “find best waking moments, so that waking up has never been easier”. I considered the watch as a good investment despite the price, because I am really awful at waking up. My experience shows that, although Sleeptracker Pro have a few shortcomings, the watch does what it claims.]]></description>
			<content:encoded><![CDATA[<p>I bought Sleeptracker Pro gadget from <a title="Innovative Sleep Solutions LLC" href="http://www.sleeptracker.com/">Innovative Sleep Solutions LLC</a> a month ago. The device is a watch, aimed to <q cite="http://www.sleeptracker.com">find best waking moments, so that waking up has never been easier</q>.</p>
<p>Sleeptracker monitors your movements while you sleep and wakes you up at a time, when you are in an almost-awake state, so that you wake up easily and feeling refreshed. Moreover, Sleeptracker Pro allows to upload your sleep data to a computer for analysis that helps you to improve your sleep habits.</p>
<p>I considered the watch as a good investment despite the price, because I am really awful at waking up. Does the product come up to the expectations aroused by the manufacturer&#8217;s promises? My experience shows that, although Sleeptracker Pro have a few shortcomings, the watch does what it claims.<br />
<span id="more-39"></span></p>
<h3>How it works</h3>
<p>Sleep cycle is what makes Sleeptracker possible. Sleeping is not a steady state, but a series of cycles that occurs throughout the night. Here is a sketchy graph of a typical adult sleep pattern (from the product manual):</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-sleep-cycle-large.gif" title="Sleeptracker Pro: Sleep Cycle" class="image"><img src="/images/sleeptracker/sleeptracker-pro-sleep-cycle.gif" alt="Graph Of Human Sleep Cycle" title="Sleeptracker Pro: Sleep Cycle" width="480" height="283" /></a><br />
<br />
Each cycle comprises different <a title="Sleep, Stages - Wikipedia" href="http://en.wikipedia.org/wiki/Sleep#Stages">stages</a> with different conditions of body and mind. That is why some waking up moments are better than others. So, if the alarm goes off while you are in an “almost-awake” state, you will wake up on the right side of the bed.</p>
<p>Despite the vague claim, that Sleeptracker “monitors <em>signals</em> from your body that indicate whether you are asleep or awake”, the <em>only</em> thing measured by the watch is movements of your arm. Sleeptracker uses a built-in accelerometer as a sensor to determine speed and direction of your motions. It is a potential drawback of the device, because accelerometer may be insufficient to reliable detect sleep phases, although it may be enough to merely register awake moments (usually, sleep stages and other characteristics of sleep measured by <a title="Polysomnography - Wikipedia" href="http://en.wikipedia.org/wiki/Polysomnography">polysomnography</a>, that includes simultaneous monitoring of brain waves, eye movements, hearth rhythm and muscle activity).</p>
<h3>Exterior</h3>
<p>The watch comes in an unpretentious box, the package contains:</p>
<ul>
<li>the device,</li>
<li>a fancy connector,</li>
<li>printed manual,</li>
<li>CD with PC software.</li>
</ul>
<p><a href="/images/sleeptracker/sleeptracker-pro-delivery-set-large.jpg" title="Sleeptracker Pro: Delivery-Set" class="image"><img src="/images/sleeptracker/sleeptracker-pro-delivery-set.jpg" alt="The watch, connector, manual and CD" title="Sleeptracker Pro: Delivery-Set" width="480" height="323" /></a><br />
<br />
The watch is big and heavy, with small monochrome display on a moderately large face:</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-large.jpg" title="Sleeptracker Pro" class="image"><img src="/images/sleeptracker/sleeptracker-pro.jpg" alt="Sleeptracker Pro Close-Up" title="Sleeptracker Pro" width="230" height="318" /></a><br />
<br />
The device has two buttons on each side:</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-side-large.jpg" title="Sleeptracker Pro: Side" class="image"><img src="/images/sleeptracker/sleeptracker-pro-side.jpg" alt="Sleeptracker Pro Side Buttons" title="Sleeptracker Pro: Side" width="230" height="129" /></a><br />
<br />
On the back of the watch there are: battery cover, communication contacts and labels (one of which promises water resistance to a depth of 10 meters):</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-back-large.jpg" title="Sleeptracker Pro: Back" class="image"><img src="/images/sleeptracker/sleeptracker-pro-back.jpg" alt="Sleeptracker Pro Back" title="Sleeptracker Pro: Back" width="230" height="229" /></a><br />
<br />
The display includes current time, day, date, and alarm settings:</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-display-large.jpg" title="Sleeptracker Pro: Display" class="image"><img src="/images/sleeptracker/sleeptracker-pro-display.jpg" alt="Sleeptracker Pro Display" title="Sleeptracker Pro: Display" width="230" height="176" /></a><br />
<br />
The watch has a back-lit:</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-back-lit-large.jpg" title="Sleeptracker Pro: Back-lit" class="image"><img src="/images/sleeptracker/sleeptracker-pro-back-lit.jpg" alt="Sleeptracker Pro Back-lit" title="Sleeptracker Pro: Back-lit" width="230" height="175" /></a><br />
<br />
The way the device connects to a computer is rather unusual:</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-connection-large.jpg" title="Sleeptracker Pro: Connection" class="image"><img src="/images/sleeptracker/sleeptracker-pro-connection.jpg" alt="Sleeptracker Pro Connection" title="Sleeptracker Pro: Connection" width="350" height="384" /></a></p>
<h3>Usage</h3>
<p>Although you can wear Sleeptracker anytime, it only needs to be worn at night to be effective. The face of the watch must be on top of your wrist, and the band must be tight enough to suppress movements of the wrist inside the band.</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-on-wrist-large.jpg" title="Wearing Sleeptracker Pro" class="image"><img src="/images/sleeptracker/sleeptracker-pro-on-wrist.jpg" alt="Sleeptracker Pro On Wrist" title="Wearing Sleeptracker Pro" width="480" height="337" /></a><br />
<br />
There are four buttons to configure Sleeptracker and any of them can be used together with the backlit to interact with the watch in the dark.</p>
<p>Unlike ordinary alarm clocks, Sleeptracker uses <em>two</em> parameters to specify the wake-up time:</p>
<ul>
<li>ALARM TIME – the latest moment to wake you up.</li>
<li>ALARM WINDOW – a period (before the alarm time), Sleeptracker uses to detect the optimal moments at which to trigger the alarm (default window is 20 minutes).</li>
</ul>
<p>Besides, if you want Sleeptracker to record your sleep data, you should properly set TO BED TIME. After that time, the watch starts recording your sleep patterns. The device supports “button shortcut” to easily adjust this parameter at 30 minutes after the current time.</p>
<p>You can choose alarm type from the following:</p>
<ul>
<li>ringing alarm;</li>
<li>vibrating alarm;</li>
<li>ringing-and-vibrating alarm.</li>
</ul>
<p>The alarm is activated at your first almost-awake moment within the ALARM WINDOW. If no almost-awake moments found, the alarm is finally triggered right at the ALARM TIME (as an ordinary alarm clock does).</p>
<p>You have two ways to deal with the ringing/vibrating alarm, you can:</p>
<ul>
<li>turn it off;</li>
<li>snooze it until the default ALARM TIME.</li>
</ul>
<p>After waking up you may review your sleep data. The watch shows all recorded almost-awake moments for the recent night. You can see when those moments occurred in chronological order as DATA 1, DATA 2, etc. </p>
<p><a href="/images/sleeptracker/sleeptracker-pro-data-3-large.jpg" title="Sleeptracker Pro: Data 3" class="image"><img src="/images/sleeptracker/sleeptracker-pro-data-3.jpg" alt="Sleeptracker Pro Data 3" title="Sleeptracker Pro: Data 3" width="230" height="174" /></a><br />
<br />
The average time between the almost-awake moments is called DATA-A, and aimed to determine how soundly you have slept (the greater DATA-A indicates the better sleep).</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-data-a-large.jpg" title="Sleeptracker Pro: Data A" class="image"><img src="/images/sleeptracker/sleeptracker-pro-data-a.jpg" alt="Sleeptracker Pro Data A" title="Sleeptracker Pro: Data A" width="230" height="174" /></a><br />
<br />
Sleeptracker Pro supports uploading the sleep data to the computer, so that you can track your sleep history and identify factors that may be affecting your sleep. Provided software supports only Microsoft Windows operating systems. A cable with the clip is a USB-to-COM adapter, that requires a special driver (packaged with the software).</p>
<p>To transfer the sleep data of a recent night, you need to do the following:</p>
<ol>
<li>Attach the included cable to your PC.</li>
<li>Set the watch to the DATA screen.</li>
<li>Connect the watch to the cable by inserting the clip into the holes on the back of the watch.</li>
<li>Open Sleeptracker Pro software and add a new sleep event.</li>
</ol>
<p>The software also allows you to manually enter your sleep data without connecting the watch to the computer.</p>
<p><a href="/images/sleeptracker/sleeptracker-pro-new-event-large.gif" title="Sleeptracker Pro: New Sleep Event" class="image"><img src="/images/sleeptracker/sleeptracker-pro-new-event.gif" alt="Sleeptracker Pro New Sleep Event" title="Sleeptracker Pro: New Sleep Event" width="550" height="351" /></a><br />
<br />
The main window of the program contains the following:</p>
<ul>
<li>Date column – shows the date of each night.</li>
<li>Sleep chart – the horizontal lines show the time you went to bed, when you woke up, and how long you slept; vertical ticks mark almost-awake moments.</li>
<li>Mood column – indicates the mood you were in when you woke up.</li>
<li>Data-A column – shows the average time between almost-awake moments.</li>
<li>Factors column – lists circumstances that may have affected your sleep.</li>
<li>Averages chart – shows your sleep averages based on all nights you have added.</li>
</ul>
<p><a href="/images/sleeptracker/sleeptracker-pro-main-window-large.gif" title="Sleeptracker Pro: Main Window" class="image"><img src="/images/sleeptracker/sleeptracker-pro-main-window.gif" alt="Sleeptracker Pro Main Window" title="Sleeptracker Pro: Main Window" width="550" height="351" /></a><br />
<br />
You may customize the display of your sleep data by changing the period of view or by hiding certain categories of data.</p>
<h3>My experience</h3>
<p>I have already been using Sleeptracker Pro for more than a month, and I have mixed feelings about the device.</p>
<p>The idea behind the product is great, but it is not a silver bullet. Although Sleeptracker performs better than an ordinary alarm clock, waking up is <em>still</em> waking up (at least for me). Many times I successfully slept through the alarm because I didn’t feel much aspiration to leave a bed.</p>
<p>The design of the watch is hardly practical. While most people don’t want their alarm clock to be waterproof, Sleeptracker Pro <em>is</em> waterproof, and that is why it looks a bit clumpy (heavy sealed case with a lot of metal, tight buttons and a small display). It’s not very comfortable to wear such a device at night, also, I doubt that someone consider using Sleeptracker Pro as a day-to-day watch (particularly, because of bright orange strips on the wristband).</p>
<p>Still, the main drawback of Sleeptracker Pro is oversimplification:</p>
<ul>
<li>The device only stores one night&#8217;s data, and if you forget to acquire the data on a day, you lose it.</li>
<li>The watch doesn&#8217;t detect the moment when you actually fall asleep, so if you want to record the sleep data, you have to predict and set that time by yourself (often I update that setting several times in one night).</li>
<li>Included software is rather old-fashioned, and has limited analytical capability.</li>
</ul>
<p>Nevertheless, the watch works as promised and I definitely feel the difference.  Most times I was waking up feeling refreshed and ready to take on the day.</p>
<p>The ability to record sleep history proved to be valuable, but I avoid using the bundled software for synchronization and prefer to type night&#8217;s recordings into an <a title="OpenOffice.org - The Free and Open Productivity Suite" href="http://www.openoffice.org/">OpenOffice.org</a> spreadsheet (later I am going to develop my own program to store and analyze the data).</p>
<p>Vibrating alarm is an awesome bonus: waking up is definitely more pleasant without audible alarm. Moreover, for the first time I have a truly personal alarm that doesn&#8217;t awake the whole house (except me).</p>
<h3>Conclusion</h3>
<p>The idea behind the product is great, while the implementation leaves much to be desired.  However, the device does what it is marketed for, and Sleeptracker Pro can actually improve the quality of your life.</p>
<p><em>Update:</em> Take a look at <a title="SleepArchiver" href="/sleeparchiver/">SleepArchiver</a> &#8211; a cross-platform data manager for Sleeptracker-series watches.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/sleeptracker-pro-review/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>The Best Player for Audiobooks and Podcasts</title>
		<link>http://pavelfatin.com/the-best-player-for-audiobooks-and-podcasts/</link>
		<comments>http://pavelfatin.com/the-best-player-for-audiobooks-and-podcasts/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 09:00:48 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[audiobook]]></category>
		<category><![CDATA[bookmark]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[podcast]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=3</guid>
		<description><![CDATA[Although all portable players can play audiobooks and podcasts, few of them can do it well. In this article I suggest, based on my personal experience, what the perfect player for audiobooks and podcasts should look like.]]></description>
			<content:encoded><![CDATA[<p>Although all portable players can play audiobooks and podcasts, few of them can do it well. In this article I suggest, based on my personal experience, what the perfect player for audiobooks and podcasts should look like.<br />
<span id="more-3"></span></p>
<h3>Player matters</h3>
<p>Audiobooks and podcasts become very popular medium of information. One cause of such popularity is a fact, that audio material, by its nature, has many advantages over text. However, an important reason for audiobooks spread is the creation of portable audio players.</p>
<p>Today, almost any gadget with internal memory and a battery supports audio playback. You can use a mobile phone, a communicator, PDA or a music player to listen to podcast or audiobook.</p>
<p>Personally, I enjoy listening to audiobooks and podcasts for many years. After I&#8217;ve tried many various devices, I&#8217;ve finally come to the conclusion that some of them are far more appropriate for this purpose.</p>
<h3>Newer isn&#8217;t better</h3>
<p>Although there&#8217;s obvious progress in portable players&#8217; development, it seems that, in case of audiobooks, many modern features actually degrade player&#8217;s usability.</p>
<p>Touch controls, big color screens and small buttons are good for watching video, but when it comes to plain audio, these stuff can cause troubles.</p>
<p>Player optimization for music playback doesn&#8217;t guarantee smooth work with audiobooks either.</p>
<h3>The perfect player</h3>
<p>So, what should the perfect player for audiobooks and podcasts look like? Based on my personal experience, I defined the following must-have features for such a player:</p>
<ul>
<li>Bookmarks support</li>
<li>Proper search support</li>
<li>Tactile control</li>
<li>Large monochrome display with landscape orientation</li>
<li>Enough storage capacity</li>
<li>Good file browser</li>
</ul>
<h3>Bookmarks support</h3>
<p>Proper bookmarks support is a foundation stone. Without it, you can&#8217;t correctly resume the playback after a shutdown or a track change &#8211; you have to remember files you are listening to and current position for every file to restore it later. Needles to say, it&#8217;s not very exciting experience, especially in a case of a poorly implemented search (in that case, you&#8217;re obliged to hold &#8220;fast forward&#8221; or &#8220;rewind&#8221; button for minutes to find the right position in a large audio file).</p>
<p>I distinguish the following types of bookmarks support:</p>
<ul>
<li>Player correctly resumes audio playback after shutdown.</li>
<li>Player restores position of playback on per-file basis.</li>
<li>Player has capacity to add any number of bookmarks for any file.</li>
</ul>
<p>The absolute minimum is a capacity to resume playback where you left off after turning the player off and then on. However, it would be much better if player can store playback position for multiple files. Such an ability helps a lot when you listen to different books and podcasts at a time (or when you alternate audiobooks with music). These are two kinds of automatic bookmarks support.</p>
<p>Support for manual bookmarking is a different way to resume playback, which has its own pros and cons. The advantages are that you can manually mark a file to quickly return to it later (without searching through a file system), also, you can store multiple bookmarks for the same file. The disadvantage is you have to do more actions by yourself (which is usually error-prone).</p>
<p>Which type of bookmarking support is better? It seems that automatic bookmarking is suitable for listening to podcasts (because each podcast is usually represented by only one file), and support for manual bookmarking is a convenient feature for audiobooks (to remember current files). Certainly, it&#8217;s better to have both.</p>
<h3>Proper search support</h3>
<p>Although decent bookmarking support significantly reduces the need for navigation inside audio tracks, there are cases where fast forward and rewind functions are still handy. For instance, you can use them to do the following:</p>
<ul>
<li>repeat the last sentence;</li>
<li>omit an unwanted episode;</li>
<li>skip a commercial insertion;</li>
<li>find a particular place inside audio file (in case you have no bookmark).</li>
</ul>
<p>Most players have search support, but often the speed either too slow or too fast (what is uncomfortable). An adjustable search speed is a partial solution, because any selected speed is constant, while preferable speeds for different action vary. (i. e. you may want a slow speed to repeat a phrase, and a fast one to find a particular episode).</p>
<p>Personally, I prefer the player to have fast forward / rewind acceleration. Acceleration mode increases search speed depending on how long &#8220;fast forward&#8221; or &#8220;rewind&#8221; button is pressed. This gives, on the one hand, means to easily skip small portions of audio, and, on the other hand, a tool for fast navigation inside long tracks. Certainly, it&#8217;s useful to have an ability to configure acceleration parameters.</p>
<p>There&#8217;s one important (but often underestimated) characteristic of search functions beside speed issues. It&#8217;s a difference threshold between a button&#8217;s hold-down time for track search and track change actions. The larger threshold is, the more likely you are to choose next or previous track instead of fast-forwarding or rewinding (so you have to select your file again and restore the precise position inside it). No doubt, only a player with clear distinction between search and track change actions can save you from going mad and tearing your hair out.</p>
<h3>Tactile control</h3>
<p>When you listen to audiobook or podcast it&#8217;s likely you have to control your player more frequently than when you listen to music. Speech is a more subtle entity comparing to the music &#8211; often you need to pause the playback for a moment, repeat the sentence, skip a commercial insertion, raise or lower the volume, change the track, etc&#8230; Who wants to bother removing the player from a pocket or interrupting pleasant rest just to operate a brand-new touchscreen (or a touch wheel)?</p>
<p>Tactile control implies the following:</p>
<ul>
<li>Player has palpable controls (like buttons) for all basic actions.</li>
<li>You can easily locate, identify and use all controls by touch, without seeing them.</li>
<li>You can operate all controls using one hand only.</li>
<li>It&#8217;s unlikely to activate any control unintentionally.</li>
</ul>
<p>Good player&#8217;s tactile control promotes a smooth and enjoyable listening experience.</p>
<h3>Large monochrome display with landscape orientation</h3>
<p>Big enough screen is useful for fast and easy navigation among books, chapters and podcasts. Landscape orientation of the screen gives more horizontal resolution in order to avoid annoying titles scrolling.</p>
<p>Although colors on screen look cool, it&#8217;s no surprise that color display is a pointless feature for pure audio player. Monochrome display, on the contrary, is comfortable for the eyes and has no problems with visibility in a bright light.</p>
<h3>Enough storage capacity</h3>
<p>Why is the player&#8217;s capacity important? Usually, a typical audiobook consumes more storage space than an average album of music. Besides, it&#8217;s handy to store all chapters of audiobook together. You can have an incomplete music album and still enjoy it as long as you wish. But, as for audiobook&#8217;s chapters, sooner or later you will need every one of them.</p>
<p>Personally, I don&#8217;t like to update player&#8217;s memory every time I&#8217;m going to listen to the next part of an audiobook. Also, I have a habit to listen to many audiobooks at a time, and, depending on my mood, to add podcasts or music to my listening. That&#8217;s why I consider storage capacity important.</p>
<p>Until recently, player with a lot of storage capacity meant &#8220;a big expensive player with hard disk drive&#8221;. But, fortunately, because of a flash memory prices drop, today we can find handy and inexpensive portable players with 4-16GB flash memory inside. Apparently, such capacity is enough for comfortable listening to audiobooks and podcasts.</p>
<p>If you intend to interchange large amounts of audio material, you may also consider using player with memory card slot for removable flash cards (like microSD). Many up-to-date players support removable cards, although such support is often bounded by 2GB or 4GB card limitation.</p>
<h3>Good file browser</h3>
<p>Some players show all audio files in a single flat list, what is by no means suitable for listening to audiobooks. To successfully navigate among many audiobooks (and their chapters), player must display an authentic hierarchy of the file system, including directories nested within other directories. It&#8217;s better to avoid limits either in the numbers of directories on the same level, or in the level of nesting.</p>
<p>Metadata tags (like ID3 tags) are a controversial issue. They can hold additional information about audio file beside the content of a filename. Sometimes that can be useful, but:</p>
<ul>
<li>it is harder to edit tags than the name of file,</li>
<li>tags are intended for music and therefore store properties, directly inapplicable to audiobooks and podcasts (such as &#8220;artist&#8221;, &#8220;album&#8221;, &#8220;genre&#8221; and so on),</li>
<li>displaying of excess metadata requires scrolling,</li>
<li>often audio files lack tag information or include incorrect tags.</li>
</ul>
<p>That is why I decided to give up using metadata tags and to store description of audio files only in filenames. Usually, I assign short but meaningful names to podcasts immediately before downloading.</p>
<p>It is up to you whether to relay on tags, however, you can avoid a great deal of confusion in this matter by choosing portable player with optional metadata tags&#8217; usage.</p>
<h3>Miscellaneous features</h3>
<p>There are a few other things to consider when choosing a portable player for audiobooks and podcasts.</p>
<p>Player should allow to play audio files by directory structure (don&#8217;t reorder them by metadata tags). Support for continuous playing through a sequence of directories is essential to handle audiobooks divided in separate folders.</p>
<p>There should be no compulsory (always enabled) &#8220;fade-in&#8221;, &#8220;fade-out&#8221;, or &#8220;cross-fade&#8221; features. Obviously, they are not compatible with speech.</p>
<p>Player should supports many audio formats (like mp3, wma, ogg, mp4, flac, etc). Although you can always convert (for example, using <a href="http://mediacoder.sourceforge.net/">MediaCoder</a>) your audio files to supported format, it&#8217;s not so convenient task.</p>
<p>If you&#8217;re going to buy audiobooks with digital rights management (DRM), you must ensure that player supports it.</p>
<h3>Conclusion</h3>
<p>I laid down the basic guidelines for choosing portable player for audiobooks and podcasts. I omitted players features, that don&#8217;t exert much special influence on listening to audiobooks or podcasts. They are:</p>
<ul>
<li>design of the player (size, shape, weight, color, etc),</li>
<li>type of the storage (HDD or flash),</li>
<li>type and capacity of a battery,</li>
<li>external interface (mini-USB or some proprietary one),</li>
<li>speed of files transfer,</li>
<li>quality of sound,</li>
<li>sound processing capabilities (like equalizer),</li>
<li>operating systems support,</li>
<li>price.</li>
</ul>
<p>However these features may be still important to you because of a personal preference. All need to be weighed before making a decision. That&#8217;s why, unfortunately, there&#8217;s no perfect player for everyone.</p>
<p>As for me, I have five portable audio players (not counting mobile phone, PDA and Sony Reader), and all of them are far from ideal (from my point of view, of course). Next player I am going to buy is one with <a href="http://www.rockbox.org">Rockbox</a> support.</p>
<p>Rockbox is an open source firmware for many digital audio players. It aims to be considerably more functional and efficient than stock firmwares while remaining easy to use and customizable. At the moment, it looks like it&#8217;s the only software that good for listening to audiobooks and podcasts. Everything you need to use Rockbox is to have a <a href="http://www.rockbox.org/twiki/bin/view/Main/TargetStatus">supported player</a>.</p>
<p>I hope the information will be useful to you. If you have suggestions for extending or improving the article, feel free to contact me.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/the-best-player-for-audiobooks-and-podcasts/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Hello World!</title>
		<link>http://pavelfatin.com/hello-world/</link>
		<comments>http://pavelfatin.com/hello-world/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 08:39:06 +0000</pubDate>
		<dc:creator>Pavel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pavelfatin.com/?p=1</guid>
		<description><![CDATA[This is the post to cherish a tradition.]]></description>
			<content:encoded><![CDATA[<p>This is the post to cherish a <a href="http://en.wikipedia.org/wiki/Hello_world_program">tradition</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pavelfatin.com/hello-world/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

