The Digital Cat - Scalahttps://www.thedigitalcatonline.com/2019-02-28T10:00:00+00:00Adventures of a curious cat in the land of programming99 Scala Problems 16-202015-05-13T16:00:00+01:002015-05-13T16:00:00+01:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-05-13:/blog/2015/05/13/99-scala-problems-16-20/<p>Discussing more list management in Scala (dropping elements, splitting the, etc.)</p><h2 id="problem-16">Problem 16<a class="headerlink" href="#problem-16" title="Permanent link">¶</a></h2>
<h3 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h3>
<p><strong>P16</strong> (**) Drop every Nth element from a list.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">drop</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">)</span>
</code></pre></div>
<h3 id="mapping">Mapping<a class="headerlink" href="#mapping" title="Permanent link">¶</a></h3>
<p>A first simple approach is to divide the list in small groups of up to N elements and drop the last element from each of them. This is easily achieved with the <code>grouped()</code> method of <code>List</code> types and the application of a flat mapping.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">drop</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">grouped</span><span class="p">(</span><span class="n">n</span><span class="p">).</span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">}.</span><span class="n">toList</span>
<span class="p">}</span>
</code></pre></div>
<p>The <code>grouped()</code> method returns an iterator, which is, as in other languages, something that can visit the elements contained in a collection and yield them. When an iterator is required to be consumed all at once you can call the <code>toList()</code> method to convert it into a <code>List</code>.</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">val</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">)</span>
<span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">grouped</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">Iterator</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">non</span><span class="o">-</span><span class="n">empty</span><span class="w"> </span><span class="n">iterator</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">grouped</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span><span class="n">toList</span>
<span class="n">res1</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
</code></pre></div>
<p><code>Iterator</code> type has <a href="http://www.scala-lang.org/api/2.11.5/index.html#scala.collection.Iterator">a lot of methods</a> in common with <code>List</code> type, most notably <code>flatMap()</code>. This last method is fed with a simple anonymous function that, using <code>take()</code>, keeps the first <code>n - 1</code> elements.</p>
<p>A different approach may be followed using the <code>zipWithIndex()</code> method that packs each element of the list with its index (starting from 0)</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">zipWithIndex</span>
<span class="n">res5</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Symbol</span><span class="p">,</span><span class="w"> </span><span class="nc">Int</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">((</span><span class="ss">'a</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'b</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'c</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'e</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'f</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'g</span><span class="p">,</span><span class="mi">6</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'h</span><span class="p">,</span><span class="mi">7</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'i</span><span class="p">,</span><span class="mi">8</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'j</span><span class="p">,</span><span class="mi">9</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="ss">'k</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
</code></pre></div>
<p>After this transformation, we may apply the <code>filter()</code> method to get the right elements with a selection based on the modulo operation.</p>
<p>The list is now made of <code>Tuple2</code> elements, as tuples in Scala aren't a collection just like lists (or like Python tuples). For performance reasons, they are implemented with a different type according to the length, like in this case. To index a <code>Tuple2</code> element we may use its <code>_1</code> and <code>_2</code> attributes (pay attention that tuples are indexed starting from 1).</p>
<p>The filter anonymous function just checks if the index (the second element of the tuple) is a multiple of <code>n</code>. Then, with <code>map()</code> we keep the first element only (the original element); the anonymous function <code>{ _._1 }</code> is a shortcut form for <code>{ e => e._1 }</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">dropZip</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">zipWithIndex</span><span class="w"> </span><span class="n">filter</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">_2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="p">.</span><span class="n">_1</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="the-recursive-solution">The recursive solution<a class="headerlink" href="#the-recursive-solution" title="Permanent link">¶</a></h3>
<p>A recursive solution can be written based on this simple algorithm: the number N is used as a countdown, keeping elements until it reaches the value 1. Then the current element is discarded and the process continues with a countdown reset.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">dropRec</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_dropRec</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">c</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="nc">Nil</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">_::tail</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_dropRec</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">h::tail</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_dropRec</span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_dropRec</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>As you can see the case <code>(1, _::tail)</code> restarts the process ignoring the current head of the list, while the more generic <code>(_, h::tail)</code> case stores the element in the result list.</p>
<h2 id="problem-17">Problem 17<a class="headerlink" href="#problem-17" title="Permanent link">¶</a></h2>
<h3 id="the-problem_1">The problem<a class="headerlink" href="#the-problem_1" title="Permanent link">¶</a></h3>
<p><strong>P17</strong> (*) Split a list into two parts.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">split</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">],</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">),</span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
</code></pre></div>
<h3 id="solution">Solution<a class="headerlink" href="#solution" title="Permanent link">¶</a></h3>
<p><code>List</code> objects provide a bunch of methods to interact with them, thus splitting may make use of several different ones. Very simple and straightforward solutions come from the <code>splitAt()</code> method</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">split</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">splitAt</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
</code></pre></div>
<p>using the two <code>take()</code> and <code>drop()</code> methods</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">split</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">n</span><span class="p">),</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>or using <code>take()</code> and <code>takeRight()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">split</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">n</span><span class="p">),</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">takeRight</span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">n</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>A list can be splitted also using recursion, however, using the given split position as a counter</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">split</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_split</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">c</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="nc">Nil</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="nc">Nil</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">h::tail</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_split</span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">res:::</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">)),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_split</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>where I basically keep extracting the head from <code>rem</code> appending it to <code>res</code> until the counter is 0.</p>
<h2 id="problem-18">Problem 18<a class="headerlink" href="#problem-18" title="Permanent link">¶</a></h2>
<h3 id="the-problem_2">The problem<a class="headerlink" href="#the-problem_2" title="Permanent link">¶</a></h3>
<p><strong>Pxx</strong> (**) Extract a slice from a list.
Given two indices, I and K, the slice is the list containing the elements from and including the Ith element up to but not including the Kth element of the original list. Start counting the elements with 0.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">slice</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">)</span>
</code></pre></div>
<h3 id="solution_1">Solution<a class="headerlink" href="#solution_1" title="Permanent link">¶</a></h3>
<p>As for the previous problem we may make use of the <code>List</code> type methods. The aptly named <code>slice()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">slice</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">start</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">end</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span>
<span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">slice</span><span class="p">(</span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="n">end</span><span class="p">)</span>
</code></pre></div>
<p>or a combination of <code>drop()</code> and <code>take()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">slice</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">i</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">take</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">drop</span><span class="w"> </span><span class="n">i</span>
<span class="p">}</span>
</code></pre></div>
<p>The recursive solution first drops the required number of elements from the head of the list. When the first index is exhausted the function starts dropping elements from the tail (using <code>init()</code>). The number of elements to be dropped is computed as <code>k - i</code> when the internal function is called.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">slice</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">i</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_slice</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">cl</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">rem</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">.</span><span class="n">init</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="p">,</span><span class="w"> </span><span class="n">h::rem</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_slice</span><span class="p">(</span><span class="n">cl</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">cr</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_slice</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="problem-19">Problem 19<a class="headerlink" href="#problem-19" title="Permanent link">¶</a></h2>
<h3 id="the-problem_3">The problem<a class="headerlink" href="#the-problem_3" title="Permanent link">¶</a></h3>
<p><strong>P19</strong> (**) Rotate a list N places to the left.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">rotate</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">rotate</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">,</span><span class="w"> </span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">))</span>
<span class="n">res1</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'j</span><span class="p">,</span><span class="w"> </span><span class="ss">'k</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'f</span><span class="p">,</span><span class="w"> </span><span class="ss">'g</span><span class="p">,</span><span class="w"> </span><span class="ss">'h</span><span class="p">,</span><span class="w"> </span><span class="ss">'i</span><span class="p">)</span>
</code></pre></div>
<h3 id="solution_2">Solution<a class="headerlink" href="#solution_2" title="Permanent link">¶</a></h3>
<p>Rotating a list has some caveats. First one must consider wrapping, so the first thing I did is to calculate the actual shift with the modulo operation. The second thing is that rotation can happen in both directions, and the case of negative shift can be converted to a positive one just adding the shift to the length of the list (being the shift negative this is actually a subtraction). Eventually we can perform the rotation which requires a composition of the output of <code>drop()</code> and <code>take()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">rotate</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">val</span><span class="w"> </span><span class="n">wrapn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">isEmpty</span><span class="p">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">length</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">wrapn</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">rotate</span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="n">wrapn</span><span class="p">)</span><span class="n">:::l</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">wrapn</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="problem-20">Problem 20<a class="headerlink" href="#problem-20" title="Permanent link">¶</a></h2>
<h3 id="the-problem_4">The problem<a class="headerlink" href="#the-problem_4" title="Permanent link">¶</a></h3>
<p><strong>P20</strong> (*) Remove the Kth element from a list.
Return the list and the removed element in a Tuple. Elements are numbered from 0.</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">removeAt</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">],</span><span class="w"> </span><span class="nc">Symbol</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">),</span><span class="ss">'b</span><span class="p">)</span>
</code></pre></div>
<h3 id="solution_3">Solution<a class="headerlink" href="#solution_3" title="Permanent link">¶</a></h3>
<p>There are two edge conditions in this problem. The first is when the list is empty, and the second is when we are asking for an index outside the list. Since an empty list has length 0 both conditions can be summarized checking if the requested index is greater or equal than the length of the list (the "or equal" part comes from the fact that lists are indexed starting from 0).</p>
<p>The simplest solution uses <code>take()</code> and <code>drop()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">removeAt</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">A</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="nc">NoSuchElementException</span>
<span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="n">:::l</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="n">n</span><span class="p">).</span><span class="n">tail</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>The problem with boundaries comes from the use of <code>tail()</code>, that cannot be applied to an empty list, while <code>take()</code> and <code>drop()</code> seamlessly work on empty lists and negative indexes. So using the <code>take()</code> counterpart <code>takeRight()</code> we could write</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">removeAt</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">A</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="n">:::l</span><span class="p">.</span><span class="n">takeRight</span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">n</span><span class="p">),</span><span class="w"> </span><span class="n">l</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>which automatically raises an <code>IndexOutOfBoundsException</code> when the requested index is outside the list. If we want a <code>NoSuchElementException</code>, however, we have to wrap the code with a <code>try</code> statement.</p>
<p>We can also use mapping, even if in this case its use is probably overkill</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">removeAt</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">A</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">zipWithIndex</span><span class="w"> </span><span class="n">filter</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">_2</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="p">.</span><span class="n">_1</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="n">l</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>this solution raises an <code>IndexOutOfBoundsException</code> when the index is outside the list, just like the previous one.</p>
<p>A recursive solution may use the index as a countdown value to get elements until the requested one pops up, then skipping it and getting the rest of the list.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">removeAtR</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">A</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_removeAtR</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">k</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="nc">A</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">rem</span><span class="p">)</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">h::tail</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">res:::tail</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="nc">Nil</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="nc">NoSuchElementException</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">h::tail</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">_removeAtR</span><span class="p">(</span><span class="n">k</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">_removeAtR</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>Problem 16 introduced me to new <strong>list methods</strong> <code>filter()</code> and <code>zipWithIndex()</code>. I met <strong>iterators</strong> and <strong>tuples</strong> for the first time and learned how to deal with them on a basic level. Problem 17 introduced the new <code>splitAt()</code> method and let me review <code>take()</code>, <code>takeRight()</code> and <code>drop()</code>. The recursive solution makes use of everything has been already discovered solving the previous problems. With problem 18 I learned a new method of the <code>List</code> type, <code>slice()</code>. The recursive solution is pretty straightforward but matching a tuple of three values requires some attention. I appreciate the <strong>syntactic sugar</strong> that allows to drop parenthesis when calling a function with a single argument, it makes the call resemble natural language. Problems 19 and 20 are just applications of the same methods.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 15 - Duplicate the elements of a list a given number of times2015-04-14T12:30:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-15-duplicate-the-elements-of-a-list-a-given-number-of-times/<p>Discussing how to replicate elements in a Scala list</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P15</strong> (**) Duplicate the elements of a list a given number of times.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">duplicateN</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">)</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>Problem 12 already taught me to use <code>fill()</code> to build lists of repeated elements so this could be a good occasion to use it again.</p>
<h2 id="solution">Solution<a class="headerlink" href="#solution" title="Permanent link">¶</a></h2>
<p>This problem is a generalization of the previous <a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-14-duplicate-the-elements-of-a-list/">problem 14</a> which required to duplicate the elements of a list. There we could build the list into an anonymous function with the <code>List(e, e)</code> syntax.</p>
<p>For this problem we have to use a more general solution, which is the <code>fill()</code> method of the <code>List</code> object (not class), already discovered in <a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-12-decode-a-run-length-encoded-list/">problem 12</a>. This method is expressed in a curried form, thus the two argument applications.</p>
<p>Again, since the result of <code>fill()</code> is a list, we have to flatten it through <code>flatMap()</code>.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">duplicateN</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">List</span><span class="p">.</span><span class="n">fill</span><span class="p">(</span><span class="n">n</span><span class="p">)(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Scala allows us to express the anonymous function in a shorter way, making use of the underscore wild card.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">duplicateN2</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nc">List</span><span class="p">.</span><span class="n">fill</span><span class="p">(</span><span class="n">n</span><span class="p">)(</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>Previous problems gave me all I needed to solve this one. I used <strong>anonymous functions</strong> and <strong>mapping</strong>, which are a very important component of Scala. I learned how to <strong>simplify an anonymous function</strong> using the underscore.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 14 - Duplicate the elements of a list2015-04-14T12:00:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-14-duplicate-the-elements-of-a-list/<p>Discussing how to duplicate elements of a list in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P14</strong> (*) Duplicate the elements of a list.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">duplicate</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">)</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>Once again (see <a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-12-decode-a-run-length-encoded-list/">problem 12</a>) a perfect task for <code>flatMap()</code> since for each element a list must be produced, but the resulting list shall be flat.</p>
<h2 id="solution">Solution<a class="headerlink" href="#solution" title="Permanent link">¶</a></h2>
<p>The function passed to <code>flatMap()</code> this time shall return a list with two elements for each element of the source list.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">duplicate</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>This problem didn't involve new concepts, but allowed me to test again <strong>mapping</strong> and <strong>anonymous</strong> functions.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 13 - Run-length encoding of a list (direct solution)2015-04-14T11:30:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-13-run-length-encoding-of-a-list-direct-solution/<p>Discussing how to process a whole list through the run-length encoding in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P13</strong> (**) Run-length encoding of a list (direct solution).
Implement the so-called run-length encoding data compression method directly. I.e. don't use other methods you've written (like P09's pack); do all the work directly.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">encodeDirect</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">Symbol</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">((</span><span class="mi">4</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="ss">'b</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="ss">'d</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="ss">'e</span><span class="p">))</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>Obviously the issue shouldn't be solved just copying all stuff from <a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-09-pack-consecutive-duplicates/">problem 09</a> and <a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-10-run-length-encoding-of-a-list/">problem 10</a> inside a single file. There shall be a way to build a single-function solution.</p>
<h2 id="spanning">Spanning<a class="headerlink" href="#spanning" title="Permanent link">¶</a></h2>
<p>Scala lists provide a <code>span()</code> method that splits the list in two. It scans all elements in order, storing them into a list while the given predicate (a function) is true. When the predicate is false <code>span()</code> stops and returns the two resulting lists.</p>
<p>It seems to be the perfect candidate for our job. We just have to recursively apply it obtaining two lists. The first list is made by equal elements, and can be reduced to a tuple, the second list is given to the recursive call.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">encodeDirect</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_encodeDirect</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">val</span><span class="w"> </span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_encodeDirect</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">((</span><span class="n">s</span><span class="p">.</span><span class="n">length</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">head</span><span class="p">)),</span><span class="w"> </span><span class="n">r</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_encodeDirect</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span><span class="w"> </span>
</code></pre></div>
<p>The predicate given to <code>span()</code> is <code>_ == rem.head</code>, an anonymous function that tests if the current element is equal to the first element. While this is always true for the first element, by definition, other elements can be equal or not, and the job of <code>span()</code> is to find where to split the list.</p>
<p>So example given in the problem runs through the following steps</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">)</span>
<span class="n">rem1</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem1</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem1</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'b</span><span class="p">)</span>
<span class="n">rem2</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem2</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem2</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">)</span>
<span class="n">rem3</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem3</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem3</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">)</span>
<span class="n">rem4</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem5</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem4</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem4</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">)</span>
<span class="n">rem5</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">rem6</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem5</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem5</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
<span class="n">rem6</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">()</span>
</code></pre></div>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>I learned another very useful method to <strong>split</strong> Scala lists, <code>span()</code>. I also used a <strong>complex expression</strong> in a case statement, as already done in problems 09 and 10.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 12 - Decode a run-length encoded list2015-04-14T11:00:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-12-decode-a-run-length-encoded-list/<p>Discussing how to implement run-length encoding in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P12</strong> (**) Decode a run-length encoded list.
Given a run-length code list generated as specified in problem P10, construct its uncompressed version.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">decode</span><span class="p">(</span><span class="nc">List</span><span class="p">((</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>The problem is simple, being just a reverse version of the last two problems. The target is to build a list from another one, so it should be possible to find both a recursive and a functional solution. The only problem is that we may easily build a list for each element, but we shall end up with a flat list. So <code>flatMap()</code> from <a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-07-flatten/">problem 07</a> will come in play again.</p>
<h2 id="the-recursive-solution">The recursive solution<a class="headerlink" href="#the-recursive-solution" title="Permanent link">¶</a></h2>
<p>Since I decided to use <code>flatMap()</code>, which basically acts like <code>map()</code> but then inserts the resulting list into the target list (indeed flattening it), I have to write a function that converts a <code>(Int, A)</code> tuple into a <code>List[A]</code>, where <code>A</code> is a type of choice.</p>
<p>The only issue in building lists in Scala is that the <code>:::</code> operator works with two lists, so we have to build a list with the current head to be able to append it.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">decode</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_expand</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="n">rem</span><span class="p">:(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_expand</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="p">))</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_expand</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The last call is a mapping. Each element is mapped into a list by the <code>_expand()</code> function, while <code>flatMap()</code> does the flattening job.</p>
<h2 id="the-functional-solution">The functional solution<a class="headerlink" href="#the-functional-solution" title="Permanent link">¶</a></h2>
<p>There is a simpler way that makes use of a function of the <code>List</code> object. Object and classes are two different entities in Scala, and objects are singletons that encapsulate constructor (and de-constructor) methods.</p>
<p>The <code>fill()</code> method is documented <a href="http://www.scala-lang.org/api/2.11.4/index.html#scala.collection.immutable.List$">here</a>, and we are interested now in the one-dimensional version. As you can see from the documentation, this function is curried (see <a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-04-length/">problem 04</a>) and accepts as first parameter the length of the list and as second parameter the element to put into the list itself.</p>
<p>We are just interested in repeating an element this time, so the function invocation is very simple</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">decode2</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">flatMap</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">List</span><span class="p">.</span><span class="n">fill</span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">_1</span><span class="p">)(</span><span class="n">e</span><span class="p">.</span><span class="n">_2</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Scala tuples may be indexed using the <code>_index</code> notation, starting from 1 (while lists are indexed from 0). Here, just like in the recursive solution, we have to use <code>flatMap()</code> to flatten the resulting list.</p>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>Writing this solution I renewed my knowledge of <strong>flatmapping</strong>, learned that Scala classes have <strong>companion objects</strong>, learned how to <strong>create lists</strong> and how to <strong>index tuples</strong>.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 11 - Modified run-length encoding2015-04-14T10:30:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-11-modified-run-length-encoding/<p>Discussing a variant of the run-length encoding in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P11</strong> (*) Modified run-length encoding.
Modify the result of problem P10 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 (N, E) terms.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">encodeModified</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Any</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">((</span><span class="mi">4</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="ss">'e</span><span class="p">))</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>The solution shall be a modification of that of <a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-10-run-length-encoding-of-a-list/">problem 10</a>, and the only difference is that this time we do not produce the same type of result for each element.</p>
<h2 id="choices">Choices<a class="headerlink" href="#choices" title="Permanent link">¶</a></h2>
<p>If the source element is a list with more than an element, we produce a tuple <code>(Int, A)</code>, where <code>A</code> is the actual type of elements in the list. If the source element is a list with a single element, we just produce that element, so the type is <code>A</code>.</p>
<p>In Scala this situation may be represented by means of <code>Either</code>, <code>Left</code> and <code>Right</code>. Good explanations of this matter may be found <a href="http://alvinalexander.com/scala/scala-either-left-right-example-option-some-none-null">here</a> and <a href="http://danielwestheide.com/blog/2013/01/02/the-neophytes-guide-to-scala-part-7-the-either-type.html">here</a>.</p>
<p>Given that, the solution is straightforward</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">encode</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">Either</span><span class="p">[</span><span class="nc">A</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">utils</span><span class="p">.</span><span class="n">packer</span><span class="p">.</span><span class="n">pack</span><span class="p">(</span><span class="n">l</span><span class="p">)</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">Left</span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">head</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">Right</span><span class="p">((</span><span class="n">e</span><span class="p">.</span><span class="n">length</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">head</span><span class="p">))</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>I prefer to express conditions through pattern matching, but the same code may be expressed with an <code>if/else</code> statement.</p>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>This time I learned how to use the three types <strong>Either</strong>, <strong>Left</strong> and <strong>Right</strong>. Reading the suggested posts I also dug into <strong>Option</strong>, <strong>Some</strong> and <strong>None</strong>, and the three similar types introduced with Scala 2.10 <strong>Try</strong>, <strong>Success</strong> and <strong>Failure</strong>.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 10 - Run-length encoding of a list.2015-04-14T10:00:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-14:/blog/2015/04/14/99-scala-problems-10-run-length-encoding-of-a-list/<p>Discussing how to compress a list in Scala using run-length encoding</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P10</strong> (*) Run-length encoding of a list.
Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as tuples (N, E) where N is the number of duplicates of the element E.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">encode</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">Symbol</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">((</span><span class="mi">4</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="ss">'b</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="ss">'d</span><span class="p">),</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="ss">'e</span><span class="p">))</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>The problem explicitly states "use the result of problem 09" (<a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-09-pack-consecutive-duplicates/">here</a>) so I think it's time for me to learn how to make and import libraries. The problem itself seems to be rather simple to solve.</p>
<h2 id="the-recursive-solution">The recursive solution<a class="headerlink" href="#the-recursive-solution" title="Permanent link">¶</a></h2>
<p>Given the availability of the <code>pack()</code> function from problem 09 the recursive solution just has to walk the packed list and convert each element (a list of equal elements) into a tuple. This is the tail recursive version</p>
<div class="highlight"><pre><span></span><code><span class="k">import</span><span class="w"> </span><span class="nn">utils</span><span class="p">.</span><span class="n">packer</span>
<span class="k">def</span><span class="w"> </span><span class="nf">encode</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_encode</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]):</span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::tail</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_encode</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">((</span><span class="n">h</span><span class="p">.</span><span class="n">length</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="p">.</span><span class="n">head</span><span class="p">)),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_encode</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">utils</span><span class="p">.</span><span class="n">packer</span><span class="p">.</span><span class="n">pack</span><span class="p">(</span><span class="n">l</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div>
<p>Note that I use the <code>utils.packer.pack()</code> function imported from a package which contains the code developed for problem 09.</p>
<p>To obtain the availability of the <code>pack()</code> function I first created a <em>package</em>. In Scala a package may be declared with the <code>package</code> keyword, but the functions cannot be declared at module-level, they have to be converted into methods of an object. So the content of the <code>utils.scala</code> file is</p>
<div class="highlight"><pre><span></span><code><span class="k">package</span><span class="w"> </span><span class="n">utils</span>
<span class="k">object</span><span class="w"> </span><span class="nc">packer</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">pack</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_pack</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">val</span><span class="w"> </span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="n">s</span><span class="p">),</span><span class="w"> </span><span class="n">r</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>In Scala, an <code>object</code> is a singleton, and it is used without instancing it. So the <code>pack()</code> method may be used in this file as <code>packer.pack()</code>. This file is then compiled with the Scala compiler</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>scalac<span class="w"> </span>utils.scala
</code></pre></div>
<p>producing a <code>utils</code> directory with the following files</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ls<span class="w"> </span>utils
packer<span class="nv">$$</span>anonfun<span class="nv">$1</span>.class
packer.class
packer$.class
</code></pre></div>
<p>This package may be directly used by any file in the same directory (e.g. through <code>scala program.scala</code>). If you plan to use it from another directory use the <code>-classpath</code> switch to include the right directory where the <code>utils</code> package may be found. (As an UNIX programmer, I hate single-dash Java long options, but they are here to stay)</p>
<h2 id="mapping">Mapping<a class="headerlink" href="#mapping" title="Permanent link">¶</a></h2>
<p>Mapping is, just like folding, a <em>functional</em> technique, because it applies a function to the elements of some collection. In Scala, the <code>map()</code> function of the <code>List</code> type produces a new list processing each element of the original list with the given function.</p>
<p>The function to process elements is very simple, since it has to pack together the length of the element (which is a list) and its head.</p>
<div class="highlight"><pre><span></span><code><span class="k">import</span><span class="w"> </span><span class="nn">utils</span><span class="p">.</span><span class="n">packer</span>
<span class="k">def</span><span class="w"> </span><span class="nf">encode</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[(</span><span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="nc">A</span><span class="p">)]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">utils</span><span class="p">.</span><span class="n">packer</span><span class="p">.</span><span class="n">pack</span><span class="p">(</span><span class="n">l</span><span class="p">)</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">length</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">head</span><span class="p">)</span><span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The expression <code>e => (e.length, e.head)</code> is an anonymous function that maps an element into a tuple.</p>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>With this problem I met <strong>packages</strong> for the first time, learned how to <strong>compile</strong> and add paths through <strong>classpath</strong>. The functional solution introduced me to <strong>mapping</strong>.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems Index2015-04-07T09:45:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-07:/blog/2015/04/07/99-scala-problems-index/<p>I decided to learn <a href="http://www.scala-lang.org/">Scala</a>. I looked for some good exercises for Scala programmers and found <a href="http://aperiodic.net/phil/scala/s-99/">S-99: Ninety-Nine Scala Problems</a>, and since writing about things helps me learning them I am going to write a post for each problem I manage to solve.</p>
<p>The official site provides solutions for the problems, so my solutions will obviously be influenced by those, when not the same.</p>
<p><strong>CAVEAT</strong>: I am a beginner so what I state in the following posts may be inaccurate and sometimes wrong. Please submit an issue on the blog <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page.</p>
<p>This is the index of the problems I already discussed. I kept the original title and difficulty ranking (asterisks)</p>
<ul>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-01-find-last-element/">P01</a> (*) Find the last element of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-02-find-last-nth/">P02</a> (*) Find the last but one element of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-03-find-kth/">P03</a> (*) Find the Kth element of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-04-length/">P04</a> (*) Find the number of elements of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-05-reverse/">P05</a> (*) Reverse a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-06-palindome/">P06</a> (*) Find out whether a list is a palindrome.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-07-flatten/">P07</a> (**) Flatten a nested list structure.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-08-eliminate-consecutive-duplicates/">P08</a> (**) Eliminate consecutive duplicates of list elements.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-09-pack-consecutive-duplicates/">P09</a> (**) Pack consecutive duplicates of list elements into sublists.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-10-run-length-encoding-of-a-list/">P10</a> (*) Run-length encoding of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-11-modified-run-length-encoding/">P11</a> (*) Modified run-length encoding.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-12-decode-a-run-length-encoded-list/">P12</a> (**) Decode a run-length encoded list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-13-run-length-encoding-of-a-list-direct-solution/">P13</a> (**) Run-length encoding of a list (direct solution).</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-14-duplicate-the-elements-of-a-list/">P14</a> (*) Duplicate the elements of a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/04/14/99-scala-problems-15-duplicate-the-elements-of-a-list-a-given-number-of-times/">P15</a> (**) Duplicate the elements of a list a given number of times.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/05/13/99-scala-problems-16-20/#problem-16">P16</a> (**) Drop every Nth element from a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/05/13/99-scala-problems-16-20/#problem-17">P17</a> (*) Split a list into two parts.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/05/13/99-scala-problems-16-20/#problem-18">P18</a> (**) Extract a slice from a list.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/05/13/99-scala-problems-16-20/#problem-19">P19</a> (**) Rotate a list N places to the left.</li>
<li><a href="https://www.thedigitalcatonline.com/blog/2015/05/13/99-scala-problems-16-20/#problem-20">P20</a> (*) Remove the Kth element from a list.</li>
</ul>99 Scala Problems 09 - Pack consecutive duplicates of list elements into sublists2015-04-07T09:40:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-07:/blog/2015/04/07/99-scala-problems-09-pack-consecutive-duplicates/<p>Discussing how to groups values inside a list in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P09</strong> (**) Pack consecutive duplicates of list elements into sublists. If a list contains repeated elements they should be placed in separate sublists.</p>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">pack</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'b</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'d</span><span class="p">),</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>This is similar to <a href="https://www.thedigitalcatonline.com/blog/2015/04/07/99-scala-problems-08-eliminate-consecutive-duplicates/">problem 08</a> but has an important difference: the result will be a list of lists. When dealing with multi-level structures like these, it is very easy to get lost, so I expect to find a recursive solution with a lot of cases or complex pattern guards.</p>
<h2 id="the-recursive-solution">The recursive solution<a class="headerlink" href="#the-recursive-solution" title="Permanent link">¶</a></h2>
<p>The tail recursive solution is easier to write than the standard recursive one. The resulting list we are building is a <code>List[List[A]]</code>, while the remainder is just a plain list <code>List[A]</code>.</p>
<p>The first case is straightforward. The second case extracts an element from the list and, if the result is empty of the result doesn't contain that element, appends a new list. Pay attention: we have to check <code>res.last.head</code> since <code>res</code> is a list of lists. So <code>res.last</code> is the last list we put into <code>res</code> and its head is the repeated element. Obviously the same thing is accomplished by checking <code>res.last.last</code>, since this algorithm packs together equal values. The third case covers the situation in which the extracted element is already in the last list or <code>res</code>, so we have to modify the latter. To do this we separate <code>res</code> in <code>res.init</code> and <code>res.last</code>, append <code>h</code> to <code>res.last</code> (<code>res.last:::List(h)</code>) and merge again the two pieces.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">pack</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_pack</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::tail</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">isEmpty</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">res</span><span class="p">.</span><span class="n">last</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">h</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">)),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::tail</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">init:::</span><span class="nc">List</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">last:::</span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">)),</span><span class="w"> </span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>A very simpler solution, however, comes from the <code>span()</code> method of <code>List</code> objects. This method "splits this list into a prefix/suffix pair according to a predicate."</p>
<p>In other words, <code>span()</code> selects the elements of the list (preserving order) that satisfy a given function until it finds an element for which the function returns false. This is exactly what we need to pack consecutive duplicate elements. The strategy is to pack all elements with the same value of the list head element, then store this list and recursively call <code>span()</code> on the remaining list.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">pack</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">_pack</span><span class="p">(</span><span class="n">res</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]],</span><span class="w"> </span><span class="n">rem</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">res</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">val</span><span class="w"> </span><span class="p">(</span><span class="n">s</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">],</span><span class="w"> </span><span class="n">r</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">])</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rem</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">rem</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="n">res:::</span><span class="nc">List</span><span class="p">(</span><span class="n">s</span><span class="p">),</span><span class="w"> </span><span class="n">r</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">_pack</span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">l</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>The function I pass to <code>span()</code> is simply <code>{ _ == rem.head }</code> since the method gives the function each element in the list.</p>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>This problem helped me enhance my knowledge of <strong>pattern guards</strong> and Scala <strong>anonymous functions</strong>. The solution with <code>span()</code> includes a pattern match that leads to a <strong>block expression</strong>, which was somehow a syntactical blind guess for me, but ended up being perfectly valid.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>99 Scala Problems 08 - Eliminate consecutive duplicates of list elements2015-04-07T09:35:00+01:002019-02-28T10:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2015-04-07:/blog/2015/04/07/99-scala-problems-08-eliminate-consecutive-duplicates/<p>Discussing strategies to clean up lists in Scala</p><h2 id="the-problem">The problem<a class="headerlink" href="#the-problem" title="Permanent link">¶</a></h2>
<p><strong>P08</strong> Eliminate consecutive duplicates of list elements. 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>
<p>Example:</p>
<div class="highlight"><pre><span></span><code><span class="n">scala</span><span class="o">></span><span class="w"> </span><span class="n">compress</span><span class="p">(</span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">))</span>
<span class="n">res0</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">Symbol</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'b</span><span class="p">,</span><span class="w"> </span><span class="ss">'c</span><span class="p">,</span><span class="w"> </span><span class="ss">'a</span><span class="p">,</span><span class="w"> </span><span class="ss">'d</span><span class="p">,</span><span class="w"> </span><span class="ss">'e</span><span class="p">)</span>
</code></pre></div>
<h2 id="initial-thoughts">Initial thoughts<a class="headerlink" href="#initial-thoughts" title="Permanent link">¶</a></h2>
<p>This task seems to be easy to accomplish. It should be all about filtering incoming elements based on the last element added to the list.</p>
<h2 id="the-recursive-solution">The recursive solution<a class="headerlink" href="#the-recursive-solution" title="Permanent link">¶</a></h2>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="nc">Nil</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">Nil</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::</span><span class="nc">List</span><span class="p">()</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::tail</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">h</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">tail</span><span class="p">.</span><span class="n">head</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">compress</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">h::tail</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">h::compress</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>Instead of adding one element and then discarding the successive if equal, the point here is to discard elements until a new one pops up.</p>
<h2 id="folding">Folding<a class="headerlink" href="#folding" title="Permanent link">¶</a></h2>
<p>The folding methods of <code>List</code> types are very suitable for this task, as they scan the whole list carrying the result of previous applications.</p>
<p>I already used <code>foldLeft()</code> so this was my first pick</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">foldLeft</span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]())</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="nc">List</span><span class="p">(),</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nc">List</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">.</span><span class="n">last</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">ls</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">ls:::</span><span class="nc">List</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>The initial value given to the folding method is an empty list. Then if the previous result is empty (i.e. when scanning the first element) the result is a list with that element. If the current element is already in the result (second case) the result is returned unchanged. Otherwise, the new element is appended at the end of the result.</p>
<p>Since appending a list to an empty list is just like returning the list itself we may join the first and third cases with a modified pattern guard</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">foldLeft</span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]())</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">.</span><span class="n">isEmpty</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">ls</span><span class="p">.</span><span class="n">last</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">ls:::</span><span class="nc">List</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">ls</span>
<span class="p">}</span>
</code></pre></div>
<p>Left folding implies appending new values at the end of the result list, which is syntactically less straightforward than appending at the beginning (<code>list:::List(t)</code> vs <code>h::list</code>). So we may fold from right with <code>foldRight()</code></p>
<div class="highlight"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">[</span><span class="nc">A</span><span class="p">](</span><span class="n">l</span><span class="p">:</span><span class="w"> </span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]):</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">foldRight</span><span class="p">(</span><span class="nc">List</span><span class="p">[</span><span class="nc">A</span><span class="p">]())</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="w"> </span><span class="n">ls</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ls</span><span class="p">.</span><span class="n">isEmpty</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">ls</span><span class="p">.</span><span class="n">head</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">e::ls</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="w"> </span><span class="n">ls</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">ls</span>
<span class="p">}</span>
</code></pre></div>
<p>Remember that <code>foldLeft()</code> accepts a tuple in the form <code>(result, element)</code>, while <code>foldRight()</code> wants a tuple in the form <code>(element, result)</code>.</p>
<h2 id="final-considerations">Final considerations<a class="headerlink" href="#final-considerations" title="Permanent link">¶</a></h2>
<p>Folding became more clear with this exercise. It's a good thing to learn ho to reverse algorithms to use <code>foldLeft()</code> or <code>foldRight()</code> according to the task we are performing.</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>