<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>ETOOBUSY</title>
    <description>🚀 minimal blogging for the impatient</description>
    <link>https://github.polettix.it/ETOOBUSY/</link>
    <atom:link href="https://github.polettix.it/ETOOBUSY/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 13 Sep 2024 07:30:31 +0200</pubDate>
    <lastBuildDate>Fri, 13 Sep 2024 07:30:31 +0200</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Getting the `ntSecurityDescriptor` with an LDAP query</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I found out how to retrieve the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntSecurityDescriptor&lt;/code&gt; in Active
Directory, via LDAP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Active Directory is a… &lt;em&gt;beast&lt;/em&gt; and it’s not always easy to get what’s
needed. This took me… some time.&lt;/p&gt;

&lt;p&gt;One configuration that is supported for an account is the possibility to
set a flag for preventing a user to change password. I’m not sure &lt;em&gt;why&lt;/em&gt;
there’s such a flag; I can only imagine that’s an easy way to lock an
account (you just set a very random password, then prevent anyone from
changing it).&lt;/p&gt;

&lt;p&gt;There’s a promising flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PASSWD_CANT_CHANGE&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userAccountControl&lt;/code&gt;,
but alas:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You can’t assign this permission by directly modifying the
UserAccountControl attribute. For information about how to set the
permission programmatically, see the [Property flag descriptions][]
section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The link eventually lands us on page &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/adsi/modifying-user-cannot-change-password-ldap-provider&quot;&gt;Modifying User Cannot Change
Password (LDAP Provider)&lt;/a&gt;, which is &lt;em&gt;somehow&lt;/em&gt; helpful but not too
much, because it includes code examples that assume the use of some
Microsoft library for C++. I guess 🙄&lt;/p&gt;

&lt;p&gt;Anyway, the page includes some interesting info:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the information that we’re after is in an &lt;em&gt;Discretionary Access
Control List&lt;/em&gt; (DACL)&lt;/li&gt;
  &lt;li&gt;it is included in property (/attribute) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntSecurityDescriptor&lt;/code&gt; in the
LDAP record.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only fact is that this attribute is nowhere to be found.&lt;/p&gt;

&lt;p&gt;Wait a minute. What?!?&lt;/p&gt;

&lt;p&gt;It turns out that depending on how you set the query parameters, this
field will contain more or less information. By default it is supposed
to contain everything, except that normal users are &lt;em&gt;not&lt;/em&gt; supposed to
see everything, so Active Directory does not include this attribute in
the answer.&lt;/p&gt;

&lt;p&gt;The trick consists in &lt;em&gt;asking for less&lt;/em&gt;. &lt;a href=&quot;https://stackoverflow.com/questions/40771503/selecting-the-ad-ntsecuritydescriptor-attribute-as-a-non-admin/40773088#40773088&quot;&gt;This answer&lt;/a&gt; got me on the
right track for a solution &lt;em&gt;in &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;&lt;/em&gt;: we have to set the extension
control &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDAP_SERVER_SD_FLAGS_OID&lt;/code&gt; to a value that excludes the &lt;em&gt;System
Access Control List&lt;/em&gt; part from the answer, while keeping everything
else. The answer also includes a quick and dirty way of building up the
right value to pass for this control:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$sdFlags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;mf&quot;&gt;...&lt;/span&gt;
   &lt;span class=&quot;s2&quot;&gt;&quot;value&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%c%c%c%c%c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$sdFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This even works in &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;, but it’s a bit too &lt;em&gt;hackish&lt;/em&gt; and I’d like
to know more.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/3888c2b7-35b9-45b7-afeb-b772aa932dd0&quot;&gt;This page&lt;/a&gt; contains the information I was after:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDAP_SERVER_SD_FLAGS_OID&lt;/code&gt; control is used with an LDAP Search
request to control the portion of a &lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/b645c125-a7da-4097-84a1-2fa7cea07714#gt_e5213722-75a9-44e7-b026-8e4833f0d350&quot;&gt;Windows security descriptor&lt;/a&gt; to
retrieve.&lt;/p&gt;

  &lt;p&gt;…&lt;/p&gt;

  &lt;p&gt;When sending this control to the DC, the controlValue field is set to
the BER encoding of the following ASN.1 structure.&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SDFlagsRequestValue ::= SEQUENCE {
    Flags    INTEGER
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes it clearer the trick in the PHP code; it’s just a way to
produce the BER encoding of the required data structure. In particular:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0x30 (48 decimal)    tag for a SEQUENCE
0x03 (3 decimal)     length of SEQUENCE (# of following octets)
    0X02 (2 decimal)     tag for an INTEGER
    0x01 (1 decimal)     length of INTEGER (# of following octets)
    0x07 ($sdFlags)      value of INTEGER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When using &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;, especially when using &lt;a href=&quot;https://metacpan.org/pod/Net::LDAP&quot;&gt;Net::LDAP&lt;/a&gt;, there’s a
cleaner and more readable way of producing the same:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Convert::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ASN1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;OWNER_SECURITY_INFORMATION&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GROUP_SECURITY_INFORMATION&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;DACL_SECURITY_INFORMATION&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;SACL_SECURITY_INFORMATION&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$asn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Convert::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ASN1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$asn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prepare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;END&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;);&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;SDFlagsRequestValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;SEQUENCE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;Flags&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;INTEGER&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;END&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ldap_control_sd_flags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$asn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Flags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;nv&quot;&gt;OWNER_SECURITY_INFORMATION&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;GROUP_SECURITY_INFORMATION&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DACL_SECURITY_INFORMATION&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Setting the control for the query is quite straightforward, as it’s part
of the interface for the &lt;a href=&quot;https://metacpan.org/pod/Net::LDAP#search-(-OPTIONS-)&quot;&gt;search&lt;/a&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Net::LDAP::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Constant&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;qw&amp;lt; LDAP_CONTROL_SD_FLAGS &amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Net::LDAP::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$control&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Net::LDAP::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Control&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;critical&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;type&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LDAP_CONTROL_SD_FLAGS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;value&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ldap_control_sd_flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ldap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;control&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should eventually give us the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntSecurityDescriptor&lt;/code&gt; we’re after
(including the DACL), even when we’re not super-administrators.&lt;/p&gt;

&lt;p&gt;Stay safe!&lt;/p&gt;

</description>
        <pubDate>Fri, 13 Sep 2024 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2024/09/13/ldap-ntSecurityDescriptor/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2024/09/13/ldap-ntSecurityDescriptor/</guid>
        
        <category>perl</category>
        
        <category>ldap</category>
        
        <category>active directory</category>
        
        
      </item>
    
      <item>
        <title>App::Easer release 2.008 is out</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There’s a new release of &lt;a href=&quot;https://metacpan.org/pod/App::Easer&quot;&gt;App::Easer&lt;/a&gt;: 2.008.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Long time no see, huh?!? My last post here was &lt;em&gt;almost&lt;/em&gt; e-l-e-v-e-n
months ago! &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OK, back to &lt;a href=&quot;https://metacpan.org/pod/App::Easer&quot;&gt;App::Easer&lt;/a&gt;. It was a long due release, after fixing many
bugs and annoyances that &lt;a href=&quot;https://github.com/djerius&quot;&gt;djerius&lt;/a&gt; reported.&lt;/p&gt;

&lt;p&gt;There’s been new designing but in a backwards-compatible way, especially
in how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sources&lt;/code&gt; can be handled in a new way. Check out the new &lt;a href=&quot;https://metacpan.org/release/POLETTIX/App-Easer-2.008/view/lib/App/Easer/Tutorial/V2_008.pod&quot;&gt;shiny
tutorial for v2.008&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Stay safe!&lt;/p&gt;

</description>
        <pubDate>Thu, 12 Sep 2024 07:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2024/09/12/app-easer-28/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2024/09/12/app-easer-28/</guid>
        
        <category>perl</category>
        
        <category>client</category>
        
        <category>terminal</category>
        
        
      </item>
    
      <item>
        <title>PWC239 - Consistent Strings</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-239/#TASK2&quot;&gt;TASK #2&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt; &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-239/&quot;&gt;#239&lt;/a&gt;.
Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given an array of strings and allowed string having distinct
characters.&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;A string is consistent if all characters in the string appear in the
string allowed.&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;Write a script to return the number of consistent strings in the given
array.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @str = (&quot;ad&quot;, &quot;bd&quot;, &quot;aaab&quot;, &quot;baa&quot;, &quot;badab&quot;)
       $allowed = &quot;ab&quot;
Output: 2

Strings &quot;aaab&quot; and &quot;baa&quot; are consistent since they only contain characters &apos;a&apos; and &apos;b&apos;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @str = (&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;ab&quot;, &quot;ac&quot;, &quot;bc&quot;, &quot;abc&quot;)
       $allowed = &quot;abc&quot;
Output: 7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @str = (&quot;cc&quot;, &quot;acd&quot;, &quot;b&quot;, &quot;ba&quot;, &quot;bac&quot;, &quot;bad&quot;, &quot;ac&quot;, &quot;d&quot;)
       $allowed = &quot;cad&quot;
Output: 4

Strings &quot;cc&quot;, &quot;acd&quot;, &quot;ac&quot;, and &quot;d&quot; are consistent.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;Talking about checking for equality… are accented characters the same
as non-accented ones?&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;We can do the check using a hash/set and then checking that all
characters belong to it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; goes first, we encapsulate the test in a function so that it’s
easy to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&lt;/code&gt; in scalar context to produce the output:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;consistency_checker_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;scalar&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;consistency_checker_for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;($string) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%is_allowed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;m{}mxs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;($input) {&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$is_allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)};&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We do almost the same in &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;, just a little change moving the test
function inside the function to do the overall test. We could have done
like this in &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; as well.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN ($allowed, *@str) { put consistent-string($allowed, @str).elems }

sub consistent-string ($allowed, @str) {
   my $al = $allowed.comb.Set;
   my &amp;amp;checker = sub ($input) {
      for $input.comb -&amp;gt; $c {
         return False unless $c ∈ $al;
      }
      return True;
   };
   @str.grep(&amp;amp;checker);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Stay safe!&lt;/p&gt;

</description>
        <pubDate>Mon, 23 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/23/consistent-strings/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/23/consistent-strings/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC239 - Same String</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Here we are with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-239/#TASK1&quot;&gt;TASK #1&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt;
&lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-239/&quot;&gt;#239&lt;/a&gt;. Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given two arrays of strings.&lt;/p&gt;

  &lt;p&gt;Write a script to find out if the word created by concatenating the
array elements is the same.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @arr1 = (&quot;ab&quot;, &quot;c&quot;)

Output: true

Using @arr1, word1 =&amp;gt; &quot;ab&quot; . &quot;c&quot; =&amp;gt; &quot;abc&quot;
Using @arr2, word2 =&amp;gt; &quot;a&quot; . &quot;bc&quot; =&amp;gt; &quot;abc&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @arr1 = (&quot;ab&quot;, &quot;c&quot;)
       @arr2 = (&quot;ac&quot;, &quot;b&quot;)
Output: false

Using @arr1, word1 =&amp;gt; &quot;ab&quot; . &quot;c&quot; =&amp;gt; &quot;abc&quot;
Using @arr2, word2 =&amp;gt; &quot;ac&quot; . &quot;b&quot; =&amp;gt; &quot;acb&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;This time I have a &lt;em&gt;meta&lt;/em&gt;-question… how is people addressing the
problem of getting the inputs from the command line?&lt;/p&gt;

&lt;p&gt;Well, apart from this I’d probably ask what &lt;em&gt;the same&lt;/em&gt; means. E.g.
should differently-accented character count as &lt;em&gt;same&lt;/em&gt;? I’ll assume
not…&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;We’re starting with &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt; and we’re going the easy way, joining all
strings together and comparing the results:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN ($s1, $s2) { say is-same-string($s1.split(/\,/), $s2.split(/\,/)) }

sub is-same-string (@s1, @s2) { @s1.join(&apos;&apos;) eq @s2.join(&apos;&apos;) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; counterpart, we’re going the over-engineering way and
assume that there might be several input arrays, as well as avoiding to
merge them in single strings and instead iterate them character by
character:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;m{,}mxs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;is_same_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;is_same_string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$lead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ch_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aref&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#*) {&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aref&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ch_idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ch_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aref&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$ch_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;necessary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;defined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;defined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$it&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$och&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$och&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&apos;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;ne&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cheers and… stay safe!&lt;/p&gt;

</description>
        <pubDate>Sun, 22 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/22/pwc239-same-string/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/22/pwc239-same-string/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC238 - Persistence Sort</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-238/#TASK2&quot;&gt;TASK #2&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt; &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-238/&quot;&gt;#238&lt;/a&gt;.
Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given an array of positive integers.&lt;/p&gt;

  &lt;p&gt;Write a script to sort the given array in increasing order with
respect to the count of steps required to obtain a single-digit number
by multiplying its digits recursively for each array element. If any
two numbers have the same count of steps, then print the smaller
number first.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @int = (15, 99, 1, 34)
Output: (1, 15, 34, 99)

15 =&amp;gt; 1 x 5 =&amp;gt; 5 (1 step)
99 =&amp;gt; 9 x 9 =&amp;gt; 81 =&amp;gt; 8 x 1 =&amp;gt; 8 (2 steps)
1  =&amp;gt; 0 step
34 =&amp;gt; 3 x 4 =&amp;gt; 12 =&amp;gt; 1 x 2 =&amp;gt; 2 (2 steps)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @int = (50, 25, 33, 22)
Output: (22, 33, 50, 25)

50 =&amp;gt; 5 x 0 =&amp;gt; 0 (1 step)
25 =&amp;gt; 2 x 5 =&amp;gt; 10 =&amp;gt; 1 x 0 =&amp;gt; 0 (2 steps)
33 =&amp;gt; 3 x 3 =&amp;gt; 9 (1 step)
22 =&amp;gt; 2 x 2 =&amp;gt; 4 (1 step)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;Doing multiplications can get big numbers quite fast, although each
iteration will &lt;em&gt;always&lt;/em&gt; produce a smaller value. Anyhow, it’s probably
fine to ask for the input domain and rule out (or in!) the need for big
integers.&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;We will go &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; first this time, enhancing the input array with info
for doing the sorting, then getting the basic data back at the end. This
is a common technique that I know under the name of &lt;em&gt;Schwartzian transform&lt;/em&gt; (from Randal L. Schwartz, a.k.a. &lt;em&gt;merlyn&lt;/em&gt;, who invented it):&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;persistence_sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;persistence_sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@int) {&lt;/span&gt;
   &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;persistence_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;@int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;persistence_for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;($v) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$rounds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@digits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;m{}mxs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@digits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$rounds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;@digits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;m{}mxs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$rounds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prod&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@ints) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$retval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$retval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$int&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$retval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can replicate the same in &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;, taking advantage of some of the
included batteries (e.g. to compute the product of all digits):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN (*@args) { say persistence-sort(@args) }

sub persistence-sort (@int) {
   return @int
      .map({ [$_, persistence-for($_)] })
      .sort({ ($^a[1] &amp;lt;=&amp;gt; $^b[1]) || ($^a[0] &amp;lt;=&amp;gt; $^b[0]) })
      .map({ $_[0] })
      .Array;
}

sub persistence-for ($v) {
   my $rounds = 0;
   my @digits = $v.comb;
   while @digits &amp;gt; 1 {
      ++$rounds;
      @digits = ([*] @digits).comb;
   }
   return $rounds;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Schwartziant transform has a different &lt;em&gt;taste&lt;/em&gt; this time, because it
goes on a natural “reading” way instead of going backwards. Still, it’s
basically the same as before.&lt;/p&gt;

&lt;p&gt;Stay safe folks!&lt;/p&gt;

</description>
        <pubDate>Sat, 21 Oct 2023 16:43:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/21/pwc238-persistence-sort/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/21/pwc238-persistence-sort/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC238 - Running Sum</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Here we are with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-238/#TASK1&quot;&gt;TASK #1&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt;
&lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-238/&quot;&gt;#238&lt;/a&gt;. Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given an array of integers.&lt;/p&gt;

  &lt;p&gt;Write a script to return the running sum of the given array. The
running sum can be calculated as sum[i] = num[0] + num[1] + …. +
num[i].&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @int = (1, 2, 3, 4, 5)
Output: (1, 3, 6, 10, 15)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @int = (1, 1, 1, 1, 1)
Output: (1, 2, 3, 4, 5)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @int = (0, -1, 1, 2)
Output: (0, -1, 0, 2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;I’d probably just ask:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the domain of the inputs (i.e. should we prepare for big integers?)&lt;/li&gt;
  &lt;li&gt;the length of the input/output arrays.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;We can iterate over the input array and collect stuff along the way,
using an accumulator variable. Here’s how to do it in &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN (*@args) { say running-sum(@args) }

sub running-sum (@int) {
   my $accumulator = 0;
   return [ @int.map({$accumulator += $_}) ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I didn’t really like the accumulator variable, so I tried to implement
an alternative solution with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gather&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;take&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;sub running-sum-alternative (@int) {
   return [ gather { take @int[0]; @int.reduce({ take $^a + $^b }) } ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Still not that satisfactory, though. Surely &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt; has something &lt;em&gt;to
the point&lt;/em&gt;, right? Right, let’s &lt;a href=&quot;https://docs.raku.org/type/List#routine_produce&quot;&gt;produce&lt;/a&gt;!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;sub running-sum-alternative2 (@int) { @int.produce(&amp;amp;[+]) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Surely &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; has something too, right? Right, let’s use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reductions&lt;/code&gt;!&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Util&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;reductions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;running_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;running_sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reductions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s all for this challenge, folks!&lt;/p&gt;

</description>
        <pubDate>Sat, 21 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/21/pwc238-running-sum/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/21/pwc238-running-sum/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC237 - Maximise Greatness</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-237/#TASK2&quot;&gt;TASK #2&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt; &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-237/&quot;&gt;#237&lt;/a&gt;.
Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given an array of integers.&lt;/p&gt;

  &lt;p&gt;Write a script to permute the give array such that you get the maximum
possible greatness.&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;To determine greatness, nums[i] &amp;lt; perm[i] where 0 &amp;lt;= i &amp;lt; nums.length&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @nums = (1, 3, 5, 2, 1, 3, 1)
Output: 4

One possible permutation: (2, 5, 1, 3, 3, 1, 1) which returns 4 greatness as below:
nums[0] &amp;lt; perm[0]
nums[1] &amp;lt; perm[1]
nums[3] &amp;lt; perm[3]
nums[4] &amp;lt; perm[4]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @ints = (1, 2, 3, 4)
Output: 3

One possible permutation: (2, 3, 4, 1) which returns 3 greatness as below:
nums[0] &amp;lt; perm[0]
nums[1] &amp;lt; perm[1]
nums[2] &amp;lt; perm[2]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;My first question is… &lt;em&gt;what is the question&lt;/em&gt;? I mean, not &lt;em&gt;my&lt;/em&gt;
question, but the challenge’s question. It seems we’re asked for a
permutation, but examples seem to indicate that we need to calculate the
&lt;em&gt;greatness&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, any clue about the size of inputs would probably be a
question worth asking.&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;OK, let’s start with some talk.&lt;/p&gt;

&lt;p&gt;A permutation will generally have “great” positions (i.e. positions that
contribute to greatness) and other “not-great” positions. In each great
position, the corresponding number from the original input is strictly
lower.&lt;/p&gt;

&lt;p&gt;If we rearrange all such correspondent pairs in the respective
permutations, nothing changes regarding the greatness, so it’s an
invariant with respect to pre-arranging the input permutation in some
way. For this reason, it will be useful to think the initial input
permutation as sorted in descending order, e.g. the first example would
become:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;5 3 3 2 1 1 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We are also optimistic folks, so we start big and assume that &lt;em&gt;every&lt;/em&gt;
position can be a great one!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 7
5 3 3 2 1 1 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point we can observe that the first position can &lt;em&gt;never&lt;/em&gt; be
great: it holds the maximum value, so by definition there’s nothing
inside the permutation that can be greater than it. One point lost to
greatness. Anyway, we put this value in a &lt;em&gt;pool&lt;/em&gt; of values that we can
later use to fill in &lt;em&gt;great&lt;/em&gt; positions.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 6
5 3 3 2 1 1 1
-
P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where should we put this value, though? It can actually fill any
position past its own, because it’s the maximum and there’s only one of
it. We can observe, though, that it makes sense to allocate it to the
value immediately below it, because if we e.g. “waste” it on a 2 or a 1
we might miss an opportunity. As a sub-example, consider all different
values, like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;4 3 2 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It only makes sense to allocate the 4 to a 3, because otherwise we will
just “lose” the 3 and get a greatness score of 2 instead of 3.&lt;/p&gt;

&lt;p&gt;Back to the original example and algorithm explanation, then, we use the
pool as soon as it makes sense, i.e. the first 3 that we find. We fit
the 5 in second position and remove it from the pool, because we can
(and must) use it exactly once:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 6
5 3 3 2 1 1 1
- 5
x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we pass, we collect this first 3 in the pool for possible great
positions further down the road:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 6
5 3 3 2 1 1 1
- 5
x P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we move on to the following 3, and we find that there’s nothing in
the pool to make this a great position. Hence we keep our pool as it is
and declare this a miss, lowering the greatness value by 1 again. We
also collect this 3 in the pool, by the way.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 5
5 3 3 2 1 1 1
- 5 -
x P P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Moving on, we find the 2, which can be made a great position thanks to
the 3 that we have in the pool. Taking also into account that we collect
the 2 in the pool, the step becomes:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 5
5 3 3 2 1 1 1
- 5 - 3
x x P P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can move on with the same algorithm:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 5
5 3 3 2 1 1 1
- 5 - 3 3
x x x P P

greatness = 5
5 3 3 2 1 1 1
- 5 - 3 3 2
x x x x P P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last position cannot be great, because we only have 1 in the pool,
so we end up with:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 4
5 3 3 2 1 1 1
- 5 - 3 3 2 -
x x x x P P P
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point we have found our greatness value. To find one
permutation, we can just use what’s left in the pool inside the
positions that we skipped so far:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;greatness = 4
5 3 3 2 1 1 1
1 5 1 3 3 2 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach guarantees us that we will always find both the maximum
greatness and a corresponding permutation that has that value of
greatness.&lt;/p&gt;

&lt;p&gt;We can observe that we can establish the greatness at the end of the
first sweep, by subtracting the size of the pool from the size of the
input data. This is what happens in this &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; implementation:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;JSON::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;great_permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;JSON::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;great_permutation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@inputs) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sorted_indexes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$#inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@permutation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# first pass - set greatness!&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@not_great&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@sorted_indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;$permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;nb&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@not_great&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# second pass - fill the rest&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;@permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@not_great&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@permutation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The code above contains some initial index-calculation to make it
possible to find a permutation for the actual input, not the one sorted
descendingly that we used in our algorithm. Basically, we operate on the
sorted one, but keep the original indexes so that our allocations end up
in the right place.&lt;/p&gt;

&lt;p&gt;If we just need the value of greatness (as it seems from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;output&lt;/code&gt; of
the examples), this can be further squeezed by working on whole blocks
of same-valued positions. We still keep the pool, but it’s just a count
at this point.&lt;/p&gt;

&lt;p&gt;In our initial example, we first turn the input:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 3 5 2 1 3 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;into an array of pairs of counts, sorted in descending order for the
value (not the count):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(5 1) (3 2) (2 1) (1 3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, we can observe that we just need these values to be
ordered by the original value, but we don’t need the value any more
actually because we only care about “greater-than” relations, not actual
values:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 2 1 3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This means that we have 1 top value, then 2 (same) values, then 1 value,
then 3 (same) values, all values being sorted descendingly.&lt;/p&gt;

&lt;p&gt;The pool starts from 0; at each count, in order, what’s in the pool goes
to “cover” that count as much as possible, with two possibilies:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;the pool value is more than, or equal to, the count. This means
that the greatness is not impacted, because all corresponding slots
can be made great; in this case we “consume” the exact amount of count
from the pool, while at the same time also gaining all of them for the
next slot, so actually nothing changes!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;the pool value is less than the count. This means that we will lose
the difference in greatness, exhausting the current pool and resetting
it with the count of the current slot (for the following slots).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this… in &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;greatness&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@inputs) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%count_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$count_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@counts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@count_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%count_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# win &amp;amp; accumulate the same quantity&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# not enough in pool, lose some&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# restart pool from this slot&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$greatness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… and, of course, in &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN (*@args) { put greatness(@args) }

sub greatness (@inputs) {
   my %count-for;
   %count-for{$_}++ for @inputs;
   my @counts = %count-for{ %count-for.keys.sort({$^a.Int &amp;lt;=&amp;gt; $^b.Int}) };

   my $greatness = @inputs.elems;
   my $pool = 0;
   for @counts -&amp;gt; $count {
      next if $count &amp;lt;= $pool; # win and accumulate the same quantity
      $greatness -= $count - $pool; # not enough in pool, lose some
      $pool = $count;  # restart pool from this slot
   }
   return $greatness;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, I guess I bored every single one of you future me:s at this point,
to the rest please stay safe and have fun!&lt;/p&gt;

</description>
        <pubDate>Sun, 08 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/08/pwc237-maximise-greatness/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/08/pwc237-maximise-greatness/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC237 - Seize The Day</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Here we are with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-237/#TASK1&quot;&gt;TASK #1&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt;
&lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-237/&quot;&gt;#237&lt;/a&gt;. Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;Given a year, a month, a weekday of month, and a day of week (1 (Mon)
.. 7 (Sun)), print the day.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: Year = 2024, Month = 4, Weekday of month = 3, day of week = 2
Output: 16

The 3rd Tue of Apr 2024 is the 16th
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: Year = 2025, Month = 10, Weekday of month = 2, day of week = 4
Output: 9

The 2nd Thu of Oct 2025 is the 9th
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: Year = 2026, Month = 8, Weekday of month = 5, day of week = 3
Output: 0

There isn&apos;t a 5th Wed in Aug 2026
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;I have to admit that I had a hard time understanding what &lt;em&gt;a weekday of
month&lt;/em&gt; means, so I hope I got it right from the examples (i.e. that $n$
means &lt;em&gt;the $n$-th such day in the specific month&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Another thing that is not clear is what to return if such a day does not
exist, except that there’s an explicit example about it so I get that
printing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; is fine.&lt;/p&gt;

&lt;p&gt;I would also like to know if there are limits that can be assumed on the
dates range, just to avoid pitfalls like when different countries
switched to the Gregorian calendar.&lt;/p&gt;

&lt;p&gt;Speaking of which, I assume we’re actually talking about the Gregorian
calendar or anything people living in the so-called “west” are used to.&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;We will start with &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;, which provides an excellent &lt;a href=&quot;https://docs.raku.org/type/Date&quot;&gt;Date&lt;/a&gt; class
out of the box that allows doing intuitive arithmetics with integers
representing days. I’ll leave the algorithm to the comments:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN (Int $year, Int $month, Int $weekday_in_month, Int $weekday) {
   my $date = Date.new(year =&amp;gt; $year, month =&amp;gt; $month, day =&amp;gt; 1);

   # how much should we advance to find the first occurrence of the
   # target $weekday?
   my $delta = ($weekday + 7 - $date.day-of-week) % 7;

   # advance that much to land on the first, then additional weeks to
   # land on the target $weekday_in_month
   $date += $delta + ($weekday_in_month - 1) * 7;

   # print the result making sure it&apos;s still in the same year &amp;amp; month
   put($date.year == $year &amp;amp;&amp;amp; $date.month == $month ?? $date.day !! 0);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It’s still easy to translate this into &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;, although we have to
play at a lower level of abstraction if we want to stick with stuff in
CORE (there are excellent libraries but they come with a toll).&lt;/p&gt;

&lt;p&gt;So here our dates will be represented by the &lt;em&gt;epoch&lt;/em&gt; of its mid-day in
Greenwich Mean Time, and all transformations will take into account that
a day has exactly $24 * 3600$ seconds. We are not worried by leap
seconds here, though, because we’re anyway focusing on mid-day and we’re
not using anything below the day granularity anyway.&lt;/p&gt;

&lt;p&gt;Again, I’ll leave it to the comments to explain the gory details:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Time::&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Local&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;timegm_modern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;seize_the_day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;seize_the_day&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;($year, $month, $weekday_in_month, $weekday) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;timegm_modern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$month&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$date_day_of_week&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;gmtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# how many days should we advance to find the first occurrence of the&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;# target $weekday?&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$delta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$weekday&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$date_day_of_week&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# advance that many days to land on the first, then additional weeks&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;# to land on the target $weekday_in_month.&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$delta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$weekday_in_month&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# get back the year and month of the date we landed on&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$newm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$newy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;gmtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$newm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# apply offset for month&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$newy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1900&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# apply offset for year&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# return making sure we&apos;re in the same year &amp;amp; month&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$newy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$month&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$newm&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$day&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This said… stay safe and have a good time!&lt;/p&gt;

</description>
        <pubDate>Sat, 07 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/07/pwc237-seize-the-day/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/07/pwc237-seize-the-day/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC236 - Array Loops</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;On with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-236/#TASK2&quot;&gt;TASK #2&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt; &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-236/&quot;&gt;#236&lt;/a&gt;.
Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are given an array of unique integers.&lt;/p&gt;

  &lt;p&gt;Write a script to determine how many loops are in the given array.&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;To determine a loop: Start at an index and take the number at
array[index] and then proceed to that index and continue this until
you end up at the starting index.&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @ints = (4,6,3,8,15,0,13,18,7,16,14,19,17,5,11,1,12,2,9,10)
Output: 3

To determine the 1st loop, start at index 0,
the number at that index is 4, proceed to index 4,
the number at that index is 15, proceed to index 15
and so on until you&apos;re back at index 0.

Loops are as below:
[4 15 1 6 13 5 0]
[3 8 7 18 9 16 12 17 2]
[14 11 19 10]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @ints = (0,1,13,7,6,8,10,11,2,14,16,4,12,9,17,5,3,18,15,19)
Output: 6

Loops are as below:
[0]
[1]
[13 9 14 17 18 15 5 8 2]
[7 11 4 6 10 16 3]
[12]
[19]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @ints = (9,8,3,11,5,7,13,19,12,4,14,10,18,2,16,1,0,15,6,17)
Output: 1

Loop is as below:
[9 4 5 7 19 17 15 1 8 12 18 6 13 2 3 11 10 14 16 0]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;Well well well… we’re going to take a &lt;strong&gt;huge&lt;/strong&gt; assumption here, that
is the &lt;em&gt;integer values&lt;/em&gt; will always be &lt;em&gt;valid&lt;/em&gt; indexes in the input
array. &lt;em&gt;OK with that?!?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Additionally, we will consider a loop also a situation in which an
element points to itself, &lt;em&gt;OK?&lt;/em&gt; This is within the rules and within the
examples, so this question is probably not needed but better be clear.&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;The assumption allows us to rule out arrays like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(100)&lt;/code&gt; where there is
no loop at all, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(100,2,1)&lt;/code&gt; where there is one with two elements
only.&lt;/p&gt;

&lt;p&gt;This said, every input array is then a permutation of all (and only) the
indexes of the array itself, i.e. integers from $0$ up to $n - 1$, where
$n$ is the number of elements in the array. Every element in the array
is part of a chain; I have a wonderful demonstration of this fact, but
the margins of this blog post are too tight to write it down so trust me
because you trusted Fermat for about 350 years and he was eventually
right.&lt;/p&gt;

&lt;p&gt;At this point, we just have to calculate how many of them are there,
ranging from 1 (just a big chain) up to $n$ (every element just points
to itself). This is a partition of the initial set and the perfect
candidate for the &lt;a href=&quot;https://algs4.cs.princeton.edu/15uf/&quot;&gt;Union-Find&lt;/a&gt; algorithm, where we only need to know
how many unified sets we are left after considering all inputs.&lt;/p&gt;

&lt;p&gt;As a matter of fact, &lt;a href=&quot;https://github.com/polettix/cglib-perl&quot;&gt;cglib-perl&lt;/a&gt; indeed has a &lt;a href=&quot;https://github.com/polettix/cglib-perl/blob/master/UnionFind.pm&quot;&gt;UnionFind.pm&lt;/a&gt;
implementation, that we are happy to leverage here:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;array_loops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;m{\D+}mxs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;array_loops&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@ints) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UnionFind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;components&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$#ints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$uf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$#ints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$uf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;nb&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UnionFind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Sedgewick &amp;amp; Wayne, Algorithms 4th ed, §1.5&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;strict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# see below&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;connected&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;count&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# see below&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# see below&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# see below&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
   &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find_id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;id_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;ne&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;ne&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;## end sub find_id&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$id_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bless&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;id_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$id_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$pk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;$self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;components&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;## end sub new&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# i -&amp;gt; max&lt;/span&gt;
   &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
   &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
   &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;## end sub union&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alas, &lt;a href=&quot;https://github.com/polettix/cglib-raku&quot;&gt;cglib-raku&lt;/a&gt; did not have the corresponding implementation… up
to this challenge, which was the perfect occasion to add it as
&lt;a href=&quot;https://github.com/polettix/cglib-raku/blob/main/UnionFind.rakumod&quot;&gt;UnionFind.rakumod&lt;/a&gt;. So here we are with the &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt; solution too:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;

class UnionFind {
   has $.count = 0;
   has %!cs;
   has &amp;amp;!id-of is built;
   has @!items;

   method add ($item) {
      my $id = &amp;amp;!id-of($item);
      return self if %!cs{$id};
      %!cs{$id} = [ $id, $item, 1 ];
      $!count++;
      return self;
   }

   method find ($item) { %!cs{self.find-id($item)}[1] }

   method find-id ($item) {
      my $r = my $i = &amp;amp;!id-of($item);
      return unless %!cs{$r}:exists;
      $r = %!cs{$r}[0] while $r ne %!cs{$r}[0];
      ($i, %!cs{$i}) = (%!cs{$i}[0], %!cs{$r}) while $i ne $r;
      return $r;
   }

   method new (:&amp;amp;id-of = -&amp;gt; $n { $n.Str }, :@components) {
      my $obj = self.bless(:&amp;amp;id-of);
      $obj.add($_) for @components;
      return $obj;
   }

   method union ($p, $q) {
      my ($i, $j) = self.find-id($p), self.find-id($q);
      return self if $i eq $j;
      ($i, $j) = $j, $i if %!cs{$i}[2] &amp;lt; %!cs{$j}[2]; # i -&amp;gt; max
      %!cs{$i}[2] += %!cs{$j}[2];
      %!cs{$j} = %!cs{$i};
      $!count--;
      return self;
   }
}

sub MAIN (*@indexes) {
   @indexes = @indexes.map({.split(/\D+/)}).flat;
   my $uf = UnionFind.new(components =&amp;gt; [ ^@indexes ]);
   for @indexes.kv -&amp;gt; $i, $j { $uf.union($i, $j) }
   put $uf.count;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some might argue that re-implementing stuff in &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt; could be a waste
of time, but I beg to differ. I still have to learn to play with the
object model (there’s a &lt;strong&gt;huge&lt;/strong&gt; regression in how I’m providing a
constructor), but I got to better understand what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bless&lt;/code&gt; does &lt;em&gt;and&lt;/em&gt; I
uncovered a bug in the &lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt; implementation too. Win-win, yay!&lt;/p&gt;

&lt;p&gt;That’s all for this post, see you soon and stay safe!&lt;/p&gt;

</description>
        <pubDate>Sun, 01 Oct 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/10/01/pwc236-array-loops/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/10/01/pwc236-array-loops/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
      <item>
        <title>PWC236 - Exact Change</title>
        <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Here we are with &lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-236/#TASK1&quot;&gt;TASK #1&lt;/a&gt; from &lt;a href=&quot;https://theweeklychallenge.org/&quot;&gt;The Weekly Challenge&lt;/a&gt;
&lt;a href=&quot;https://theweeklychallenge.org/blog/perl-weekly-challenge-236/&quot;&gt;#236&lt;/a&gt;. Enjoy!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-challenge&quot;&gt;The challenge&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;You are asked to sell juice each costs $5. You are given an array of
bills. You can only sell ONE juice to each customer but make sure you
return exact change back. You only have $5, $10 and $20 notes. You do
not have any change in hand at first.&lt;/p&gt;

  &lt;p&gt;Write a script to find out if it is possible to sell to each customers
with correct change.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @bills = (5, 5, 5, 10, 20)
Output: true

From the first 3 customers, we collect three $5 bills in order.
From the fourth customer, we collect a $10 bill and give back a $5.
From the fifth customer, we give a $10 bill and a $5 bill.
Since all customers got correct change, we output true.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @bills = (5, 5, 10, 10, 20)
Output: false

From the first two customers in order, we collect two $5 bills.
For the next two customers in order, we collect a $10 bill and give back a $5 bill.
For the last customer, we can not give the change of $15 back because we only have two $10 bills.
Since not every customer received the correct change, the answer is false.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;&lt;strong&gt;Example 3&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Input: @bills = (5, 5, 5, 20)
Output: true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;the-questions&quot;&gt;The questions&lt;/h1&gt;

&lt;p&gt;Long time no see, uh?!?&lt;/p&gt;

&lt;p&gt;One question is about this shortage of juice… why only one per
customer?&lt;/p&gt;

&lt;p&gt;More seriously, it seems that we’re not allowed to sort the incoming
bills by value, otherwise the consideration &lt;em&gt;You do not have any change
in hand at first.&lt;/em&gt; would not be needed. So I’m assuming that they have
to be addressed as a FIFO.&lt;/p&gt;

&lt;h1 id=&quot;the-solution&quot;&gt;The solution&lt;/h1&gt;

&lt;p&gt;In the good ol’ times spirit, let’s start with &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt; first:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-raku&quot;&gt;#!/usr/bin/env raku
use v6;
sub MAIN (*@bills) { put exact-change(@bills) ?? &apos;true&apos; !! &apos;false&apos; }

sub exact-change (@bills) {
   my %bills-of = &amp;lt;5 0 10 0 20 0&amp;gt;;
   for @bills -&amp;gt; $bill {
      if $bill == 5 { %bills-of&amp;lt;5&amp;gt;++ }
      elsif $bill == 10 {
         return False unless %bills-of&amp;lt;5&amp;gt;-- &amp;gt; 0;
         %bills-of&amp;lt;10&amp;gt;++;
      }
      else { # $bill == 20
         return False unless %bills-of&amp;lt;5&amp;gt;-- &amp;gt; 0;
         if %bills-of&amp;lt;10&amp;gt; &amp;gt;= 1 {
            %bills-of&amp;lt;10&amp;gt;--;
         }
         elsif %bills-of&amp;lt;5&amp;gt; &amp;gt;= 2 {
            %bills-of&amp;lt;5&amp;gt; -= 2;
         }
         else {
            return False;
         }
      }
   }
   return True;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Every customer with a 5$ bill is very welcome and we have to give no
change back. Every customer with a 10$ bill gets back a 5$ bill if
available, otherwise we bail out. Customers with 20$ bills always get
one 5$ bill back, then a 10$ bill (if possible) or two 5$ bills. It’s
always better to check if 10$ bills are available first, because the 5$
bills are the most needed in changes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.perl.org/&quot;&gt;Perl&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-perl highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;experimental&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;signatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;say&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;exact_change&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&apos;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;exact_change&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(@bills) {&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%bills_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bill&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@bills&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bill&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bill&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# $bill == 20&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$bills_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I think this is it!&lt;/p&gt;

</description>
        <pubDate>Fri, 29 Sep 2023 06:00:00 +0200</pubDate>
        <link>https://github.polettix.it/ETOOBUSY/2023/09/29/pwc236-exact-change/</link>
        <guid isPermaLink="true">https://github.polettix.it/ETOOBUSY/2023/09/29/pwc236-exact-change/</guid>
        
        <category>the weekly challenge</category>
        
        <category>Perl</category>
        
        <category>RakuLang</category>
        
        
      </item>
    
  </channel>
</rss>
