Jekyll2022-08-28T02:38:04+00:00https://rage.powered.ninja/feed.xmlRage Powered NinjaCode musings of a disillusioned web developer.Francis WhittleGreedy expression of the best months – Perl weekly challenge 192019-07-29T14:08:30+00:002019-07-29T14:08:30+00:00https://rage.powered.ninja/2019/07/29/-best-months<h2 id="the-best-months-to-be-alive-in">The best months to be alive in</h2>
<p>The first challenge this week is to list all the months between 1900 and 2019
with three weekends in them (Friday, Saturday, Sunday).</p>
<p>This in itself sounds like hard work, so let’s be tricky instead. We know that
in a 28 day period there are exactly 4 weekends, so in order for a month to have
5 weekends, it must have at least 3 days more than that, or 31 days. As we know
that the longest months have 31 days it follows that we’re therefore looking for
<em>only</em> months that have 31 days. First criteria.</p>
<p>We can also determine that the last three days must be Friday, Saturday, Sunday,
which also means that the first day of the month must be a Friday. Second
criteria.</p>
<p>So the simplified criteria for this challenge are that we’re looking for 31 day
months that start on a Friday.</p>
<p>We can do this pretty easily with a sequence:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="p">(</span><span class="nv">Date</span><span class="o">.</span><span class="k">new</span><span class="p">('</span><span class="s1">1900-01-01</span><span class="p">'),</span> <span class="o">*.</span><span class="nv">later</span><span class="p">(:</span><span class="mi">1</span><span class="nv">month</span><span class="p">)</span> <span class="o">...</span> <span class="nv">Date</span><span class="o">.</span><span class="k">new</span><span class="p">('</span><span class="s1">2019-12-01</span><span class="p">'))</span><span class="o">.\</span>
<span class="nb">grep</span><span class="p">({</span><span class="o">.</span><span class="nv">day</span><span class="o">-</span><span class="nv">of</span><span class="o">-</span><span class="nv">week</span> <span class="o">==</span> <span class="mi">5</span> <span class="ow">and</span> <span class="o">.</span><span class="nv">days</span><span class="o">-</span><span class="nv">in</span><span class="o">-</span><span class="nv">month</span> <span class="o">==</span> <span class="mi">31</span><span class="p">});</span></code></pre></figure>
<p>Which gives a bunch of Dates in YYYY-MM-DD format, so let’s neaten it up with an
enum of months and mapped output:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">enum</span> <span class="nv">Month</span> <span class="err">«</span><span class="p">:</span><span class="mi">1</span><span class="nv">January</span> <span class="nv">February</span> <span class="nv">March</span> <span class="nv">April</span> <span class="nv">May</span> <span class="nv">June</span> <span class="nv">July</span> <span class="nv">August</span> <span class="nv">September</span> <span class="nv">October</span> <span class="nv">November</span> <span class="nv">December</span><span class="err">»</span><span class="p">;</span>
<span class="p">(</span><span class="nv">Date</span><span class="o">.</span><span class="k">new</span><span class="p">('</span><span class="s1">1900-01-01</span><span class="p">'),</span> <span class="o">*.</span><span class="nv">later</span><span class="p">(:</span><span class="mi">1</span><span class="nv">month</span><span class="p">)</span> <span class="o">...</span> <span class="nv">Date</span><span class="o">.</span><span class="k">new</span><span class="p">('</span><span class="s1">2019-12-01</span><span class="p">'))</span><span class="o">.\</span>
<span class="nb">grep</span><span class="p">({</span><span class="o">.</span><span class="nv">day</span><span class="o">-</span><span class="nv">of</span><span class="o">-</span><span class="nv">week</span> <span class="o">==</span> <span class="mi">5</span> <span class="ow">and</span> <span class="o">.</span><span class="nv">days</span><span class="o">-</span><span class="nv">in</span><span class="o">-</span><span class="nv">month</span> <span class="o">==</span> <span class="mi">31</span><span class="p">})</span><span class="o">.\</span>
<span class="nb">map</span><span class="p">({"</span><span class="s2">{Month(.month)} {.year}</span><span class="p">"})</span><span class="err">»</span><span class="o">.</span><span class="nv">say</span><span class="p">;</span></code></pre></figure>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-019/fjwhittle/perl6/ch-1.p6">Here be codeses</a></p>
<h2 id="greedy-lines-are-regularly-expressed">Greedy lines are regularly expressed.</h2>
<p>The second challenge is to implement line wrapping using the greedy algorithm.</p>
<p>Because the greedy algorithm just inserts as many words as it can onto a single
line, it never needs to re-evaluate past rows, so we can do this in a fairly
straightforward way by combing the input with a regular expression, and
<code class="language-plaintext highlighter-rouge">put</code>ting the results.</p>
<p>For just a paragraph, we should only need the comparatively simple:</p>
<pre>
/ \s * <( <-[ \n ]> ** { 1..($column-1) } \S )> [ \s+ || $ ] /
</pre>
<p>Which will find:</p>
<ul>
<li>Up to the specified column less 1 of non-newline characters, followed by a
non-whitespace character.</li>
<li>Trailing whitespace – which is discarded; or the end of input</li>
</ul>
<p>However this will discard the first <em>$column</em> × <em>n</em> characters of any word
that’s longer than the specified column length. So we branch it:</p>
<pre>
/ || \s * <( <-[ \n ]> ** { 1..($column-1) } \S )> [ \s + || $ ]
|| \S ** { $column }
/
</pre>
<p>Now we aren’t losing large amounts of really long words. Yes I added an extra
<code class="language-plaintext highlighter-rouge">||</code> at the start – Perl6 regexes let you do that, as the empty branch before
never matches, and IMO it neatens things up a bit.</p>
<p>But to go overboard a bit, we can also handle multiple paragraphs separated by
blank lines:</p>
<pre>
/ || )> \s *? \n
|| <( <-[ \n ]> ** { 1..($column-1) } \S )>
<?before [ \s || $ ]> <[ \s ] - [ \n ]>* \n ?
|| \S ** { $column }
/
</pre>
<p>Now we’ve re-arranged things a bit so:</p>
<ul>
<li>The first branch matches trailing whitespace and whitespace only lines, but
gives an empty string so when we <code class="language-plaintext highlighter-rouge">put</code> this match we <em>only</em> output a newline.</li>
<li>The second branch will now only suck up whitespace up to a single newline.</li>
</ul>
<p>This preserves any paragraph breaks.</p>
<p>Insert this into a <code class="language-plaintext highlighter-rouge">.comb()</code> and <code class="language-plaintext highlighter-rouge">put</code> the output, and Bob’s yer uncle.</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-019/fjwhittle/perl6/ch-2.p6">Check it out</a>.</p>FrancisThe best months to be alive inMultitudinal Uniform Resource Parsing – Perl weekly challenge, week 172019-07-21T13:28:22+00:002019-07-21T13:28:22+00:00https://rage.powered.ninja/2019/07/21/-uniform-resource-parsing<p>The time between posts should be smaler than this.</p>
<h2 id="ack-part-one-wrote-itself">Ack, part one wrote itself</h2>
<p>The source for my solution to part one of this week’s challenge looks pretty
similar to the question.</p>
<p>This is because of Perl 6’s built in support for multi dispatch. 3 function
definitions; one symbol; branching recursions; no ifs or switches.</p>
<p>So I thought, what can I do to make this more interesting?</p>
<p>Coincidentally, for large values of m and n (mostly m), A(m,n) can be quite
slow. Also, it could be called many times for the same values of m and n.</p>
<p>So why not cache it?</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="c1"># Anonymous cache handler.</span>
<span class="nv">&A</span><span class="o">.</span><span class="nv">wrap:</span> <span class="o">-></span> <span class="nv">$m</span><span class="p">,</span> <span class="nv">$n</span> <span class="p">{</span> <span class="o">.</span><span class="p">[</span><span class="nv">$m</span><span class="p">;</span><span class="nv">$n</span><span class="p">]</span> <span class="sr">//</span><span class="o">=</span> <span class="nv">callsame</span> <span class="p">}</span> <span class="nv">given</span> <span class="nv">Array</span><span class="o">.</span><span class="k">new</span><span class="p">;</span></code></pre></figure>
<p>What this does:</p>
<ol>
<li>Creates a new Array and sets it as the topic</li>
<li>Wraps every symbol called A (there’s three of them)</li>
</ol>
<p>Every time the wrapper is called, it retrieves the cached result for a given m
and n, first setting them by calling the wrapped function <em>only</em> if no such
value is defined.</p>
<p>Alternatively there’s built in behaviour for this if you mark the prototype as
<code class="language-plaintext highlighter-rouge">is cached</code>, but then you (a) have to declare <code class="language-plaintext highlighter-rouge">use experimental :cached</code> and (b)
get a caching mechanism that’s not quite so optimised for this use case.</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-017/fjwhittle/perl6/ch-1.p6">Obligatory github link</a></p>
<h2 id="part-two-sort-of-wrote-itself-too">Part two sort of wrote itself, too.</h2>
<p>Okay, so not quite. However, there’s a <a href="https://www.w3.org/Addressing/URL/5_URI_BNF.html">BNF available</a>
for URI format (the example given isn’t a URL, or in fact a URI as <code class="language-plaintext highlighter-rouge">jdbc:mysql</code>
is not a valid scheme owed to the colon, but it’s close to a URI than a URL).</p>
<p>Converting BNF to Perl 6 Grammar syntax is pretty straightforward. Mostly. Up
to a point. I put dots in front of a lot of parts we don’t actually care about.</p>
<p>Anyway, I wanted to actually talk about action classes again, since last time I
sort of glossed over time, but my blog post was referred to as though it was
some kind of useful reference.</p>
<p>The Action class - actually an instance of it is generally more useful – is
passed into the <code class="language-plaintext highlighter-rouge">.parse</code> method of a Grammar. Each method in the class is named
corresponding to a rule, token, or regex in the Grammar you’re parsing that you
want to perform an action with.</p>
<p>Each method is called immediately after its corresponding element is matched,
and is passed the resulting <code class="language-plaintext highlighter-rouge">Match</code> when this happens. It’s convenient to use
<code class="language-plaintext highlighter-rouge">$/</code> as the name of the passed in Match parameter, as you can refer to
sub-matches as <code class="language-plaintext highlighter-rouge">$<sub-match></code> in your method.</p>
<p>This time our action class, <code class="language-plaintext highlighter-rouge">A::URLish</code>, has two methods, because on the whole
we just want to stringify our matches directly.</p>
<p><code class="language-plaintext highlighter-rouge">TOP</code> is run when the whole thing matches. This creates an object of type URL
from (mostly) the strings that were matched by submatches of the Grammar as a
whole. The exceptions are the <code class="language-plaintext highlighter-rouge">.query</code> property, which is built up into a hash
from the <code class="language-plaintext highlighter-rouge"><param></code> elements of the <code class="language-plaintext highlighter-rouge"><query></code> submatch, and the <code class="language-plaintext highlighter-rouge">.userinfo</code>
property, which is “made” by another method specially for it.</p>
<p>This is where things get cooler.</p>
<p>Grammars allow you to specify a prototype for a kind of multi-dispatch
subexpression. In our case, the <code class="language-plaintext highlighter-rouge"><userinfo></code> expression has been defined this
way, so that we have a regex <code class="language-plaintext highlighter-rouge">userinfo:sym<user-pass></code> that parses specifically
a <code class="language-plaintext highlighter-rouge"><user>:<password></code> style authentication string, but when we’re referring to
it later, either in the Grammar or the Actions class, we only have to say
<code class="language-plaintext highlighter-rouge"><userinfo></code>. In this way, we could extend it later to accept a different style
of authentication string.</p>
<p>In the action class, we just write a <code class="language-plaintext highlighter-rouge">method userinfo:sym<user-pass></code> which
makes a <code class="language-plaintext highlighter-rouge">URL::UserInfo</code> object (it would be better if this were a role our
specific class <code class="language-plaintext highlighter-rouge">does</code>), and when we call <code class="language-plaintext highlighter-rouge">$<userinfo>.made</code> in the <code class="language-plaintext highlighter-rouge">TOP</code> method,
this is what we get back. Note how the calling function doesn’t need to know
which particular userinfo symbol we’re calling, just that it was matched and
made by <em>some</em> userinfo. Polymorphism in regular expression parsers.</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-017/fjwhittle/perl6/ch-2.p6">Also you can find this on github</a></p>
<p>Apologies for the poor quality explanation.</p>
<p>‘til next time…</p>FrancisThe time between posts should be smaler than this.Hashed up Sequencing – Perl weekly challenge, week 142019-06-30T03:13:30+00:002019-06-30T03:13:30+00:00https://rage.powered.ninja/2019/06/30/-hashed-up-sequencing<p>It’s been 4 weeks; well past time to blog again; this time for <a href="https://perlweeklychallenge.org/blog/perl-weekly-challenge-010/">Perl Weekly
Challenge 014</a></p>
<h2 id="what-the-van-eck">What the Van Eck?</h2>
<p>The first challenge for me this week was to go to the Wikipedia page, read what
it was saying, and try to figure out exactly what the Van Eck sequence is.</p>
<p>This was at 10pm and I’d spent all day learning to adapt to Fedora after
installing that on my new laptop (and discovering while trying to attach a
NASalike via SSH to my existing workstation that I’d set up SSH to immediately
launch a docker container that sandboxed my user into my home directory, thus
causing nothing to work as expected). After some heavy screen glaring I managed
to arrive at a re-interpretation as three rules:</p>
<ul>
<li><em>a</em><sub>0</sub> = 0</li>
<li><em>a</em><sub><em>n</em> + 1</sub> = <em>a</em><sub><em>n</em></sub> - <em>a</em><sub><em>m</em></sub> when <em>m</em> is
the largest index < <em>n</em> of <em>a</em> having <em>a</em><sub><em>m</em></sub> = <em>a</em><sub><em>n</em></sub></li>
<li><em>a</em><sub><em>n</em> + 1</sub> = 0 when the conditions for <em>m</em> cannot be met.</li>
</ul>
<p>This was sufficient for me to then confuse myself into tyring to store the next
<em>m</em> and <em>n</em> pair for a given value of <em>a</em> in a hash and fill everything up with
0 in a gather / take loop.</p>
<p>I did a lot of filling everything up with 0.</p>
<p>I replaced this first implementation (sorry, I didn’t save this source so you
could all laugh at it) with an eager list generation that would count back from
the current <em>n</em> to 0 instead:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">$m</span> <span class="o">=</span> <span class="nv">Van_Eck</span><span class="p">[</span><span class="nv">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nv">$n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">...</span><span class="mi">0</span><span class="p">]:</span><span class="nv">k</span><span class="o">.</span><span class="nv">first</span><span class="p">({</span><span class="nv">Van_Eck</span><span class="p">[</span><span class="vg">$_</span><span class="p">]</span> <span class="o">==</span> <span class="nv">Van_Eck</span><span class="p">[</span><span class="nv">$n</span><span class="p">]});</span>
<span class="nv">take</span> <span class="nb">defined</span><span class="p">(</span><span class="nv">$m</span><span class="p">)</span> <span class="p">??</span> <span class="nv">$n</span> <span class="o">-</span> <span class="nv">$m</span> <span class="o">!!</span> <span class="mi">0</span><span class="p">;</span></code></pre></figure>
<p>This works, but is quite slow, probably mainly because of the eager list
generation. A keen observer might also notice that <code class="language-plaintext highlighter-rouge">Van_Eck[max(0, $n-1)...0]:k</code>
is a bit silly, given that getting the keys of a list that you’ve generated by
specifying the keys of another list is just going to give you the same list
you’ve specified back, so I may as well have written <code class="language-plaintext highlighter-rouge">(max(0, $n-1)...0)</code>, but I
went to bed and discovered this the next morning instead, laughed out loud, and
fixed it; my 7 year old daughter also thought it funny.</p>
<p>This didn’t solve the speed issue though (even if said problem was only
noticeable when you gave the program an obscene upper bound), so I revisited
using a hash to find the highest index the same as <em>a<sub>n</sub></em> and the
sleep-having version of myself quickly realised that I only needed to store one
index per hash element, and whether such an <em>m</em> existed could be determined
using the <code class="language-plaintext highlighter-rouge">:exists</code> adverb.</p>
<p>After a little bit of failing to realise I never needed to explicitly update
<code class="language-plaintext highlighter-rouge">%m{0}</code> (and thus filling everything up with 0 again) I finally managed to come
up with something that wouldn’t stall massively when asked to find 2000 elements
in the sequence:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="o">\</span><span class="nv">Van_Eck</span> <span class="p">:</span><span class="o">=</span> <span class="nv">gather</span> <span class="p">{</span>
<span class="nv">take</span> <span class="nv">$start</span><span class="p">;</span>
<span class="k">my</span> <span class="nv">%m</span> <span class="o">=</span> <span class="nv">$start</span> <span class="o">=></span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="o">^</span><span class="err">∞</span> <span class="o">-></span> <span class="nv">$n</span> <span class="p">{</span>
<span class="nv">take</span> <span class="nv">%m</span><span class="p">{</span><span class="nv">Van_Eck</span><span class="p">[</span><span class="nv">$n</span><span class="p">]}:</span><span class="nb">exists</span> <span class="p">??</span> <span class="nv">$n</span> <span class="o">-</span> <span class="nv">%m</span><span class="p">{</span><span class="nv">Van_Eck</span><span class="p">[</span><span class="nv">$n</span><span class="p">]}</span> <span class="o">!!</span> <span class="mi">0</span><span class="p">;</span>
<span class="nv">%m</span><span class="p">{</span><span class="nv">Van_Eck</span><span class="p">[</span><span class="nv">$n</span><span class="p">]}</span> <span class="o">=</span> <span class="nv">$n</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Worth noting is that <code class="language-plaintext highlighter-rouge">$n</code> is always one behind the index of the current value
being taken.</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-014/fjwhittle/perl6/ch-1.p6">Github link to solution</a></p>
<h2 id="spelling-with-the-united-states">Spelling with the United States</h2>
<p>Perl 6 makes the meat of this almost trivial. Create a set of the states’
abbreviations (I zipped these into a hash of the states’ names for later
reference), sort all the even length words you have (e.g.
<code class="language-plaintext highlighter-rouge">/usr/share/dict/words</code>) into longest to shortest order, then find the first list
element where a comb of 2-letter sequences of the word is a subset of the
abbreviations.</p>
<p>Using the hash of abbreviation => name I then print out which states spelt the
word and the word itself.</p>
<p>Apparently, the longest spellable word in the British English dictionary on my
system is cacogalactia, which apparently means that California, Colorado,
Georgia, Louisiana, Connecticut & Iowa are together <a href="https://www.wordnik.com/words/cacogalactia">states of bad
milk</a>…</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-014/fjwhittle/perl6/ch-2.p6">Github link to solution</a></p>
<h2 id="what-time-is-it-in--">What time is it in … ?</h2>
<p>This week’s optional API challenge was to Find the given city current time using
the Geo DB Cities API.</p>
<p>The Geo DB Cities API has an endpoint that doesn’t require an API key, which is
a refreshing change. The documentation on what that end point <em>is</em> seemed to be
non-existent, though; after some hunting around in the network panel of Firefox
on their demo pages I found what appeared to be it.</p>
<p>I elected again (Ah, I did the optional challenge in
<a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-012/fjwhittle/perl6/ch-3.p6">week 12</a>,
but didn’t blog that one) to use <code class="language-plaintext highlighter-rouge">Cro::Http::Client</code> to do the heavy lifting of
HTTP connections, and don’t seem to be able to find a URL encoding function for
it, so I reused the routine I put together for this last time, but with support
for turning spaces into <code class="language-plaintext highlighter-rouge">+</code>:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">sub </span><span class="nf">url</span><span class="p">-part-encode (Str(Cool) $in --> Str) {</span>
<span class="nv">$in</span><span class="o">.</span><span class="nv">trans:</span> <span class="p">(</span><span class="o">|<!</span> <span class="c1"># $ % & ' ( ) * + , / : ; = ? @ [ ]>, ' ') => (|<%21 %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D>, '+')</span>
<span class="p">}</span></code></pre></figure>
<p>Pretty trivial, but I in no way endorse this as a complete solution for input
sanitation. Someone please tell me if I’ve missed something that does this in a
more bulletproof manner.</p>
<p><code class="language-plaintext highlighter-rouge">Cro::Http::Client</code> is pretty straightforward to use. You can create a defined
instance of it or not, then use the <code class="language-plaintext highlighter-rouge">get</code> method (or <code class="language-plaintext highlighter-rouge">post</code>, or <code class="language-plaintext highlighter-rouge">request</code> as
appropriate) to access the data you require. This creates a promise that
includes various methods for getting the response, including <code class="language-plaintext highlighter-rouge">body</code> which will
automatically convert JSON into Perl 6 structures for you. This itself returns a
Promise, which seems a bit awkward, although I’m sure there’s a reason for it.</p>
<p>Which brings me onto a new gripe, which is that chaining Promises together feels
awkward; I feel like using a <code class="language-plaintext highlighter-rouge">Promise</code> in sink context at the end of a <code class="language-plaintext highlighter-rouge">then</code>
block should chain automatically like it does in ECMAScript6, but it seems they
don’t, so I end up with awkward chains like:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="nv">$geodb</span><span class="o">-</span><span class="nv">client</span><span class="o">.</span><span class="nv">get</span><span class="p">(</span><span class="o">...</span><span class="p">)</span><span class="o">.</span><span class="k">then</span><span class="p">({</span> <span class="nv">await</span> <span class="o">.</span><span class="nv">result</span><span class="o">.</span><span class="nv">body</span> <span class="p">})</span><span class="o">.</span><span class="k">then</span><span class="p">({</span> <span class="k">if</span> <span class="k">my</span> <span class="nv">$cityid</span> <span class="o">=</span> <span class="o">.</span><span class="nv">result</span><span class="o"><</span><span class="nv">data</span><span class="o">></span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o"><</span><span class="nv">id</span><span class="o">></span> <span class="p">{</span><span class="o">...</span><span class="p">}</span> <span class="p">});</span></code></pre></figure>
<p>or worse:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="o">.</span><span class="k">then</span><span class="p">({</span> <span class="o">.</span><span class="nv">result</span><span class="o">.</span><span class="nv">body</span> <span class="p">})</span><span class="o">.</span><span class="k">then</span><span class="p">({</span> <span class="k">if</span> <span class="k">my</span> <span class="nv">$cityid</span> <span class="o">=</span> <span class="o">.</span><span class="nv">result</span><span class="o">.</span><span class="nv">result</span><span class="o"><</span><span class="nv">data</span><span class="o">></span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o"><</span><span class="nv">id</span><span class="o">></span> <span class="p">{</span><span class="o">...</span><span class="p">}</span> <span class="p">})</span></code></pre></figure>
<p>Maybe I’ve missed something? Maybe I’ve spent too long in the browser… I guess
given that in Diwali <code class="language-plaintext highlighter-rouge">await</code> no longer blocks a thread, it may as well be
written as:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="o">.</span><span class="k">then</span><span class="p">({</span> <span class="k">if</span> <span class="k">my</span> <span class="nv">$cityid</span> <span class="o">=</span> <span class="nv">await</span><span class="p">(</span><span class="o">.</span><span class="nv">result</span><span class="o">.</span><span class="nv">body</span><span class="p">)</span><span class="o">.<</span><span class="nv">data</span><span class="o">></span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o"><</span><span class="nv">id</span><span class="o">></span> <span class="p">{</span><span class="o">...</span><span class="p">}</span> <span class="p">})</span></code></pre></figure>
<p>This is particularly relevant in this case, because when you have a city name,
you have to make an API call to turn that into an ID, and <strong>then</strong> you can call
the dateTime endpoint on that city ID, so that’s 4 Promises.</p>
<p>I’m also struggling with error handling inside <code class="language-plaintext highlighter-rouge">then</code> blocks. I want to <code class="language-plaintext highlighter-rouge">fail</code>,
but end up with internal MoarVM errors (tried to unwind entire stack…). I guess
I have quite a bit to learn there, but didn’t feel like following it to the
bitter end this time around.</p>
<p><a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-014/fjwhittle/perl6/ch-3.p6">Github link to solution</a>.</p>FrancisIt’s been 4 weeks; well past time to blog again; this time for Perl Weekly Challenge 014Obiective Romanos grammaticam – Perl weekly challenge, week 102019-06-02T00:07:37+00:002019-06-02T00:07:37+00:00https://rage.powered.ninja/2019/06/02/-obiective-romanos-grammaticam<p>My high school Latin teachers are now writhing in horror because of my blog post
title for the
<a href="https://perlweeklychallenge.org/blog/perl-weekly-challenge-010/">Perl Weekly Challenge 010</a></p>
<h2 id="class-action-against-roman-grammar">Class action against Roman grammar</h2>
<p>One of the super strong parts of the Perl 6 language is the ability to structure
your regular expressions into expressive and easy to understand grammars, and
pair them with a class that operates on each matching sub-expression in a sort
of love letter to hierarchical abstract syntax trees.</p>
<p>This is great for turning a string of specific letters into a number using a
vaguely defined set of rules – many people would (<strong>almost</strong> correctly) say that
<code class="language-plaintext highlighter-rouge">CMCMXLXLIIIIII</code> is not a valid Roman numeral, but that shouldn’t stop us from
parsing it.</p>
<p>So I put together a grammar where each part of the input is parsed as:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="p">[</span> <span class="o"><</span><span class="nv">prefix</span><span class="o">></span> <span class="o"><</span><span class="nv">numeral</span><span class="o">></span> <span class="p">]</span><span class="o">*</span> <span class="o"><</span><span class="nv">suffix</span><span class="o">></span></code></pre></figure>
<p>Where <code class="language-plaintext highlighter-rouge">prefix</code> must be the smaller decimal prefix ((X, V) ⇒ I, (C, L) ⇒ X, (M,
D) ⇒ C) of <code class="language-plaintext highlighter-rouge">numeral</code>, and <code class="language-plaintext highlighter-rouge">suffix</code> is the sub-expression parsing the next
smallest numeral.</p>
<p>I then parse the input string using this grammar and a class with equivalent
named methods. Each method:</p>
<ul>
<li>Determines the value matching numerals,</li>
<li>Adds the already calculated suffix value, then</li>
<li>subtracts the prefix value(s).</li>
</ul>
<p>The result parses numerals that are strictly correct according to rules invented
long after the fall of the Roman empire, and also a whole lot of stuff that
looks weird, in the spirit of minimal but effective validation.</p>
<h3 id="and-the-other-way">And the other way</h3>
<p>The solution to this is almost self documenting.</p>
<ul>
<li>Map each component from its value to its numeral (or numeral pair in the case of subtractive prefixes),</li>
<li>then loop through these, assigning the required number of each component.</li>
</ul>
<p>Conveniently, only one of any half-decimal or subtractive prefix will fit into
the remainder of its decimal predecessor, so nothing extra has to be done for
strictly conforming output.</p>
<p><a href="https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-010/fjwhittle/perl6/ch-1.p6">Github link to solution</a>.</p>
<h2 id="bags-of-distance-between-jaro-winkler">Bags of distance between Jaro-Winkler</h2>
<p>The Jaro-Winkler distance of two strings is just one minus their similarity,
which is a fairly inoffensive algorithm that takes the Jaro similarity and adds
a weight based on up to the first four letters of the word being the same (which
produces some differences like for example vettel will match vent more closely
than event does).</p>
<p>The Jaro similarity algorithm seemed pretty simple to implement at first glance
– just take all the characters that are in both strings, and average these
between the length of both strings and the number of transposed / out of
sequence characters, and in fact I had an implementation of this working to my
satisfaction before I realised that I’d missed something important.</p>
<p>The matching characters cannot be more than half the length of the longer of the
two strings away from each other.</p>
<p>I <em>had</em> put together an elegant solution that would intersect the combed arrays
of the two strings together, and then loop through the matching characters in
sequence according to the first string, adding transpositions for any character
that was not in the right place in the second string, and now I had to replace
one line with an ∩ operator with a highly inelegant looking loop through the
first string that marks off any matching character in the second string within
the specified distance limits, unless it’s already been marked off.</p>
<p>Due to being unable to find more than two pieces of test data (both of which work the
same with or without the distance restriction), I’m not sure if it’s even
correct.</p>
<p><a href="https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-010/fjwhittle/perl6/ch-2.p6">Well it’s on Github anyway</a>.</p>FrancisMy high school Latin teachers are now writhing in horror because of my blog post title for the Perl Weekly Challenge 010A unique square and rank – Perl weekly challenge, week 92019-05-26T09:12:11+00:002019-05-26T09:12:11+00:00https://rage.powered.ninja/2019/05/26/-unique-square-and-rank<p>So I’m back again for the <a href="https://perlweeklychallenge.org/blog/perl-weekly-challenge-009/">Perl Weekly Challenge
009</a></p>
<h2 id="first-square-number-that-has-at-least-5-distinct-digits">First square number that has at least 5 distinct digits</h2>
<p>Challenge #1 demonstrates again the power of lazy lists. I think generating
results from lazy lists is pretty much becoming my favourite feature of Perl 6
by default – I find a use for it so frequently.</p>
<p>In this case we lazily generate a list from 0 to infinity – <code class="language-plaintext highlighter-rouge">(^∞)</code> is basically
a term, right? – map it to a list of square numbers with <code class="language-plaintext highlighter-rouge">.map(* ** 2)</code>, and
then filter to numbers that have 5 unique digits.</p>
<p>To do this I used Bags (Sets would have worked too):</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="o">.</span><span class="nb">grep</span><span class="p">(</span><span class="o">*.</span><span class="nv">comb</span><span class="o">.</span><span class="nv">Bag</span><span class="o">.</span><span class="nv">elems</span> <span class="o">>=</span> <span class="nv">$digits</span><span class="p">)</span></code></pre></figure>
<p>Where <code class="language-plaintext highlighter-rouge">$digits</code> is in this case 5 (the default for a value entered on the
command line in my solution). This will find <strong>all</strong> the Square numbers with at
least 5 digits, but it will literally take forever, so best to cut it short at
the first one with a <code class="language-plaintext highlighter-rouge">[0]</code>.</p>
<p>As usual, it’s <a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-009/fjwhittle/perl6/ch-1.p6">on
github</a>
if you care.</p>
<h2 id="varying-styles-of-rank">Varying styles of rank</h2>
<p>Insert standard rant about vague specifications here. In the end, for test data
I got 20 copypasta from a random name generator and <code class="language-plaintext highlighter-rouge">Z=></code>pped them up to dice
rolls out of 10.</p>
<p>All the same, I went relatively all out on this one. Not because the challenge
was hard, but because it’s a nice opportunity to (completely superfluously) play
with multi dispatch.</p>
<p><code class="language-plaintext highlighter-rouge">RankMode</code> is an enum of the ranking modes, <code class="language-plaintext highlighter-rouge"><rank-standard rank-modified
rank-dense></code>. Again, this is entirely unnecessary (actually I added it on at the
end).</p>
<p>Now I can stick it in a multi dispatch prototype though (more stuff I added
later):</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">proto</span> <span class="nv">rank</span><span class="p">(</span><span class="vg">$,</span> <span class="nv">RankMode</span><span class="p">,</span> <span class="o">&</span><span class="p">?)</span> <span class="p">{</span> <span class="o">*</span> <span class="p">}</span></code></pre></figure>
<p><code class="language-plaintext highlighter-rouge">$</code> basically indicates the first argument <del>is some kind of container</del>
(thanks <a href="https://github.com/raiph">@raiph</a> for the correction),
<code class="language-plaintext highlighter-rouge">RankMode</code> is as above, and <code class="language-plaintext highlighter-rouge">&?</code> indicates the third argument is a
routine and is <strong>optional</strong>.</p>
<p>Following this (in source order - chronologically I did them first), I have
three multi declarations that look like:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">multi</span> <span class="nv">rank</span><span class="p">(</span><span class="nv">@scores</span> <span class="nv">where</span> <span class="p">{</span> <span class="vg">$_</span><span class="err">»</span><span class="o">.</span><span class="p">?</span><span class="nv">value</span><span class="o">.</span><span class="nv">all</span> <span class="o">~~</span> <span class="nv">Int</span> <span class="p">},</span>
<span class="nv">rank</span><span class="o">-</span><span class="nv">standard</span><span class="p">,</span>
<span class="nv">&ranking</span> <span class="o">=</span> <span class="p">{</span><span class="err">$</span><span class="o">^</span><span class="nv">b</span><span class="o">.</span><span class="nv">key</span> <span class="o"><=></span> <span class="err">$</span><span class="o">^</span><span class="nv">a</span><span class="o">.</span><span class="nv">key</span><span class="p">})</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span></code></pre></figure>
<p>With <code class="language-plaintext highlighter-rouge">rank-modified</code> and <code class="language-plaintext highlighter-rouge">rank-dense</code> substituted for <code class="language-plaintext highlighter-rouge">rank-standard</code> in the
second and third subs’ signatures. This allows us to make apparently the same
function call but a <em>different</em> implementation is used depending on what
<code class="language-plaintext highlighter-rouge">RankMode</code> is given.</p>
<p>You might have noticed the <code class="language-plaintext highlighter-rouge">where</code> constraint on the <code class="language-plaintext highlighter-rouge">@scores</code> argument. This is
to ensure that a list of Pairs has been passed (or at least of somethings that
implement .value) with all the values being integers. This is actually a little
contrary to the flexibility provided by having a <code class="language-plaintext highlighter-rouge">&ranking</code> call back, but
provides an early indication of something that would prevent the internals of
these functions working – and if we wanted to rank something with a different
structure later we could add another version of rank with another constraint and
both would still work.</p>
<p>The contents of these subroutines is very similar, where:</p>
<ul>
<li>First, it inverts the list of scores added to it (this is why we compare the
key in the default <code class="language-plaintext highlighter-rouge">&ranking</code>) and create a Hash from this, meaning that keys of
the <code class="language-plaintext highlighter-rouge">@scores</code> argument get grouped together according to their score.</li>
<li>Then each group of Pairs is mapped to its ranking and spat out into an output
array, with the Pair inverted back to its original order.</li>
<li>Somewhere in this rank of the group <em>or</em> the one following it is determined in
the way appropriate for each implementation.</li>
</ul>
<p>I’m actually a little frustrated that when I tried to do this with a mapping
function, my <code class="language-plaintext highlighter-rouge">$n</code> ranking variable would always be evaluated before anything was
mapped to the output, which made the <code class="language-plaintext highlighter-rouge">rank-standard</code> routine behave the same as
the <code class="language-plaintext highlighter-rouge">rank-modified</code> one; if anyone has any ideas on how to avoid this, I’d love
to hear them. The implementation was:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="nv">Hash</span><span class="o">.</span><span class="k">new</span><span class="o">.</span><span class="nv">append</span><span class="p">(</span><span class="nv">@scores</span><span class="o">.</span><span class="nv">invert</span><span class="p">)</span><span class="o">.</span><span class="nv">pairs</span><span class="o">.</span><span class="nb">sort</span><span class="p">(</span><span class="nv">&ranking</span><span class="p">)</span><span class="o">.</span><span class="nb">map</span><span class="p">:</span> <span class="p">{</span>
<span class="k">my</span> <span class="nv">$e</span> <span class="o">=</span> <span class="o">.</span><span class="nv">invert</span><span class="o">.</span><span class="nb">map</span><span class="p">:</span> <span class="p">{</span><span class="nv">$n</span> <span class="o">=></span> <span class="vg">$_</span><span class="p">};</span>
<span class="nv">$n</span> <span class="o">+=</span> <span class="o">.</span><span class="nv">value</span><span class="o">.</span><span class="nv">elems</span><span class="p">;</span>
<span class="o">|</span><span class="nv">$e</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p><strong>Anyway</strong> I also have a fourth multi-sub:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">multi</span> <span class="nv">rank</span><span class="p">(</span><span class="nv">%scores</span><span class="p">,</span> <span class="nv">RankMode</span> <span class="nv">$mode</span><span class="p">,</span> <span class="nv">&ranking</span> <span class="o">=</span> <span class="p">{</span><span class="err">$</span><span class="o">^</span><span class="nv">b</span><span class="o">.</span><span class="nv">key</span> <span class="o"><=></span> <span class="err">$</span><span class="o">^</span><span class="nv">a</span><span class="o">.</span><span class="nv">key</span><span class="p">})</span> <span class="p">{</span>
<span class="nv">rank</span><span class="p">(</span><span class="nv">%scores</span><span class="o">.</span><span class="nv">pairs</span><span class="p">,</span> <span class="nv">$mode</span><span class="p">,</span> <span class="nv">&ranking</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>Which allows me to call <code class="language-plaintext highlighter-rouge">rank</code> with a Hash, which it will turn into a list of
pairs, and then pass it on to the appropriate subroutine according to the given
<code class="language-plaintext highlighter-rouge">$mode</code>. Which is just kind of cool.</p>
<p>There’s not a single if statement in my code. You can check this <a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-009/fjwhittle/perl6/ch-2.p6">on
github</a></p>
<h2 id="optional-challenge">Optional challenge</h2>
<p>Again I’m opting out of this one, for the same reasons as last week, and also
because I started this challenge late owed to being at said <code class="language-plaintext highlighter-rouge">$day-job</code> all week
(which I wasn’t before).</p>
<p>If I <strong>was</strong> to have a go at this one though, I’d probably use
<a href="https://cro.services/docs/reference/cro-http-client">Cro::Http::Client</a>
though, because it will even marshal objects to JSON for me.</p>FrancisSo I’m back again for the Perl Weekly Challenge 009Squaring up to the Perfect Centre – Perl weekly challenge, week 82019-05-15T22:34:24+00:002019-05-15T22:34:24+00:00https://rage.powered.ninja/2019/05/15/-squaring--perfect-centre<p>Blogging back, for the <a href="https://perlweeklychallenge.org/blog/perl-weekly-challenge-008/">eighth Perl weekly
challenge</a>.</p>
<p>This week our two challenges were to calculate the first 5 perfect numbers, and
to centre a series of lines on the page.</p>
<h2 id="perfect-numbers">Perfect Numbers</h2>
<p>I’m a little late to the blog this week, so I’ve had a look at what other people
did before writing this up (I did my solution before checking out others’), and
it looks like a number of people tried to filter the list of positive integers
directly. As they discovered, this is mostly fine for the first four perfect
numbers, but the fifth… takes a while to discover this way. I didn’t run into
this timing issue, because I like to generate.</p>
<h3 id="how-do-generate-perfect-number">How do generate perfect number?</h3>
<p>The first step is to find an algorithm. This is pretty well documented on the
<a href="https://en.wikipedia.org/wiki/Perfect_number">Wikipedia page</a>:</p>
<ul>
<li>Euclid proved that all numbers of the form <em>q</em>(<em>q</em> + 1) / 2 are perfect numbers
where <em>q</em> is (what would later be known as) a Mersenne Prime.</li>
<li>Much more recently, Euler proved that in fact <em>all</em> perfect numbers are formed
like this.</li>
</ul>
<p>So the answer then is to generate Mersenne primes, and calculate perfect numbers
using these.</p>
<h3 id="lazily-we-mersenne">Lazily we Mersenne</h3>
<p>A Mersenne prime is of the form 2<em><sup>p</sup></em> - 1 where <em>p</em> is a prime number. So we
lazily gather a list of all prime numbers up to ∞, check if they’re prime, apply
the formula, and then check if the result is prime as well, because the sequence
<strong>can</strong> produce composite numbers, but Mersenne numbers / primes are always
prime.</p>
<p>I bound this to the term <code class="language-plaintext highlighter-rouge">M</code>:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="o">\</span><span class="nv">M</span> <span class="p">:</span><span class="o">=</span> <span class="p">(</span><span class="o">^</span><span class="err">∞</span><span class="p">)</span>
<span class="o">.</span><span class="nb">grep</span><span class="p">(</span><span class="o">*.</span><span class="nv">is</span><span class="o">-</span><span class="nv">prime</span><span class="p">)</span>
<span class="o">.</span><span class="nb">map</span><span class="p">(</span><span class="o">-></span> <span class="nv">$n</span> <span class="p">{</span> <span class="mi">2</span> <span class="o">**</span> <span class="nv">$n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">})</span>
<span class="o">.</span><span class="nb">grep</span><span class="p">(</span><span class="o">*.</span><span class="nv">is</span><span class="o">-</span><span class="nv">prime</span><span class="p">);</span></code></pre></figure>
<h3 id="perfect-map">Perfect Map</h3>
<p>The next step is to bind a mapping of the Mersenne primes to the corresponding
perfect number:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="o">\</span><span class="nv">P</span> <span class="p">:</span><span class="o">=</span> <span class="nv">M</span><span class="o">.</span><span class="nb">map</span><span class="p">:</span> <span class="o">-></span> <span class="nv">$q</span> <span class="p">{</span> <span class="nv">$q</span> <span class="o">*</span> <span class="p">(</span><span class="nv">$q</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="nv">div</span> <span class="mi">2</span> <span class="p">};</span></code></pre></figure>
<p>I used <code class="language-plaintext highlighter-rouge">div</code> so the result is <code class="language-plaintext highlighter-rouge">Int</code> not <code class="language-plaintext highlighter-rouge">Rat</code>.</p>
<h3 id="finally-get-the-results">Finally, get the results</h3>
<p><code class="language-plaintext highlighter-rouge">P</code> is now a lazily generated array that will find the <em>n</em>th Perfect
number as <code class="language-plaintext highlighter-rouge">P[n]</code>. <code class="language-plaintext highlighter-rouge">^5</code> gives a list of the first 5, so</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="nv">P</span><span class="p">[</span><span class="o">^</span><span class="mi">5</span><span class="p">]</span><span class="err">»</span><span class="o">.</span><span class="nv">put</span></code></pre></figure>
<p>Gets the first 5 perfect numbers, then prints each one on its own line.</p>
<h2 id="text-centring">Text centring</h2>
<p>Nothing special here. Like most other people, I found the maximum line length,
then padded the average of this and the line length on the left.
Only things I did different from what I can see:</p>
<ul>
<li>Used sprintf. The <code class="language-plaintext highlighter-rouge">%*s</code> format specifier lets me pass in the amount of
padding without interpolation.</li>
<li>Filtered through <code class="language-plaintext highlighter-rouge">.trim</code> to get rid of any surrounding spaces, because
paranoia.</li>
</ul>
<h2 id="optional-api-challenge">Optional API challenge</h2>
<p>Writing a simple client for the Mailgun API is distressingly similar to the kind
of work I do in <code class="language-plaintext highlighter-rouge">$day-job</code>, so I’ve opted not to do this one, as it would be a
sad reminder that life would be so much better if I didn’t have to PHP.</p>FrancisBlogging back, for the eighth Perl weekly challenge.Anagramming to the Max – Perl weekly challenge, week 52019-04-22T05:36:33+00:002019-04-22T05:36:33+00:00https://rage.powered.ninja/2019/04/22/anagramming--max<h2 id="some-repetition-for-challenge-one">Some repetition for challenge one.</h2>
<p>As <a href="/2019/04/15/no-pi-file.html#letters-in-words-in-list-in--">hinted at in my previous entry</a>, the difference between finding words that
contain a particular sequence (in any order) and finding anagrams is somewhat
minor.</p>
<p>In fact, the only appreciable difference between my
<a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-004/fjwhittle/perl6/ch-2.p6">week 4 challenge 2 solution</a>
and my <a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-005/fjwhittle/perl6/ch-1.p6">week 5 challenge 1 solution</a>
in context is the replacement of a <code class="language-plaintext highlighter-rouge">⊆</code> operator with a <code class="language-plaintext highlighter-rouge">===</code> operator.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ perl6 ch-1.p6 /usr/share/dict/words top
opt, pot, top
</code></pre></div></div>
<h2 id="build-it-up-to-tear-it-down-in-challenge-two">Build it up to tear it down in challenge two.</h2>
<p>I feel like what I ended up doing for challenge two was somewhat in the Perl 5
idiom. Each line of the file is processed into a sorted sequence of letters,
which is used as a key in a Hash of <code class="language-plaintext highlighter-rouge">SetHash</code>es where the key of the second
dimension is the <code class="language-plaintext highlighter-rouge">.lc</code>ed word itself to avoid counting duplicates.</p>
<p>Once the Hash is built, the maximum number of elements is found, and each entry
with that number of elements is printed out — I’ve used a formatter to show the
sequences, the number of matched words, and the words themselves.</p>
<p>See the full solution at <a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-005/fjwhittle/perl6/ch-2.p6">https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-005/fjwhittle/perl6/ch-2.p6</a></p>FrancisSome repetition for challenge one.Number of Pi in file – Perl weekly challenge, week 42019-04-15T00:53:34+00:002019-04-15T00:53:34+00:00https://rage.powered.ninja/2019/04/15/no-pi-file<p>A new challenge appears!</p>
<h2 id="how-much-π-in-your-script">How much π in your script?</h2>
<p>At first glance, part 1 of this challenge is pretty simple:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="nb">printf</span> <span class="p">"</span><span class="s2">%.16f</span><span class="p">",</span><span class="nv">pi</span></code></pre></figure>
<p>Of course, I had to create the file using echo to avoid have a newline at the
end.
Look close and there’s a problem though.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>perl6 ch-1.p6
3.1415926535897930</code></pre></figure>
<p>That’s <strong>almost</strong> but not <em>quite</em> 16 significant digits of pi. I’m keeping this
as a first solution though, because IMHO it <em>should</em> be the answer.</p>
<p>Okay, time to break out the cynicallest solution for perl6:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="nv">pi</span><span class="o">.\</span> <span class="nv">put</span></code></pre></figure>
<p>15 significant digits of π for 15 characters, including the line break 🤪.</p>
<p>Now let’s get serious. Number sequences were actually one of my favourite
parts of Mathematics, and when the world presents me with an opportunity to
strike a Calculating π shaped nail, I’m going to hit it with my convergent
sequence hammer.</p>
<h3 id="isnt-that-a-bit-far-away-from-the-original-question">Isn’t that a bit far away from the original question?</h3>
<p>Yeah, I doubt this was the challenge’s intention; I’m doing it anyway.</p>
<p>Interestingly enough, revisiting <em>last</em> week’s challenge brought up something
about calculating π using Pascal’s Triangle; apparently since I was last doing
things with Blaise Pascal’s work in high school, <a href="https://www.cut-the-knot.org/arithmetic/algebra/TriPiInPascal.shtml">one Jonas Castillo Toloza
discovered another place it exposed
π</a> – in the
triangular numbers.</p>
<p>I implemented this in Perl6; it went something like this:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">$Ts</span> <span class="p">:</span><span class="o">=</span> <span class="nv">lazy</span> <span class="nv">gather</span> <span class="nv">loop</span> <span class="p">(</span><span class="k">my</span> <span class="nv">$n</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;;)</span> <span class="p">{</span>
<span class="k">for</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="o">-></span> <span class="nv">$m</span> <span class="p">{</span>
<span class="nv">take</span> <span class="p">(</span><span class="nv">$m</span> <span class="sr">/ ($n * ($n + 1) /</span> <span class="mi">2</span><span class="p">));</span>
<span class="nv">$n</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">my</span> <span class="err">$π</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">+</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="nv">$Ts</span><span class="p">[</span><span class="o">^</span><span class="nv">$lim</span><span class="p">];</span></code></pre></figure>
<p>Which is functional, and if you try out a couple of different sizes of $lim you
can see it converging; keeping in mind that Perl6’s <code class="language-plaintext highlighter-rouge">pi</code> is apparently accurate
to the 15 digits it <strong>has</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>> pi
3.141592653589793
> 2 + [+] $Ts[^2000]
3.1415921540896665
> 2 + [+] $Ts[^80000] # Jump of 40x, 3 digits closer
3.1415926532772707
> 2 + [+] $Ts[^160000] # 2x, one more digit
3.1415926535116068
> 2 + [+] $Ts[^320000] # 2x, closer but 11th digit is still wrong
3.141592653570272
> 2 + [+] $Ts[^640000] # 2x again, there we go
3.1415926535849534
> 2 + [+] $Ts[^2**20] # 1048576; many iterations
3.1415926535880487
> pi
3.141592653589793
</code></pre></div></div>
<p>… that’s a whole megasequence to still be accurate accurate to only 12 digits. That
speed of convergence is effectively nonfunctional.</p>
<p>I’ve used a much faster algorithm in the past; The Euler Convergence
Transformation, which is:</p>
<figure>
<math>
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mi>π</mi>
<mn>2</mn>
</mfrac>
</mrow>
<mo>=</mo>
<munderover>
<mo>∑</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>k</mi><mo>=</mo><mn>0</mn>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="normal">∞</mi>
</mrow>
</munderover>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mrow>
<mi>k</mi><mo>!</mo>
</mrow>
<mrow>
<mo stretchy="false">(</mo><mn>2</mn><mi>k</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>!</mo><mo>!</mo>
</mrow>
</mfrac>
</mrow>
<mo>=</mo>
<munderover>
<mo>∑</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>k</mi><mo>=</mo><mn>0</mn>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="normal">∞</mi>
</mrow>
</munderover>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mrow>
<mpadded width="0" height="8.6pt" depth="3pt">
<mrow></mrow>
</mpadded>
<mstyle displaystyle="false" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<msup>
<mn>2</mn>
<mrow class="MJX-TeXAtom-ORD">
<mi>k</mi>
</mrow>
</msup>
<mi>k</mi>
<msup>
<mo>!</mo>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mstyle>
</mrow>
<mrow>
<mpadded width="0" height="8.6pt" depth="3pt">
<mrow></mrow>
</mpadded>
<mstyle displaystyle="false" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mo stretchy="false">(</mo><mn>2</mn><mi>k</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>!</mo>
</mrow>
</mstyle>
</mrow>
</mfrac>
</mrow>
<mo>=</mo>
<mn>1</mn>
<mo>+</mo>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>1</mn>
<mn>3</mn>
</mfrac>
</mrow>
<mrow>
<mo>(</mo>
<mrow>
<mn>1</mn><mo>+</mo>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>2</mn>
<mn>5</mn>
</mfrac>
</mrow>
<mrow>
<mo>(</mo>
<mrow>
<mn>1</mn><mo>+</mo>
<mrow class="MJX-TeXAtom-ORD">
<mfrac>
<mn>3</mn>
<mn>7</mn>
</mfrac>
</mrow>
<mrow>
<mo>(</mo>
<mrow>
<mn>1</mn><mo>+</mo><mo>⋯</mo>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
<mo>)</mo>
</mrow>
</mstyle>
</mrow>
</semantics>
</math>
</figure>
<p>(Where <em>k!!</em> is the odd-only factorial of <em>k</em>)</p>
<p>Now, we <strong>could</strong> implement the sequence discretely according to probably the
second summation (this <em>k!!</em> seems a bit of a pain to implement), but if you
squint a bit at the right hand sequence, it looks a bit like:</p>
<figure>
<math>
<semantics>
<mstyle displaystyle="true">
<mrow>
<mfrac>
<mn>π</mn>
<mn>2</mn>
</mfrac>
<mo>=</mo>
<mrow>
<munderover>
<mo>∑</mo>
<mrow>
<mi>k</mi><mo>=</mo><mn>0</mn>
</mrow>
<mrow>
<mi mathvariant="normal">∞</mi>
</mrow>
</munderover>
<msub><mi>n</mi><mi>k</mi></msub>
</mrow>
<mo>where</mo>
<mrow>
<msub><mi>n</mi><mn>0</mn></msub><mo>=</mo><mn>1</mn>
</mrow>
<mo>; </mo>
<mrow>
<msub><mi>n</mi><mi>k</mi></msub>
<mo>=</mo>
<msub><mi>n</mi><mrow><mi>k</mi><mo>-</mo><mn>1</mn></mrow></msub>
<mo>·</mo>
<mfrac>
<mi>k</mi>
<mrow><mn>2</mn><mi>k</mi><mo>+</mo><mn>1</mn></mrow>
</mfrac>
</mrow>
</mrow>
</mstyle>
</semantics>
</math>
</figure>
<p>Which saves us some calculation as during a gather / take we already know what
<em>n<sub>k-1</sub></em> is. Throw it together, sum the results, multiply by two, and
Bob’s yer uncle.</p>
<p>While we’re at it, we’ll use FatRats to be away with those pesky IEE754 floats
and their imprecision.</p>
<p>Through some analysis I found that 608 iterations was enough to give me 177
correct significant digits, which is the final size of the script; that’s quite
a lot better than 1M iterations to get 12…</p>
<h3 id="algorithmic-script-size">Algorithmic Script Size</h3>
<p>‘Enough tedious maths!’ you say, ‘tell us something about programming!’</p>
<p>Cool feature of Perl 6 – you can find the size of the current script using
<code class="language-plaintext highlighter-rouge">$?FILE.IO.s</code>. To round out the script I used that (+ 1 for the decimal point)
as the end of the substring of my calculated π.</p>
<p>See my solution at
<a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-004/fjwhittle/perl6/ch-1.p6">https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-004/fjwhittle/perl6/ch-1.p6</a></p>
<h2 id="letters-in-words-in-list-in--">Letters in words in list in … ?</h2>
<p>Part 2 of the week 4 challenge starts with “You are given a file containing a
list of words (case insensitive 1 word per line) and a list of letters” however
doesn’t provide any such data. I have to admit I’m not a big fan of challenges
with undefined data sets, although I can also certainly appreciate that
providing data for testing is potentially not something challenge authors have
time for. The challenge itself is fairly similar to an anagram generator I had a
go at making for my own fun some time back (around the release of 6.c).</p>
<h3 id="finding-data">Finding data.</h3>
<p>Hmm. Where would I find a list of words lying around waiting to be used?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ time perl6 -e 'put + "/usr/share/dict/british-english".IO.lines.unique'
101921
real 0m0.593s
user 0m0.671s
sys 0m0.065s
</code></pre></div></div>
<p>Seems reasonable. Next step is to get a list of letters… Oh, let’s just use
command line arguments.</p>
<p>One of my favourite things about Perl 6 is how easy it is to get arguments from
the command line. I normally make my main script file <code class="language-plaintext highlighter-rouge">unit sub MAIN();</code>, which
lets me treat it otherwise like a script. I can then use Pod to document the
options as well.</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="c1">#| Find words in a file that contain only the given letters</span>
<span class="nv">unit</span> <span class="k">sub </span><span class="nf">MAIN</span><span class="err">(</span>
<span class="nf">Str</span> <span class="err">$</span><span class="nf">file</span> <span class="err">#=</span> <span class="nf">file</span> <span class="nf">containing</span> <span class="nf">list</span> <span class="nf">of</span> <span class="nf">words</span>
<span class="nf">where</span> <span class="p">{</span> <span class="nv">given</span> <span class="o">.</span><span class="nv">IO</span> <span class="p">{</span> <span class="o">.</span><span class="nv">r</span> <span class="o">&&</span> <span class="p">(</span> <span class="o">.</span><span class="nv">l</span> <span class="o">||</span> <span class="o">.</span><span class="nv">f</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">die</span> <span class="p">"</span><span class="s2">Cannot read from </span><span class="si">$_</span><span class="p">"</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">#= file containing list of words</span>
<span class="nv">*@letters</span> <span class="c1">#= list of letters to search for</span>
<span class="p">);</span></code></pre></figure>
<p>We’ll approach the problem using Bags and the subsets thereof. We use Bags
instead of Sets to count duplicate letters.</p>
<p>We’ll comb through each of the gobbled arguments for letters, which will allow
the user to enter words on the command line, so map the @letters array to
lower-case, comb each argument for letters, flatten, and convert to a bag..</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">$letter</span><span class="o">-</span><span class="nv">bag</span> <span class="p">:</span><span class="o">=</span> <span class="nv">@letters</span><span class="o">.</span><span class="nv">hyper</span><span class="o">.</span><span class="nb">map</span><span class="p">(</span><span class="o">*.</span><span class="nb">lc</span><span class="o">.</span><span class="nv">comb</span><span class="p">(</span><span class="sr">/ \w /</span><span class="p">))</span><span class="o">.</span><span class="nv">flat</span><span class="o">.</span><span class="nv">Bag</span><span class="p">;</span></code></pre></figure>
<p><code class="language-plaintext highlighter-rouge">.hyper</code> makes the <code class="language-plaintext highlighter-rouge">.map</code> happen in parallel. Maybe not a huge deal for this
step, however when now building a list of word bags out of a 102000 line file it
makes the 30 second process take 10 (on my system – an old Athlon II. It
doesn’t even have SSEv4, but it <strong>does</strong> have 4 cores).</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="k">my</span> <span class="nv">@words</span> <span class="o">=</span> <span class="nv">$file</span><span class="o">.</span><span class="nv">IO</span><span class="o">.</span><span class="nv">lines</span><span class="o">.</span><span class="nv">unique</span><span class="o">.</span><span class="nv">hyper</span><span class="o">.</span><span class="nb">grep</span><span class="p">(</span><span class="o">*.</span><span class="nv">chars</span> <span class="o">></span> <span class="mi">2</span><span class="p">)</span>
<span class="o">.</span><span class="nb">map</span><span class="p">:</span> <span class="p">{</span> <span class="o">.</span><span class="nb">lc</span><span class="o">.</span><span class="nv">comb</span><span class="p">(</span><span class="sr">/ \w /</span><span class="p">)</span><span class="o">.</span><span class="s">Bag</span> <span class="o">=></span> <span class="vg">$_</span> <span class="p">};</span></code></pre></figure>
<p>Use of a pair here allows us to map a word bag to the unmodified word
preserving order, punctuation, and case.
It’s now a pretty simple task to find our words; we just grep the <code class="language-plaintext highlighter-rouge">@words</code> list
for a key that’s a subset of or equal to the <code class="language-plaintext highlighter-rouge">$letter-bag</code> using the <code class="language-plaintext highlighter-rouge">⊆</code>
operator, and print out the corresponding values.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ perl6 ch-2.p6 /usr/share/dict/british-english hello dolly
Dell, Doe, Dole, Dolly, Dooley, Doyle, Eloy, Hell, Holley, Holly, Hood, Hoyle,
Hyde, Leo, Lloyd, Loyd, Lyell, Lyle, Odell, doll, dye, ell, he'd, he'll, held,
hello, hey, hod, hoe, hoed, hold, hole, holed, holy, hooey, led, lode, loll,
lolled, lye, ode, oho, old, oleo, yell, yodel
</code></pre></div></div>
<p>Looks good to me 😊. See the full solution at <a href="https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-004/fjwhittle/perl6/ch-2.p6">https://github.com/fjwhittle/perlweeklychallenge-club/blob/master/challenge-004/fjwhittle/perl6/ch-2.p6</a></p>
<script type="text/javascript" async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=MML_HTMLorMML">
</script>FrancisA new challenge appears!Hamming it up in Perl 6 – the weekly challenge, week 32019-04-12T12:08:00+00:002019-04-12T12:08:00+00:00https://rage.powered.ninja/2019/04/12/hamming-it-up-in-perl-6-weekly<p>Okay, so first up, I started with the <a href="https://perlweeklychallenge.org/">Perl weekly challenge</a> in its <a href="https://perlweeklychallenge.org/blog/perl-weekly-challenge-003/">third week</a>; I hadn’t heard of it in week 1, and wasn’t sure if I should submit in week 2 (also as noted on the official blog, week 2 was absurdly simple Perl 6, and I’ll be focusing on that).</p>
<h2 id="generating-some-5-smooth-numbers">Generating some 5-smooth numbers</h2>
<p>My first thought was to naïvely loop through integers, starting from 1, until we found the appropriate numbers. Pretty simple:</p>
<figure class="highlight"><pre><code class="language-perl" data-lang="perl"><span class="p">(</span><span class="nv">gather</span> <span class="k">for</span> <span class="mi">1</span><span class="o">..*</span> <span class="o">-></span> <span class="nv">$k</span> <span class="p">{</span> <span class="k">my</span> <span class="nv">$n</span> <span class="o">=</span> <span class="nv">$k</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">-></span> <span class="nv">$x</span> <span class="p">{</span> <span class="nv">$n</span> <span class="o">/=</span> <span class="nv">$x</span> <span class="k">until</span> <span class="nv">$n</span> <span class="o">%</span> <span class="nv">$x</span> <span class="p">}</span>
<span class="nv">$n</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="nv">take</span> <span class="nv">$k</span>
<span class="p">})[</span><span class="nv">$i</span><span class="p">]</span><span class="o">.</span><span class="nv">put</span></code></pre></figure>
<p>(Yes, that’s an implicit lazy list 😊)
This is pretty effective, and actually reasonably fast for small numbers; It finds the 52nd (<code class="language-plaintext highlighter-rouge">$i = 51 / 256</code>) in .037s on my aging Athlon II (not counting compile time).</p>
<p>However, as a solution, it does not scale well. Up to around the index mentioned above, it beats the algorithmic solution I’m about to talk about, but as the density of 5-smooth numbers decreases, the efficiency decreases, and the naïve loop gets exponentially slower; Finding the 104th number takes ~1.6s; The 208th, nearly 16. The 1691st which the Rosetta Code page specifies because it’s the highest 5-smooth number below 2³¹ takes so long that I gave up in timing it. The millionth… who knows?</p>
<h2 id="enter-hammings-problem">Enter Hamming’s problem</h2>
<p>The Wikipedia page on 5-smooth / Regular / Hamming numbers <a href="https://en.wikipedia.org/wiki/Regular_number#Algorithms">describes an Algorithm</a> postulated by Dijkstra to (of course) describe the set of Hamming numbers as a recursive sequence made up of three smaller sequences – essentially you start with the first Hamming number (1), then for each of 2 3 and 5, multiply by the known set of Hamming numbers ad nauseam to increase the length of those sub-sequences.</p>
<p>I’ll note now that there’s actually a slightly different <a href="https://rosettacode.org/wiki/Hamming_numbers#Perl_6">Perl6 solution on Rosetta Code</a>, which calculates the powers of 2, 3, and 5 up to a predefined limit and merge sorts the three sequences together. The results are correct, but will always calculate the same sized sequence, which may be either too small or larger than you need. Maybe when a challenge winner is determined we can update Rosetta Code with that solution.</p>
<p>On the other hand, Perl 6 makes this pretty easy with gather / take because you can reference a list inside its own gather block, allowing you to to just keep multiplying by 2 3 and 5 for as long as you need (<code class="language-plaintext highlighter-rouge">@results = @results X* (2,3,5)</code>). Unfortunately, even at the second iteration, the results will come out of order and with duplicates (1 2 3 5 4 6 10 6 9 10 15 25). We can deal with the duplicates to an extent, but ultimately need to sort and uniquify the entire list every iteration. This ⓐ forces the list to be eager, ⓑ is as slow if not slower than the sieve we implemented earlier, and ⓒ is somewhat inelegant. I actually went through a couple of iterations of this anyway and found that a pure Perl 6 merge algorithm that sliced the next three results into the appropriate array indices was much faster than calling sort (also a merge sort) on the entire array. Still not fast enough though.</p>
<p>I had a look at implementing a solution with competing Channels or Supplies, but as Wikipedia said, “explicitly concurrent generative solutions might be non-trivial,” and I kept hitting dead ends along the lines of ‘how do I make it deliver the correct next result and stop at the right time.’</p>
<p>So then I sort-of cheated and had a peek and the Python implementations mentioned by Wikipedia for inspiration.
It took me a while to figure out what it was doing, but after a while (I won’t lie, it was something like 6 hours – I’m not great at Python), I figured out it was merging the results of three generators to yield the minimum result of those.</p>
<p>Perl 6 does’t really do generators the way that Python does, and I decided quickly that nesting gathers wasn’t likely to work well. The solution was to have concurrent iterators on the list being gathered, and pick the smallest result. A couple of variations on if/elsif on three dimensions, I came to the realisation that I could just .min the three next results and advance the iterators that matched this result.</p>
<p>With some added benchmarking, we can see it’s pretty quick:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 0.034s 26: 60
0.040s 52: 256
0.061s 104: 1800
0.068s 208: 18750
0.105s 1691: 2125764000
17.552s 1000000: 519312780448388736089589843750000000000000000000000000000000000000000000000000000000
</code></pre></div></div>
<p><strong>This</strong> takes a little longer to calculate the millionth number than our sieve took to find the 208th. That’s performance progress.</p>
<p>See the full solution at <a href="https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-003/fjwhittle/perl6/ch-1.p6">https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-003/fjwhittle/perl6/ch-1.p6</a></p>
<h2 id="generating-pascals-triangle">Generating Pascal’s Triangle</h2>
<p>This took much less effort. There’s a lot of algorithms for generating Pascal’s Triangle. I chose one that allowed me to not inspect the previous row:</p>
<figure>
<math>
<semantics>
<mrow>
<mstyle displaystyle="true" scriptlevel="0">
<mrow><mrow><mo>(</mo></mrow>
<mfrac linethickness="0px"><mi>n</mi><mi>k</mi></mfrac>
<mrow><mo>)</mo></mrow>
</mrow>
<mo>=</mo>
<mrow>
<mrow><mo>(</mo></mrow>
<mfrac linethickness="0px">
<mi>n</mi>
<mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow>
</mfrac>
<mrow><mo>)</mo></mrow>
</mrow>
<mo>×</mo>
<mrow>
<mfrac>
<mrow><mi>n</mi><mo>+</mo><mn>1</mn><mo>−</mo><mi>k</mi></mrow>
<mi>k</mi>
</mfrac>
</mrow>
</mstyle>
</mrow>
</semantics>
</math>
</figure>
<p>… and made it into Perl6. See <a href="https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-003/fjwhittle/perl6/ch-2.p6">https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-003/fjwhittle/perl6/ch-2.p6</a>, noting that the formula is 1-indexed and Perl6 is 0-indexed (except I made $n 1-indexed).</p>
<script type="text/javascript" async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=MML_HTMLorMML">
</script>FrancisOkay, so first up, I started with the Perl weekly challenge in its third week; I hadn’t heard of it in week 1, and wasn’t sure if I should submit in week 2 (also as noted on the official blog, week 2 was absurdly simple Perl 6, and I’ll be focusing on that).Introducing….2014-06-04T10:27:00+00:002014-06-04T10:27:00+00:00https://rage.powered.ninja/2014/06/04/introducingVexed, the wind blows,<br />
an age to become one;<br />
Run out of ideas,<br />
more later with awesome.FrancisVexed, the wind blows, an age to become one; Run out of ideas, more later with awesome.