<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>posts by nikita galaiko</title>
    <link>https://nikita.galaiko.rocks/posts</link>
    <description>This is an RSS feed of posts by Nikita Galaiko</description><lastBuildDate>2025-03-13T00:00:00Z</lastBuildDate>
    <managingEditor>nikita@galaiko.rocks (Nikita Galaiko)</managingEditor>
    <webMaster>nikita@galaiko.rocks (Nikita Galaiko)</webMaster>
    <ttl>60</ttl>
    <image>
      <url>https://nikita.galaiko.rocks/favicon.ico</url>
      <title>posts by nikita galaiko</title>
      <link>https://nikita.galaiko.rocks/posts</link>
    </image>
    <item>
      <title>from hledger to ledger</title>
      <link>https://nikita.galaiko.rocks/posts/from-hledger-to-ledger.html</link>
      <guid>https://nikita.galaiko.rocks/posts/from-hledger-to-ledger.html</guid>
      <pubDate>2025-03-13T00:00:00Z</pubDate>
      <description><![CDATA[<p>yesterday i have switched from hleder, that i have been using for
over three yesrs to ledger. all because of one new flow i have to
model.</p>
<p>me and my wife are using the same credit card, which is linked to my
bank account. meaning every month i close the debt, and my wife
transferres me some part of that debt.</p>
<p>which means when we have visited some cafe, and payed from a credit
card, i will log it like that:</p>
<pre><code>2025/03/08 Cafe Pupp
    expenses:Food:Eating Out              508.00 CZK @@ 224.72 SEK
    liabilities:shared:nordea:gold</code></pre>
<p>what i really want is to log say 35% into my wife’s liability</p>
<pre><code>2025/03/08 Cafe Pupp
    expenses:Food:Eating Out              508.00 CZK @@ 224.72 SEK
    liabilities:shared:nordea:gold
    expenses:Food:Eating Out             -177.80 CZK @@ 78,65 SEK
    liabilities:wife                      78.65 SEK</code></pre>
<p>i don’t want to manually calculate that every time, so naturally i’ve
reached out to automated postings.</p>
<p>that’s where that problem starts. hedger doesn’t support <a
href="https://github.com/simonmichael/hledger/issues/1975">references in
auto-posting rules</a></p>
<p>but ledger allows me to do this:</p>
<pre><code>; transactions tagged with shared:: 35% will be shared with wife
; a - The posting’s amount; the balance of an account, without considering children.
; b - The cost of a posting; the cost of an account, without its children.
= expenses and %shared
    $account                                                           (a * -tag(&quot;shared&quot;) * 0.01)
    liabilities:wife                                                   (b *  tag(&quot;shared&quot;) * 0.01)
    equity:conversion:%(commodity(a))-%(commodity(b)):%(commodity(b))  (b * -tag(&quot;shared&quot;) * 0.01)
    equity:conversion:%(commodity(a))-%(commodity(b)):%(commodity(a))  (a *  tag(&quot;shared&quot;) * 0.01)
</code></pre>
<p>which does exactly what i want automatically if i tag transaction
with new ‘shared’ tag like so:</p>
<pre><code>2025/03/08 Cafe Pupp
    ; shared:: 35%
    expenses:Food:Eating Out              508.00 CZK @@ 224.72 SEK
    liabilities:shared:nordea:gold</code></pre>
<p>which is perfect.</p>
<p>also now with ledger i can finally properly track investment lots</p>
]]></description>
    </item>
    <item>
      <title>fixed gear text editors</title>
      <link>https://nikita.galaiko.rocks/posts/fixed-gear-vim.html</link>
      <guid>https://nikita.galaiko.rocks/posts/fixed-gear-vim.html</guid>
      <pubDate>2024-03-30T00:00:00Z</pubDate>
      <description><![CDATA[<p>if you are using vim daily now, it must be feeling great. it certanly
does for me. but some time in the past i had to hammer that skill down
into my muscules, and that was fun by iteself.</p>
<p>it is hard to describe the feeling i had learning vim. but it is
definately the same feeling i have now when i ride on a fixed gear
bike.</p>
<p>to be doing a mundain activity with foreign tools captures a lot of
attention. and it is surprisingly pleasent to pay nearly all the
attention to the present moment.</p>
<p>constantly remembering which mode i am in now and all the shortkeys,
or asessing traffic and people around because i can not stop fast
enough.</p>
<p>i think that is what buddist monks mean when they talk about “living
in the present moment”. there is no past or a future, only me and a that
traffic light ahead that i should either race now or slow down and
wait.</p>
<p>but that feeling flees. i do not have it with vim at all now, after
many years. and i have it less and less on my bike every day.</p>
<p>i would like to keep it for a long as i can.</p>
]]></description>
    </item>
    <item>
      <title>Sverige News</title>
      <link>https://nikita.galaiko.rocks/posts/sverige-news.html</link>
      <guid>https://nikita.galaiko.rocks/posts/sverige-news.html</guid>
      <pubDate>2024-03-12T00:00:00Z</pubDate>
      <description><![CDATA[<p>i have been using <a
href="https://thetruestory.news/en">thetruestorynews</a> for a while
now. idea of automatic news aggregation, without any human curation, is
very appealing to me.</p>
<p>a few days ago <a
href="https://duarteocarmo.com/blog/newshavn-danish-news-in-english">this
post</a> popped up in my rss feed. it is about a small service Duarte
built for himself to keep track of news in denmark, where he lives, but
does not speak danish.</p>
<p>i thought it would be cool to have something similar for sweden,
where i live, but do not speak swedish. so i built it. with a little
sprinkles of ai.</p>
<p>instead of translating articles, my service first groups them by
meaning and only translates headlines for each group.</p>
<p>grouping is done by using openai’s embeddings api and dbscan
algorithm. it is not perfect, but good enough for my use case.</p>
<p>here it is: <a
href="https://sverige-news.fly.dev">sverige-news.fly.dev</a></p>
]]></description>
    </item>
    <item>
      <title>2024 website rewrite</title>
      <link>https://nikita.galaiko.rocks/posts/2024-website-rewrite.html</link>
      <guid>https://nikita.galaiko.rocks/posts/2024-website-rewrite.html</guid>
      <pubDate>2024-01-16T00:00:00Z</pubDate>
      <description><![CDATA[<p>i like the idea of having one single binary with the complete website
inside.</p>
<p>i also like rust and have become comfortable with it last year.</p>
<p>and since new year is a good reason to rewrite your entire website to
a new stack,</p>
<p>this website is now powered by a single binary built with rust.</p>
<p><a
href="https://github.com/ngalaiko/galaiko.rocks/tree/904bfa15ce37eb3944b223e98e6c0fcadd137ee9">source</a></p>
]]></description>
    </item>
    <item>
      <title>My daily apps at the end of 2023</title>
      <link>https://nikita.galaiko.rocks/posts/daily-apps-2023.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/my-default-apps-at-the-end-of-2023/</guid>
      <pubDate>2023-11-07T00:00:00Z</pubDate>
      <description><![CDATA[<p>jumping on a <a href="https://defaults.rknight.me">hype train</a>
here:</p>
<table>
<colgroup>
<col style="width: 46%" />
<col style="width: 53%" />
</colgroup>
<tbody>
<tr>
<td>📨 Mail Client</td>
<td>Mail.app</td>
</tr>
<tr>
<td>📮 Mail Server</td>
<td><a href="https://countermail.com">countermail</a></td>
</tr>
<tr>
<td>📝 Notes</td>
<td>Notes.app</td>
</tr>
<tr>
<td>✅ To-Do</td>
<td>Reminders.app</td>
</tr>
<tr>
<td>📷 iPhone Photo Shooting</td>
<td>_</td>
</tr>
<tr>
<td>🟦 Photo Management</td>
<td>_</td>
</tr>
<tr>
<td>📆 Calendar</td>
<td>Calendar.app</td>
</tr>
<tr>
<td>📁 Cloud File Storage</td>
<td>iCloud</td>
</tr>
<tr>
<td>📖 RSS</td>
<td><a href="https://netnewswire.com">NetNewsWire</a></td>
</tr>
<tr>
<td>🙍🏻‍♂️ Contacts</td>
<td>Contacts.app</td>
</tr>
<tr>
<td>🌐 Browser</td>
<td>Safari</td>
</tr>
<tr>
<td>💬 Chat</td>
<td><a href="https://telegram.org">Telegram</a></td>
</tr>
<tr>
<td>🔖 Bookmarks</td>
<td>_</td>
</tr>
<tr>
<td>📑 Read It Later</td>
<td>_</td>
</tr>
<tr>
<td>📜 Word Processing</td>
<td>vim, Pages.app</td>
</tr>
<tr>
<td>📈 Spreadsheets</td>
<td>Numbers.app</td>
</tr>
<tr>
<td>📊 Presentations</td>
<td>Keynote.app</td>
</tr>
<tr>
<td>🛒 Shopping Lists</td>
<td>Reminders.app</td>
</tr>
<tr>
<td>🍴 Meal Planning</td>
<td>_</td>
</tr>
<tr>
<td>💰 Budgeting and Personal Finance</td>
<td><a href="https://hledger.org">hledger</a></td>
</tr>
<tr>
<td>📰 News</td>
<td>_</td>
</tr>
<tr>
<td>🎵 Music</td>
<td>Apple Music</td>
</tr>
<tr>
<td>🎤 Podcasts</td>
<td><a href="https://overcast.fm">Overcast</a></td>
</tr>
<tr>
<td>🔐 Password Management</td>
<td><a href="https://strongboxsafe.com">Strongbox</a></td>
</tr>
</tbody>
</table>
<p>one thing I’ve discovered browsing through other people’s default
apps - there are mostly no apps i haven’t heard about.</p>
<p>which either means I spend too much time in the Internet, or that
there are not so many good apps after all.</p>
]]></description>
    </item>
    <item>
      <title>programming metaphor</title>
      <link>https://nikita.galaiko.rocks/posts/programming-metaphor.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/programming-metaphor/</guid>
      <pubDate>2023-01-19T00:00:00Z</pubDate>
      <description><![CDATA[<p>in this post i will be describing a programming metaphor. i use it to
explain to people outside it what does it mean to work as a software
engineer. it proved itself useful and i do not recall seeing it anywhere
else. here it is:</p>
<p>first, being a software engineer is a mix between being an architect
and being a writer. most people can imagine what both architects’ and
writers’ do. so the comparison like that is a good start.</p>
<p>architect part:</p>
<ul>
<li><p>considering business requirements</p>
<p>a building has a purpose: it’s a mall, bridge, apartement house,
hotel, etc. architects convert buisiness requirements into something
that could solve a buisiness problem. that’s what programmers do too.
maybe we are building a social network, text editor, or photo editing
tool - it’s all about solving a problem.</p></li>
<li><p>applying technical expertise</p>
<p>building something is always constrained by a real world. and those
constraint affect a lot how you build a solution for a proble. for
architects it’s a physical limitations that constraint a building shape
or materials they can use. programmers are limited by internet
connectivity, processor power, memory size, etc.</p></li>
<li><p>a style</p>
<p>the artifact inevitably captures personality. same way you can
sometimes tell when a building was created, or who is the author, you
could tell similar things by reading programmer’s code.</p></li>
<li><p>organization structure</p>
<p>large projects involve a lot of people. high level architects who
prepare blueprints. low level workers who put briks together. managers
all around. specialists who take care of electricity, painting or
putting the right amount of trees around.</p>
<p>software organizations are built in the same way. different people
own different part of a software system. some have different
specializations, some do not write actuall code at all anymore.</p></li>
</ul>
<p>writer part:</p>
<ul>
<li><p>self-fulfilling prophecy</p>
<p>here is the most interesting part for me.</p>
<p>since software exists somewhere between real world and your computer,
you can not build it by putting physical things together. what you do
instead, you write down a <em>very</em> detailed description of what you
want to build and how to do that. and then it just happens, becoming
some kind of a self-fulfilling prophecy.</p>
<p>imagine if you had a magic book where you could write down a very
detailed description of your dream house. after you’ve written it down,
you have the house built.</p></li>
<li><p>using a language</p>
<p>writing means using a language. computers do not understand english
yet, but similar aspects matter. is it easy to read? how well is it
structured? and so on.</p></li>
<li><p>many ways to write it</p>
<p>you can communicate a similar idea by writing a poem, or a very
strict scientific text. it can be short, or long. you could rephrase the
same thought over and over again. you can translate it to a different
language, because not all people speak the same language.</p>
<p>all those things are almost literaly the same in the programming
world.</p></li>
</ul>
<p>this metaphor could also be used to explain version control:</p>
<pre><code>&gt; how to organize multiple people writing the same book at the same time?</code></pre>
<p>or why software is never completed</p>
<pre><code>&gt; like if environment around your building is constantly changing, so you have to reinforce / adjust / extend parts to adjust</code></pre>
]]></description>
    </item>
    <item>
      <title>my ideal haircut</title>
      <link>https://nikita.galaiko.rocks/posts/haircut.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/my-ideal-haircut/</guid>
      <pubDate>2023-01-06T00:00:00Z</pubDate>
      <description><![CDATA[<p>i was just about to go outside to grap something to eat. and while i
was putting my hat on (because it’s winter outside), it hit me with a
perfect description of a what an ideal haircut is to me. here it
goes:</p>
<ol type="1">
<li><p>it must fit inside my hat</p>
<p>right now i have a little too much of hairs to fit inside the hat. it
kind of feels like i am stuffing the hat with hairs a little bit - that
i’d like to avoid</p></li>
<li><p>when i take my hat off, the hairs should already be good</p>
<p>i don’t want to think about how i look just after i take my hat off.
i’d like it to be exactly as i looked when i left my home</p></li>
</ol>
<p>normally, this limits me quite a bit in terms of the hair length. i
just never realised i prefer shorter haircuts because the place i grew
up in gets cold.</p>
]]></description>
    </item>
    <item>
      <title>No more tracking</title>
      <link>https://nikita.galaiko.rocks/posts/tracking.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/no-more-tracking/</guid>
      <pubDate>2022-12-30T00:00:00Z</pubDate>
      <description><![CDATA[<p>i do not wish to know which movies i’ve seen last year. or how many
steps i’ve walked last month. i do not care which artist i’ve listened
to the most. i’ve removed all bookmarks and do not plan to use it
again.</p>
<p>accumulating useless information like that only stresses me and is
not useful at all. i usually rememeber what i actually liked and will
use that from now on.</p>
<p>still, some journaling i consider important. like keeping a <a
href="https://hledger.org">ledger</a> of my financial history - that is
useful.</p>
]]></description>
    </item>
    <item>
      <title>GitHub powered comments for a static website</title>
      <link>https://nikita.galaiko.rocks/posts/comments.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/comments/</guid>
      <pubDate>2022-10-04T00:00:00Z</pubDate>
      <description><![CDATA[<p>after <a href="/posts/blog/hello-indieweb/">implementing and then
removing indieweb’s webmentions</a>, i still kept thinking about a good
way to allow comments on this website. a good way for me is:</p>
<ul>
<li>without a dedicated server software that i have to run and
maintain</li>
<li>works without javascript</li>
<li>doesn’t share data with 3rd parties</li>
</ul>
<p>and last week <a href="https://grishaev.me/de-js-3/">this post</a>
poped up in my rss feed. it’s written in russian, so i’ll summarize it
briefly.</p>
<p>the author noticed that disqus (a cloud comments engine) that he uses
sends a lot of garbage js requests and decided to fix that. the fix is
neat: use github pull requests to create website comments.</p>
<p>i really like the idea, so now my website has comments that work in a
silimar (yet a little beter) way! here is how:</p>
<ol type="1">
<li>i have a github <a
href="https://github.com/ngalaiko/galaiko.rocks/blob/1d1c6d6858250272814a1f60bd18e74d8018f9e2/.github/workflows/create-comment.yaml">action</a>
to create a new comment. it’s really simple: given a author name, url
and comment body, create a new .md file with the coment body like
this:</li>
</ol>
<div class="sourceCode" id="cb1"><pre class="sourceCode md"><code class="sourceCode markdown"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">---</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="an">pathname:</span><span class="co"> &quot;/posts/blog/cluster/&quot;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="an">author-name:</span><span class="co"> &quot;Nikita&quot;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="an">timestamp:</span><span class="co"> &quot;1664822102&quot;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co">---</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>comment body</span></code></pre></div>
<ol start="2" type="1">
<li>a <a href="https://kit.svelte.dev/docs/form-actions">sveltekit
form</a> to trigger action via http:</li>
</ol>
<pre class="svelte"><code>&lt;form method=&quot;POST&quot; use:enhance&gt;
 &lt;!-- author name input --&gt;
 &lt;label for=&quot;author_name&quot;&gt; Your name: &lt;/label&gt;
 &lt;input name=&quot;author_name&quot; type=&quot;text&quot; required /&gt;

 &lt;!-- challange text --&gt;
 &lt;label for=&quot;solution&quot;&gt;{data.challange} = &lt;/label&gt;
 &lt;input name=&quot;solution&quot; type=&quot;text&quot; required /&gt;

 &lt;!-- comment body --&gt;
 &lt;textarea rows=&quot;3&quot; name=&quot;body&quot; type=&quot;text&quot; required /&gt;

 &lt;!-- url pathname to link comment to the page --&gt;
 &lt;input name=&quot;pathname&quot; value={$page.url.pathname} type=&quot;text&quot; hidden /&gt;

 &lt;!-- input challange for validation --&gt;
 &lt;input name=&quot;challange&quot; value={data.challange} type=&quot;text&quot; hidden /&gt;

 &lt;input type=&quot;submit&quot; value=&quot;Comment&quot; /&gt;
&lt;/form&gt;</code></pre>
<ol start="3" type="1">
<li>some server-side typescript to trigger the action:</li>
</ol>
<div class="sourceCode" id="cb3"><pre class="sourceCode ts"><code class="sourceCode typescript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { solve } <span class="im">from</span> <span class="st">&quot;$lib/challange&quot;</span><span class="op">;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { invalid } <span class="im">from</span> <span class="st">&quot;@sveltejs/kit&quot;</span><span class="op">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="im">type</span> { Actions } <span class="im">from</span> <span class="st">&quot;./$types&quot;</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { env } <span class="im">from</span> <span class="st">&quot;$env/dynamic/private&quot;</span><span class="op">;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> GITHUB_TOKEN <span class="op">=</span> env<span class="op">.</span><span class="at">GITHUB_TOKEN</span><span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> trigger <span class="op">=</span> (inputs<span class="op">:</span> <span class="dt">any</span>) <span class="kw">=&gt;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">fetch</span>(</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>   <span class="st">&quot;https://api.github.com/repos/ngalaiko/galaiko.rocks/actions/workflows/create-comment.yaml/dispatches&quot;</span><span class="op">,</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>   {</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>     method<span class="op">:</span> <span class="st">&quot;POST&quot;</span><span class="op">,</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>     headers<span class="op">:</span> {</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>       Accept<span class="op">:</span> <span class="st">&quot;application/vnd.github+json&quot;</span><span class="op">,</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>       Authorization<span class="op">:</span> <span class="vs">`Bearer </span><span class="sc">${</span>GITHUB_TOKEN<span class="sc">}</span><span class="vs">`</span><span class="op">,</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>     }<span class="op">,</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>     body<span class="op">:</span> <span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>({</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>       ref<span class="op">:</span> <span class="st">&quot;master&quot;</span><span class="op">,</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>       inputs<span class="op">,</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>     })<span class="op">,</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a> )<span class="op">;</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">const</span> actions<span class="op">:</span> Actions <span class="op">=</span> {</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">default</span><span class="op">:</span> <span class="kw">async</span> ({ request }) <span class="kw">=&gt;</span> {</span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> data <span class="op">=</span> <span class="cf">await</span> request<span class="op">.</span><span class="fu">formData</span>()<span class="op">;</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> body <span class="op">=</span> data<span class="op">.</span><span class="fu">get</span>(<span class="st">&quot;body&quot;</span>)<span class="op">;</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> author_name <span class="op">=</span> data<span class="op">.</span><span class="fu">get</span>(<span class="st">&quot;author_name&quot;</span>)<span class="op">;</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> pathname <span class="op">=</span> data<span class="op">.</span><span class="fu">get</span>(<span class="st">&quot;pathname&quot;</span>)<span class="op">;</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> solution <span class="op">=</span> data<span class="op">.</span><span class="fu">get</span>(<span class="st">&quot;solution&quot;</span>)<span class="op">;</span></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a>   <span class="kw">const</span> challange <span class="op">=</span> data<span class="op">.</span><span class="fu">get</span>(<span class="st">&quot;challange&quot;</span>)<span class="op">;</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a>   <span class="cf">if</span> (body <span class="op">===</span> <span class="st">&quot;&quot;</span>)</span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>     <span class="cf">return</span> <span class="fu">invalid</span>(<span class="dv">400</span><span class="op">,</span> { message<span class="op">:</span> <span class="st">&quot;Message can not be empty&quot;</span> })<span class="op">;</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a>   <span class="cf">if</span> (author_name <span class="op">===</span> <span class="st">&quot;&quot;</span>)</span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a>     <span class="cf">return</span> <span class="fu">invalid</span>(<span class="dv">400</span><span class="op">,</span> { message<span class="op">:</span> <span class="st">&quot;Please, fill in name&quot;</span> })<span class="op">;</span></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a>   <span class="cf">if</span> (solution <span class="op">===</span> <span class="st">&quot;&quot;</span>) {</span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a>     <span class="cf">return</span> <span class="fu">invalid</span>(<span class="dv">400</span><span class="op">,</span> { message<span class="op">:</span> <span class="st">&quot;Challange solution is empty&quot;</span> })<span class="op">;</span></span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a>   } <span class="cf">else</span> <span class="cf">if</span> (solution <span class="op">!==</span> <span class="fu">solve</span>(challange <span class="im">as</span> <span class="dt">string</span>)) {</span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a>     <span class="cf">return</span> <span class="fu">invalid</span>(<span class="dv">400</span><span class="op">,</span> { message<span class="op">:</span> <span class="st">&quot;Wrong solution&quot;</span> })<span class="op">;</span></span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a>   } <span class="cf">else</span> {</span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a>     <span class="kw">const</span> res <span class="op">=</span> <span class="cf">await</span> <span class="fu">trigger</span>({ body<span class="op">,</span> author_name<span class="op">,</span> pathname })<span class="op">;</span></span>
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true" tabindex="-1"></a>     <span class="cf">if</span> (res<span class="op">.</span><span class="at">status</span> <span class="op">!==</span> <span class="dv">204</span>) {</span>
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true" tabindex="-1"></a>       <span class="cf">return</span> <span class="fu">invalid</span>(<span class="dv">500</span><span class="op">,</span> { message<span class="op">:</span> <span class="cf">await</span> res<span class="op">.</span><span class="fu">text</span>() })<span class="op">;</span></span>
<span id="cb3-46"><a href="#cb3-46" aria-hidden="true" tabindex="-1"></a>     } <span class="cf">else</span> {</span>
<span id="cb3-47"><a href="#cb3-47" aria-hidden="true" tabindex="-1"></a>       <span class="cf">return</span> {</span>
<span id="cb3-48"><a href="#cb3-48" aria-hidden="true" tabindex="-1"></a>         success<span class="op">:</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb3-49"><a href="#cb3-49" aria-hidden="true" tabindex="-1"></a>         message<span class="op">:</span></span>
<span id="cb3-50"><a href="#cb3-50" aria-hidden="true" tabindex="-1"></a>           <span class="st">&quot;Thanks! Your comment will appear after moderation. Check in later!&quot;</span><span class="op">,</span></span>
<span id="cb3-51"><a href="#cb3-51" aria-hidden="true" tabindex="-1"></a>       }<span class="op">;</span></span>
<span id="cb3-52"><a href="#cb3-52" aria-hidden="true" tabindex="-1"></a>     }</span>
<span id="cb3-53"><a href="#cb3-53" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb3-54"><a href="#cb3-54" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
<span id="cb3-55"><a href="#cb3-55" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>and that’s it! thanks to sveltekit, the implementation is both nice,
js-free and i don’t need to think about hosting</p>
]]></description>
    </item>
    <item>
      <title>Hello, IndieWeb</title>
      <link>https://nikita.galaiko.rocks/posts/indieweb.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/hello-indieweb/</guid>
      <pubDate>2022-04-16T00:00:00Z</pubDate>
      <description><![CDATA[<p>In this post I want to share how this website connects with <a
href="https://indieweb.org">IndieWeb</a>.</p>
<h2 id="what-is-indieweb">What is IndieWeb</h2>
<p><a href="https://indieweb.org">IndieWeb</a> how it describes itself,
is:</p>
<blockquote>
<p>a people-focused alternative to the “corporate web”</p>
</blockquote>
<p>I also don’t like the “corporate web” and try not to participate in
it. However, right now IndieWeb for me is mostly something fun to do on
the weekends.</p>
<p>On a more technical level, it’s a combination of protocols like <a
href="https://indieweb.org/Webmention">WebMentions</a>, <a
href="https://indieweb.org/Microsub">Microsub</a> and <a
href="https://www.w3.org/TR/social-web-protocols/">some others</a> that
together enable a distributed social interaction on the Web.</p>
<h2 id="what-i-would-like-to-achieve">What I would like to achieve</h2>
<ul>
<li>be discoverable on IndieWeb</li>
<li>be able to interact with others on IndieWeb</li>
<li>not use any 3rd party IndieWeb services like <a
href="https://webmention.io">webmention.io</a></li>
<li>pay zero moneys for my setup</li>
<li>have all of my data locally stored in a form of static files</li>
<li>my website to be full functioning without client side
javascript</li>
</ul>
<h2 id="setup">Setup</h2>
<p>I used to power this website with <a
href="https://gohugo.io">Hugo</a> - a static website generator. But it
doesn’t quite fit IndieWeb requirements for me.</p>
<p>Most people, as I understand, use centralized platforms like <a
href="https://webmention.io">webmention.io</a> or <a
href="https://micro.blog">micro.blog</a> mixed with different <a
href="https://wordpress.org/plugins/indieweb/">CMS plugins</a> to be on
IndieWeb. For me - it’s no fun. I want to do it all myself - thus static
website won’t do it. I have to have a server to at least receive
webmentions.</p>
<p>Some time ago <a href="https://kit.svelte.dev">SvelteKit</a> got me
interested. SvelteKit is a framework to build webapps using <a
href="https://svelte.dev">Svelte</a>. What is especially cool about it
for my use-case is that it is:</p>
<ul>
<li>prerendered by default</li>
<li>comes with <a
href="https://github.com/sveltejs/kit/tree/master/packages">adapters</a>
for different deploy targets out of the box</li>
<li>allows to seamlessly write serverless functions</li>
</ul>
<p>With that said, my tech choice is: <a
href="https://kit.svelte.dev">SvelteKit</a> deployed to <a
href="https://pages.cloudflare.com">Cloudflare Pages</a></p>
<h3 id="sveltekit">SvelteKit</h3>
<p>I won’t dive into details here, you can check out the <a
href="https://github.com/ngalaiko/blog">code</a>. Pretty much it’s <a
href="https://kit.svelte.dev">SvelteKit</a> with <a
href="https://mdsvex.com">mdsvex</a>. While configuring it, there two
articles helped me a lot:</p>
<ul>
<li><a
href="https://joshcollinsworth.com/blog/build-static-sveltekit-markdown-blog/">Let’s
learn SvelteKit by building a static Markdown blog from scratch</a></li>
<li><a href="https://www.furudean.com/blog/svelte-kit-mdsvex">MDSveX and
Svelte Kit</a></li>
</ul>
<h2 id="microformats">Microformats</h2>
<p>First step in IndieWeb is to setup <a
href="http://microformats.org">microformats</a>. It’s a data format
built on top of xml that provides a standard way of communicating
between IndieWeb sites, meaning:</p>
<p>You add some attributes to your website’s html:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;h-card&quot;</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;/&quot;</span><span class="ot"> rel</span><span class="op">=</span><span class="st">&quot;me&quot;</span><span class="dt">&gt;</span>Jimmy<span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span></code></pre></div>
<p>Microformats parsers take html and convert it to standardised
JSON:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&quot;items&quot;</span><span class="fu">:</span> <span class="ot">[</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&quot;properties&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;Jimmy&quot;</span><span class="ot">]</span><span class="fu">,</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">&quot;url&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;http://example.com/&quot;</span><span class="ot">]</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>      <span class="fu">},</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&quot;type&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;h-card&quot;</span><span class="ot">]</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">}</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>  <span class="ot">]</span><span class="fu">,</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&quot;rel-urls&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&quot;http://example.com&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&quot;rels&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;me&quot;</span><span class="ot">]</span><span class="fu">,</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&quot;text&quot;</span><span class="fu">:</span> <span class="st">&quot;Jimmy&quot;</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="fu">}</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>  <span class="fu">},</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&quot;rels&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&quot;me&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;http://example.com/&quot;</span><span class="ot">]</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>  <span class="fu">}</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<p>The JSON is used to power comments functionality on your website (for
example).</p>
<p>You can read more <a
href="https://indieweb.org/microformats">here</a> and <a
href="http://microformats.org">here</a>.</p>
<h2 id="webmentions">Webmentions</h2>
<p>Second step is webmentions. Webmentions is a very simple protocol to
let other’s know that you’ve mentioned their page. A mention could be
anything form a ‘like’ to ‘comment’ or even ‘rsvp’.</p>
<p>Since <a
href="https://www.w3.org/TR/webmention/#updating-existing-webmentions-li-4">the
protocol</a> is so simple, I am implementing it myself. Both because
it’s more fun and to satisfy my requirements for the project.</p>
<p>There are two parts when it comes to webmentions: receiving and
sending.</p>
<h3 id="receiving">Receiving</h3>
<p>Since I don’t want to pay for the hosting, here is a plan:</p>
<ol type="1">
<li>When someone send me a webmention, the request is be processed by a
serverless handler hosted on <a
href="https://developers.cloudflare.com/workers/">cloudflare workers</a>
and then stored in their <a
href="https://developers.cloudflare.com/workers/platform/pricing/#workers-kv">key
value storage</a></li>
<li>Later, <a
href="https://github.com/ngalaiko/blog/blob/12021e08b9310aaae9b3d8aa3a179cc9e3549473/scripts/webmentions/download.ts">an
export script</a> is triggered by myself manually or via GitHub Actions
cronjob to download all of the new webmentions <a
href="https://github.com/ngalaiko/blog/blob/12021e08b9310aaae9b3d8aa3a179cc9e3549473/src/lib/data/webmentions.json">into
my repository</a></li>
<li>Then, <a
href="https://github.com/ngalaiko/blog/blob/12021e08b9310aaae9b3d8aa3a179cc9e3549473/scripts/webmentions/process.ts">a
processing script</a> is triggered in a similar manner to process new
webmentions</li>
<li>Viola, now all the raw webmentions data is available in my
repository at all times, and I can use it to render static pages</li>
</ol>
<p>What I like about this plan is that:</p>
<ul>
<li>it doesn’t really depend much on the hosting solution since
SvelteKit is quite flexible with that</li>
<li>I expect the amount of data and read/write operations be close to 0,
so free tier on cloudflare and github is more than enough</li>
<li>all of the data is stored inside my repository which means I can
render static pages</li>
</ul>
<p>Of course the non real timeness of the solution might be considered a
downside.</p>
<h3 id="sending">Sending</h3>
<p>After receiving part was done I conviniently had written code that
can be reused to send webmentions too. Since this website is fully
prerendered and distributed as a set of static files, I can analyze
those files and extract my webmentions from it.</p>
<p>Once webmentions are extracted, it’s trivial to implement <a
href="https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint">the
discovery</a> and make <a
href="https://github.com/ngalaiko/galaiko.rocks/blob/12021e08b9310aaae9b3d8aa3a179cc9e3549473/scripts/webmentions/send.ts">script</a>
ping the endpoints.</p>
<h2 id="test">Test</h2>
<p>The footer of this article contains a list of received webmentions,
and I’ve already sent one!</p>
<h2 id="update">Update</h2>
<p>Support for webmentions was successfully removed, since I do not use
it :)</p>
]]></description>
    </item>
    <item>
      <title>Raspberry Pi: K8s cluster</title>
      <link>https://nikita.galaiko.rocks/posts/rpi-k8s.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/raspberry-k8s/</guid>
      <pubDate>2019-06-24T00:00:00Z</pubDate>
      <description><![CDATA[<p>I spent too much time configuring Kubernetes cluster on Raspberry Pi
today, so here are notes for my future self on how to do that:</p>
<h2 id="sd-card">SD card</h2>
<ul>
<li><p>Download operation system.</p>
<p>I am using <a
href="https://github.com/hypriot/image-builder-rpi/releases/download/v1.10.0/hypriotos-rpi-v1.10.0.img.zip">HypriotOS
v1.10.0</a> It is based on <strong>Raspbian Buster Lite</strong>, has a
preinstalled docker and some other minor things to simplify cluster
setup:</p>
<pre><code>  $ uname -a
    Linux node-red 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux
  $ docker version
    Client:
     Version:           18.06.3-ce
     API version:       1.38
     Go version:        go1.10.3
     Git commit:        d7080c1
     Built:             Wed Feb 20 02:42:54 2019
     OS/Arch:           linux/arm
     Experimental:      false

    Server:
     Engine:
     Version:          18.06.3-ce
     API version:      1.38 (minimum version 1.12)
     Go version:       go1.10.3
     Git commit:       d7080c1
     Built:            Wed Feb 20 02:38:25 2019
     OS/Arch:          linux/arm
     Experimental:     false</code></pre></li>
<li><p>Flash it to SD cards using <a
href="https://github.com/hypriot/flash/releases">flash</a></p>
<p>Don’t forget to define a hostname. It will save you some time
later.</p>
<pre><code>  $ flash -n node-red ./Downloads/hypriotos-rpi-v1.10.0.img</code></pre></li>
<li><p>Provision all nodes you have like this and boot them up.</p></li>
<li><p>Install Kubernetes on <strong>all</strong> nodes.</p>
<p>Note the version here: <code>1.13.5</code>. Because of changes in
<code>1.14.0</code>, Kubernetes requires enabled pids cgroup. But
kernels before <code>4.19.46-v7+</code> do not support it. If you are
reading this after some time, it should be fixed, and the latest version
of Kubernetes might work just fine.</p>
<pre><code>  $ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - &amp;&amp; \
      echo &quot;deb http://apt.kubernetes.io/ kubernetes-xenial main&quot; | sudo tee /etc/apt/sources.list.d/kubernetes.list &amp;&amp; \
      sudo apt-get update -q &amp;&amp; \
      sudo apt-get install -qy kubeadm=1.13.5 kubectl=1.13.5 kubelet=1.13.5</code></pre></li>
<li><p>Initialize Kubernetes on the <strong>master</strong> node:</p>
<pre><code>  $ sudo kubeadm init</code></pre>
<p>Notice <code>sudo</code> here. For some reason, if you do it as
<code>root</code>, it can fail with an error (couldn’t find what the
error was :( )</p>
<p>If all goes fine, you will see an output similar to:</p>
<pre><code>  ...
  Your Kubernetes master has initialized successfully!
  To start using your cluster, you need to run the following as a regular user:
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    You should now deploy a pod network to the cluster.
  Run &quot;kubectl apply -f [podnetwork].yaml&quot; with one of the options listed at:
    https://kubernetes.io/docs/concepts/cluster-administration/addons/
  You can now join any number of machines by running the following on each node
  as root:
    kubeadm join --token TOKEN 192.168.1.100:6443 --discovery-token-ca-cert-hash HASH</code></pre></li>
<li><p>Do what the output says:</p>
<pre><code>  $ sudo cp /etc/kubernetes/admin.conf $HOME/
  $ sudo chown $(id -u):$(id -g) $HOME/admin.conf
  $ export KUBECONFIG=$HOME/admin.conf</code></pre>
<p>Now you should be able to list all nodes. There is a single
<strong>NotReady</strong> <strong>master</strong> node at this
point:</p>
<pre><code>  $ kubectl get nodes
  NAME         STATUS     ROLES    AGE   VERSION
  node-red     NotReady   master   17m   v1.13.5</code></pre></li>
<li><p>Add other nodes to the cluster.</p>
<pre><code>  $ sudo kubeadm join --token TOKEN 192.168.1.100:6443 --discovery-token-ca-cert-hash HASH</code></pre>
<p>Notice <code>sudo</code> again.</p></li>
<li><p>Now, you should be able to see all nodes from the master
node:</p>
<pre><code>  $ kubectl get nodes
  NAME         STATUS     ROLES    AGE    VERSION
  node-black   NotReady   &lt;none&gt;   106m   v1.13.5
  node-blue    NotReady   &lt;none&gt;   105m   v1.13.5
  node-green   NotReady   &lt;none&gt;   105m   v1.13.5
  node-red     NotReady   master   110m   v1.13.5</code></pre></li>
<li><p>Deploy container network from the <strong>master</strong>
node.</p>
<pre><code>  $ kubectl apply -f &quot;https://cloud.weave.works/k8s/net?k8s-version=1.13.5&quot;</code></pre></li>
<li><p>After some time, all nodes should be ready.</p>
<pre><code>  $ kubectl get nodes
  NAME         STATUS     ROLES    AGE    VERSION
  node-black   Ready     &lt;none&gt;   106m   v1.13.5
  node-blue    Ready     &lt;none&gt;   105m   v1.13.5
  node-green   Ready     &lt;none&gt;   105m   v1.13.5
  node-red     Ready     master   110m   v1.13.5</code></pre></li>
</ul>
<h1 id="links">Links</h1>
<ul>
<li><a
href="https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/">https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/</a></li>
<li><a
href="https://kubecloud.io/setting-up-a-kubernetes-1-11-raspberry-pi-cluster-using-kubeadm-952bbda329c8">https://kubecloud.io/setting-up-a-kubernetes-1-11-raspberry-pi-cluster-using-kubeadm-952bbda329c8</a></li>
<li><a
href="https://github.com/hypriot/flash">https://github.com/hypriot/flash</a></li>
<li><a
href="https://github.com/teamserverless/k8s-on-raspbian/issues/16">https://github.com/teamserverless/k8s-on-raspbian/issues/16</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Words Count</title>
      <link>https://nikita.galaiko.rocks/posts/words-count.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/words-count/</guid>
      <pubDate>2019-05-11T00:00:00Z</pubDate>
      <description><![CDATA[<p>Last week I participated in a small competiotion at work. The goal
was to calculate the top 10 the most common words in a file and print
them with number of occurences. For testing we used export from
HackerNews comments from 2012 until today, and that file was 4GB.</p>
<p>I will describe what optimizations I used to solve the problem from
the most to the least obvious.</p>
<p>Solution was measured on MacBook Pro 2018 with 2,2 GHz Intel Core i7
CPU and 32 GB RAM.</p>
<h2 id="generic-solution">Generic solution</h2>
<p>The most simple way to solve this is to iterate over the file, save
words to a map with number of occurences, then iterate over the map and
print top 10 most common words.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> countWords<span class="op">(</span>fileData <span class="op">[]</span><span class="dt">byte</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    words <span class="op">:=</span> <span class="kw">map</span><span class="op">[</span><span class="dt">string</span><span class="op">]</span><span class="dt">uint</span><span class="op">{}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    wordBuf <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">byte</span><span class="op">,</span> <span class="dv">64</span><span class="op">)</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    wordPos <span class="op">:=</span> <span class="dv">0</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> c <span class="op">:=</span> <span class="kw">range</span> fileData <span class="op">{</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            <span class="cf">switch</span> <span class="op">{</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">case</span> c <span class="op">&gt;=</span> <span class="ch">&#39;A&#39;</span> <span class="op">&amp;&amp;</span> c <span class="op">&lt;=</span> <span class="ch">&#39;Z&#39;</span><span class="op">:</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>                    c <span class="op">+=</span> <span class="dv">32</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">fallthrough</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">case</span> c <span class="op">&gt;=</span> <span class="ch">&#39;a&#39;</span> <span class="op">&amp;&amp;</span> c <span class="op">&lt;=</span> <span class="ch">&#39;z&#39;</span><span class="op">:</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">if</span> wordPos <span class="op">==</span> maxLen <span class="op">{</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>                            <span class="cf">continue</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>                    <span class="op">}</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>                    wordBuf<span class="op">[</span>wordPos<span class="op">]</span> <span class="op">=</span> c</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>                    wordPos<span class="op">++</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>            <span class="cf">default</span><span class="op">:</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">if</span> wordPos <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">continue</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>                    <span class="op">}</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>                    words<span class="op">[</span><span class="dt">string</span><span class="op">(</span>wordBuf<span class="op">[:</span>wordPos<span class="op">])]++</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>                    wordPos <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>            words<span class="op">[</span><span class="dt">string</span><span class="op">(</span>wordBuf<span class="op">[:</span>wordPos<span class="op">])]++</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This will make a map with number of occurences of each English word
in the file.</p>
<p>It takes ~1min to make this map.</p>
<p>After that keys needs to be sorted:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>freq <span class="op">:=</span> <span class="bu">make</span><span class="op">([]*</span><span class="dt">string</span><span class="op">,</span> <span class="dv">2</span><span class="op">&lt;&lt;</span><span class="dv">25</span><span class="op">)</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> word<span class="op">,</span> count <span class="op">:=</span> <span class="kw">range</span> words <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    wCopy <span class="op">:=</span> word</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    freq<span class="op">[</span>count<span class="op">]</span> <span class="op">=</span> <span class="op">&amp;</span>wCopy</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>done <span class="op">:=</span> <span class="dv">0</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> i <span class="op">:=</span> <span class="dt">uint64</span><span class="op">(</span><span class="bu">len</span><span class="op">(</span>freq<span class="op">)</span> <span class="op">-</span> <span class="dv">1</span><span class="op">);</span> i <span class="op">&gt;</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> done <span class="op">&lt;</span> <span class="dv">10</span><span class="op">;</span> i<span class="op">--</span> <span class="op">{</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> freq<span class="op">[</span>i<span class="op">]</span> <span class="op">==</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">continue</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    fmt<span class="op">.</span>Printf<span class="op">(</span><span class="st">&quot;%s: %d</span><span class="ch">\n</span><span class="st">&quot;</span><span class="op">,</span> <span class="op">*</span>freq<span class="op">[</span>i<span class="op">],</span> i<span class="op">)</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    done<span class="op">++</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This is a terrible way of sorting anything in real life, but it works
fast, and that’s exactly what we need in our case. It took ~113ms</p>
<h2 id="reading-file-concurrently">Reading file concurrently</h2>
<p>The next step is to assume that it could go faster if file is
processed in batches concurrently. That is true, but it will also
creates <a href="https://galaiko.rocks/posts/blog/go-data-races/">data
races</a>. To solve it, I will use this implementation of a map with
atomic write.</p>
<p>Another way to go from here is to save results from each thread to
it’s own map and then merge maps.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> fromFile<span class="op">(</span>filepath <span class="dt">string</span><span class="op">,</span> batchSize <span class="dt">int64</span><span class="op">,</span> tk <span class="op">*</span>count<span class="op">.</span>Stream<span class="op">)</span> <span class="dt">error</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>        file<span class="op">,</span> err <span class="op">:=</span> os<span class="op">.</span>Open<span class="op">(</span>filepath<span class="op">)</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> fmt<span class="op">.</span>Errorf<span class="op">(</span><span class="st">&quot;failed to read `%s`: %s&quot;</span><span class="op">,</span> filepath<span class="op">,</span> err<span class="op">)</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">defer</span> file<span class="op">.</span>Close<span class="op">()</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        info<span class="op">,</span> err <span class="op">:=</span> file<span class="op">.</span>Stat<span class="op">()</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> fmt<span class="op">.</span>Errorf<span class="op">(</span><span class="st">&quot;failed to stat `%s`: %s&quot;</span><span class="op">,</span> filepath<span class="op">,</span> err<span class="op">)</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>        all <span class="op">:=</span> info<span class="op">.</span>Size<span class="op">()</span> <span class="op">/</span> batchSize</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>        wg <span class="op">:=</span> <span class="op">&amp;</span>errgroup<span class="op">.</span>Group<span class="op">{}</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> i <span class="op">:=</span> <span class="dt">int64</span><span class="op">(</span><span class="dv">0</span><span class="op">);</span> i <span class="op">&lt;</span> all<span class="op">;</span> i<span class="op">++</span> <span class="op">{</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>                i <span class="op">:=</span> i</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>                <span class="co">// </span><span class="al">NOTE</span><span class="co">: read concurrently and process in batch</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>                wg<span class="op">.</span>Go<span class="op">(</span><span class="kw">func</span><span class="op">()</span> <span class="dt">error</span> <span class="op">{</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>                        buff <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">byte</span><span class="op">,</span> batchSize<span class="op">)</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>                        off<span class="op">,</span> err <span class="op">:=</span> file<span class="op">.</span>ReadAt<span class="op">(</span>buff<span class="op">,</span> batchSize<span class="op">*</span>i<span class="op">)</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">switch</span> err <span class="op">{</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">case</span> <span class="ot">nil</span><span class="op">:</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">case</span> io<span class="op">.</span>EOF<span class="op">:</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>                                <span class="cf">return</span> <span class="ot">nil</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">default</span><span class="op">:</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>                                <span class="cf">return</span> err</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>                        <span class="op">}</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a>                        processBatch<span class="op">(</span>buff<span class="op">[:</span>off<span class="op">],</span> tk<span class="op">)</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a>                        <span class="cf">return</span> <span class="ot">nil</span></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>                <span class="op">})</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> wg<span class="op">.</span>Wait<span class="op">()</span></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>I was using <code>2&lt;&lt;19-1</code> as a <code>batchSize</code>.
This is based on test runs and nothins else.</p>
<p><code>tk</code> here contains an instance of <a
href="https://github.com/cornelk/hashmap/">github.com/cornelk/hashmap</a></p>
<h2 id="law-of-large-numbers">Law of Large numbers</h2>
<p>The last optimization, and the biggest one I’ve made is not
completely about programming.</p>
<p>There is this theorem in probablility theory that says:</p>
<blockquote>
<p>the average of the results obtained from a large number of trials
should be close to the expected value, and will tend to become closer as
more trials are performed</p>
</blockquote>
<p>That means that if you take a large file with English text and count
top 10 words in there, the top will always look almost the same.</p>
<p>Next step here is to google <a
href="https://en.wikipedia.org/wiki/Most_common_words_in_English">most
common words in English</a> and use this list to decrease number of
words we count.</p>
<p>By doing that, amount of writes to the map will dramaticaly decrease,
what will allow to spend less time waiting for write access to the
map.</p>
<p>After implementing this, processing time is ~25s</p>
<p>You can find full code on <a
href="https://github.com/ngalaiko/words">Github</a></p>
]]></description>
    </item>
    <item>
      <title>Forcing interface wrapper</title>
      <link>https://nikita.galaiko.rocks/posts/go-interface.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/interface-wrapper/</guid>
      <pubDate>2019-03-24T00:00:00Z</pubDate>
      <description><![CDATA[<p>Let’s take this interface as an example:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Block <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    Chain<span class="op">(</span>Block<span class="op">)</span> <span class="op">(</span><span class="dt">string</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>I want to make sure that input <code>Block</code> is always valid,
and the output string is never empty if the error is <code>nil</code>.
How can I do that? There are a couple of options.</p>
<p>The first option is to rely on every implementation to validate it,
but it means a boilerplate code that is easy to miss.</p>
<p>Another option is to create another layer and move all of the logic
there. Something like:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Chain <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    Add<span class="op">(</span>Block<span class="op">)</span> <span class="dt">error</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Block <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    Hash<span class="op">()</span> <span class="dt">string</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It’s better, but I don’t want to create another entity.</p>
<p>I can also create an implementation that wraps all other
implementations and does all the checks:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> check <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    i block</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Check<span class="op">(</span>i Block<span class="op">)</span> <span class="op">*</span>check <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">&amp;</span>check<span class="op">{</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        i<span class="op">:</span> i<span class="op">,</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>c <span class="op">*</span>check<span class="op">)</span> Chain<span class="op">(</span>b Block<span class="op">)</span> <span class="op">(</span><span class="dt">string</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    hash<span class="op">,</span> err <span class="op">:=</span> c<span class="op">.</span>i<span class="op">.</span>Chain<span class="op">(</span>b<span class="op">)</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> hash <span class="op">==</span> <span class="st">&quot;&quot;</span> <span class="op">&amp;&amp;</span> err <span class="op">==</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        fmt<span class="op">.</span>Println<span class="op">(</span><span class="st">&quot;err is nil, and hash is empty, do something here.&quot;</span><span class="op">)</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> hash<span class="op">,</span> err</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There is still the same problem: it’s easy to forget to wrap a custom
implementation into the check and skip validation.</p>
<p>Likely, I found a way to enforce it during the build time. To do
that, <code>Block</code> interface and the <code>check</code>
implementation should be slightly changed:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> block <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    Chain<span class="op">(</span>Block<span class="op">)</span> <span class="op">(</span><span class="dt">string</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Block <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    block</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    p<span class="op">()</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Check<span class="op">(</span>i block<span class="op">)</span> Block <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">&amp;</span>check<span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        i<span class="op">:</span> i<span class="op">,</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> check <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    i block</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>c <span class="op">*</span>check<span class="op">)</span> Chain<span class="op">(</span>b Block<span class="op">)</span> <span class="op">(</span><span class="dt">string</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    hash<span class="op">,</span> err <span class="op">:=</span> c<span class="op">.</span>i<span class="op">.</span>Chain<span class="op">(</span>b<span class="op">)</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> hash <span class="op">==</span> <span class="st">&quot;&quot;</span> <span class="op">&amp;&amp;</span> err <span class="op">==</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>        fmt<span class="op">.</span>Println<span class="op">(</span><span class="st">&quot;err is nil, and hash is empty, do something here.&quot;</span><span class="op">)</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> hash<span class="op">,</span> err</span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>c <span class="op">*</span>check<span class="op">)</span> p<span class="op">()</span> <span class="op">{}</span></span></code></pre></div>
<p>Now, it’s impossible to implement <code>Block</code> interface,
because there is no way to implement a private method.</p>
<p>The only way to do that is to implement all public methods and call
<code>Check</code> function.</p>
<p>You can find full example code on <a
href="https://github.com/ngalayko/examples/tree/master/protection">GitHub</a></p>
]]></description>
    </item>
    <item>
      <title>Building a peer to peer messenger</title>
      <link>https://nikita.galaiko.rocks/posts/p2p.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/peer-to-peer/</guid>
      <pubDate>2019-03-20T00:00:00Z</pubDate>
      <description><![CDATA[<p><img src="./p2p.jpg.800x0@2x.webp" width="800" /></p>
<p>The idea of a peer to peer <strong>something</strong> is to create a
system that doesn’t require any centralized server to operate. In the
case of a messenger, two users should be able to communicate directly
between each other until at least one of their instances is running.</p>
<p>That’s why the most important part of such systems is a discovery. If
peers can’t find each other, it’s useless.</p>
<p>The first problem is to build a messenger app, that can discover the
same apps in the network and securely communicate with each other.</p>
<p>The second problem is to allow regular people
(<strong>non-programmers</strong>) to use it. As I can see, there are
two ways here. First is to build a mobile app and discover peers via
Bluetooth or WiFi, plus have some bridge that allows joining two local
networks together via the internet.</p>
<p>I chose another way. Instead, there is a command line app for usage
within the same network. And a dispatcher app which purpose is to manage
a cloud with dockerized peers and create a new instance for every user
that needs it.</p>
<ol type="1">
<li>User goes to a dispatcher webpage and clicks
<strong>Login</strong></li>
<li>Dispatcher creates a new peer in a docker container and redirects
the user to it</li>
</ol>
<p>I don’t think that this approach is super scalable and makes sense in
the real world; it requires too many resources for a single user. But I
have chosen it because it is more fun to implement for me as it needs
more infrastructure work.</p>
<figure>
<img src="./p2p.cloud.jpg.800x0@2x.webp" width="800" alt="cloud" />
<figcaption aria-hidden="true">cloud</figcaption>
</figure>
<h2 id="peer">Peer</h2>
<h3 id="communication">Communication</h3>
<p>Peers use <a href="https://grpc.io/">gRPC</a> to communicate with
each other. It has a few benefits:</p>
<ol type="1">
<li>There is a well defined <a
href="https://github.com/ngalayko/p2p/tree/master/instance/messages/proto">.proto</a>
API schema. So it shouldn’t be a problem to build clients using other
programming languages.</li>
<li>Stream support. Peers can exchange messages over a single TCP
connection (thanks to HTTP/2). There is also ongoing work on supporting
UDP as a transport. Initially, I wanted to use UDP based communication
with QUIC but decided to go with gRPC because of other features.</li>
<li>Small things like TLS, custom resolvers, compression, schema
versioning, binary marshaling out of the box.</li>
</ol>
<p>Overall communication scenario between two peers looks like this:</p>
<ol type="1">
<li>Check if there is an open stream connection to the peer
<ul>
<li>If it exists, send a message using the connection</li>
</ul></li>
<li>Exchange public keys with a peer using an insecure connection</li>
<li>Open a secure stream connection to the peer and send a message.</li>
</ol>
<h2 id="discovery">Discovery</h2>
<p>In general, discovery is used to find other peers in the network.
Discovery message contains name, id, ports, address and a list of known
peers. Public key not included in the discovery as it makes discovery
message too big to be transmitted via UDP multicast.</p>
<p>It also allows the peer to find its address by listening for its own
announcement message.</p>
<p>UDP multicast discovery allows discovery within the same network.
Perfect for standalone runs without docker.</p>
<p>Peers also can register itself in <a
href="https://www.consul.io/">Consul</a> catalog and fetch information
about other peers from there. Perfect for dockerized runs inside docker
swarm as it also can be used by <a
href="https://traefik.io/">Traefik</a> to automatically create routes
for new peers and monitor their health.</p>
<h2 id="dispatcher">Dispatcher</h2>
<p>The goal of this service is to start a new peer by connecting to a
docker swarm API, and redirect a user to his peer instance.</p>
<p>Thanks to consul peers registration, it can fetch vacant peers
directly from consul and use the information to have a small buffer of
unused peers. It is needed as a peer takes a few seconds to start and
generate a certificate.</p>
<p>The main logic for the service is relatively simple:</p>
<ol type="1">
<li>Check if the user has an assigned peer (it is stored it his cookies)
<ul>
<li>If it is there, redirect to the peer.</li>
</ul></li>
<li>Pop an unused peer from consul</li>
<li>Store its credentials in the user’s session</li>
<li>Redirect the user to the peer.</li>
</ol>
<h2 id="bridge">Bridge</h2>
<p>This is not implemented part so far, but the idea is to create
another app that has two parts: discovery and proxy.</p>
<p>Two bridges in different networks, for example, a cloud network from
the scheme above and a local network, should connect and exchange
information about known peers.</p>
<p>When a message is sent from peer in the one network to the peer in
another, bridge acts as a gateway and proxies the connection between two
peers.</p>
<p>Final architecture:</p>
<figure>
<img src="./p2p.bridge.jpg.800x0@2x.webp" width="800" alt="bridge" />
<figcaption aria-hidden="true">bridge</figcaption>
</figure>
<p>You can find the code and maybe participate at <a
href="https://github.com/ngalayko/p2p">github</a>.</p>
<h2 id="links">Links:</h2>
<ul>
<li><a href="https://p2p.galaiko.rocks">Messenger</a></li>
<li><a href="https://github.com/ngalayko/p2p">GitHub</a></li>
<li><a href="https://traefik.io/">Traefik</a></li>
<li><a href="https://www.consul.io/">Consul</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Golang: Data races</title>
      <link>https://nikita.galaiko.rocks/posts/go-data-race.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/go-data-races/</guid>
      <pubDate>2019-02-02T00:00:00Z</pubDate>
      <description><![CDATA[<p>I have noticed that many people who have started using go have
troubles when it comes to concurrent programming. Concurrency in go is
indeed the most complicated part of the language, especially for people
who don’t have much experience working with it. There are no compile
time validations to prevent a programmer from creating race conditions,
but go provides all the needed tools and instruments to avoid it.</p>
<p>I will try to explain what is a race condition, why does it happen
and how to avoid it.</p>
<p>Wikipedia:</p>
<blockquote>
<p>A race condition or race hazard is the behavior of an electronics,
software, or another system where the system’s substantive behavior is
dependent on the sequence or timing of other uncontrollable events. It
becomes a bug when one or more of the possible behaviors is
undesirable.</p>
</blockquote>
<p>Let’s say we have a list of links to Wikipedia pages that we want to
download.</p>
<p>I wrote a <a
href="https://github.com/ngalayko/examples/tree/master/concurrency/examples/download">simple
tool</a> as an example that uses the interface to do that:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Downloader <span class="kw">interface</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    Download<span class="op">(...*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The most straightforward implementation would be to iterate over a
list of urls, download each of them and store in the resulting map:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Downloader <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    client <span class="op">*</span>http<span class="op">.</span>Client</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>d <span class="op">*</span>Downloader<span class="op">)</span> Download<span class="op">(</span>urls <span class="op">...*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>urls<span class="op">))</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> u <span class="op">:=</span> <span class="kw">range</span> urls <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        data<span class="op">,</span> err <span class="op">:=</span> d<span class="op">.</span>download<span class="op">(</span>u<span class="op">)</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">nil</span><span class="op">,</span> fmt<span class="op">.</span>Errorf<span class="op">(</span><span class="st">&quot;error downloading %s: %s&quot;</span><span class="op">,</span> u<span class="op">,</span> err<span class="op">)</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>        result<span class="op">[</span>u<span class="op">]</span> <span class="op">=</span> data</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result<span class="op">,</span> <span class="ot">nil</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>d <span class="op">*</span>Downloader<span class="op">)</span> download<span class="op">(</span>u <span class="op">*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">([]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    resp<span class="op">,</span> err <span class="op">:=</span> d<span class="op">.</span>client<span class="op">.</span>Get<span class="op">(</span>u<span class="op">.</span>String<span class="op">())</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">nil</span><span class="op">,</span> err</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">defer</span> resp<span class="op">.</span>Body<span class="op">.</span>Close<span class="op">()</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> ioutil<span class="op">.</span>ReadAll<span class="op">(</span>resp<span class="op">.</span>Body<span class="op">)</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The code works, but not so fast, because the total time to download
links is a sum of times to download for each link. It’s really
inefficient when the number of links is big. For me, it took over 16s to
download 100 links. To improve it, let’s change the code, so we download
all links at the same time:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>d <span class="op">*</span>Downloader<span class="op">)</span> Download<span class="op">(</span>urls <span class="op">...*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>urls<span class="op">))</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    wg <span class="op">:=</span> <span class="op">&amp;</span>sync<span class="op">.</span>WaitGroup<span class="op">{}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> u <span class="op">:=</span> <span class="kw">range</span> urls <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        wg<span class="op">.</span>Add<span class="op">(</span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">go</span> <span class="kw">func</span><span class="op">(</span>u <span class="op">*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>            data<span class="op">,</span> _ <span class="op">:=</span> d<span class="op">.</span>download<span class="op">(</span>u<span class="op">)</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>            result<span class="op">[</span>u<span class="op">]</span> <span class="op">=</span> data</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>            wg<span class="op">.</span>Done<span class="op">()</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}(</span>u<span class="op">)</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    wg<span class="op">.</span>Wait<span class="op">()</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result<span class="op">,</span> <span class="ot">nil</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>To do that, we have wrapped our <code>download</code> function to run
in its goroutine. Wait group here is used to wait until all of the urls
are downloaded, so the total time equals the time to download the
heavies page. On my test run, it is <code>679.53154ms</code> for 100
pages. Down from sixteen seconds to less than a second - an impressive
result!</p>
<p>But here is a problem:</p>
<pre><code>==================
WARNING: DATA RACE
Write at 0x00c0007baf60 by goroutine 257:
  runtime.mapassign_fast64()
      /usr/local/go/src/runtime/map_fast64.go:92 +0x0
  github.com/ngalayko/talks/concurrency/examples/download/downloader/race.(*Downloader).Download.func1()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/downloader/race/downloader.go:37 +0x8e

Previous write at 0x00c0007baf60 by goroutine 262:
  runtime.mapassign_fast64()
      /usr/local/go/src/runtime/map_fast64.go:92 +0x0
  github.com/ngalayko/talks/concurrency/examples/download/downloader/race.(*Downloader).Download.func1()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/downloader/race/downloader.go:37 +0x8e

Goroutine 257 (running) created at:
  github.com/ngalayko/talks/concurrency/examples/download/downloader/race.(*Downloader).Download()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/downloader/race/downloader.go:35 +0x123
  main.run()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/cmd/download/main.go:71 +0x8e
  main.main()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/cmd/download/main.go:56 +0x3b4

Goroutine 262 (finished) created at:
  github.com/ngalayko/talks/concurrency/examples/download/downloader/race.(*Downloader).Download()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/downloader/race/downloader.go:35 +0x123
  main.run()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/cmd/download/main.go:71 +0x8e
  main.main()
      /Users/nikitagalaiko/golang/src/github.com/ngalayko/talks/concurrency/examples/download/cmd/download/main.go:56 +0x3b4
==================</code></pre>
<p>I’ve built the code with <code>-race</code> flag to enable golang
race detector and got a warning about the data race. Of cource, a
warning is not an error, and we can ignore it, the result was correct:
we’ve downloaded a page for each link.</p>
<p>But why race detector does not agree?</p>
<p>First, let’s see what lines he doesn’t like:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>    result<span class="op">[</span>u<span class="op">]</span> <span class="op">=</span> data</span></code></pre></div>
<p>A map is a data structure that contains keys and values. All keys are
unique, and each key has an associated value with it. For the sake of
the example let’s say that every key is associated with a particular
address in the memory, and the address is permanent.</p>
<p>So when we are updating the key’s value, we are updating data at the
same address in the memory.</p>
<p>In our example, we have unique urls, we download each of them and
place the content to the individual memory address associated with a map
key.</p>
<p>But what should happen when we write different data into the same
key? If we follow the abstractions of a map that I’ve described above
and goroutines - light-weight threads that are running concurrently at
the same time - then the final value for the map is not determined.</p>
<p>Because what happens is that we are telling go to write some data at
the same memory address multiple times at the same time. This can cause
all kinds of problems - from the unexpected result for a programmer to
data corruption. And it’s not a responsibility of a language to decide
what does a programmer wants to see as a result. And a result in the
situation depends on uncontrollable events.</p>
<p>That’s why go gives us a warning. It can’t guarantee the result.</p>
<p>It doesn’t apply only to maps. The same can happen when you share a
pointer between two goroutines. Or you are writing to the same file from
two different programmes, or maybe you are saving data from two
instances of your applications to the same database. These all are
different kinds of the same problem.</p>
<blockquote>
<p>Data races happen only when you have multiple
threads/goroutines/processes that can access the same data at the same
time.</p>
</blockquote>
<p>Likely, that problem was around for a while, and there is a solution
to it.</p>
<blockquote>
<p>You need to make sure that only one process has access to the same
piece of memory at a time.</p>
</blockquote>
<p>Though, there is a difference between write and read access. Reading
the same data from multiple threads is safe. The problems start only
when you have a thread that writes.</p>
<p>Golang has a few instruments to deal with data races like mutexes and
channels.</p>
<p>Mutexes are used to solve exactly data race problems, here how to use
them:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>d <span class="op">*</span>Downloader<span class="op">)</span> Download<span class="op">(</span>urls <span class="op">...*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>urls<span class="op">))</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    wg <span class="op">:=</span> <span class="op">&amp;</span>sync<span class="op">.</span>WaitGroup<span class="op">{}</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    guard <span class="op">:=</span> <span class="op">&amp;</span>sync<span class="op">.</span>Mutex<span class="op">{}</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> u <span class="op">:=</span> <span class="kw">range</span> urls <span class="op">{</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>        wg<span class="op">.</span>Add<span class="op">(</span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">go</span> <span class="kw">func</span><span class="op">(</span>u <span class="op">*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>            data<span class="op">,</span> _ <span class="op">:=</span> d<span class="op">.</span>download<span class="op">(</span>u<span class="op">)</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>            guard<span class="op">.</span>Lock<span class="op">()</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>            result<span class="op">[</span>u<span class="op">]</span> <span class="op">=</span> data</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>            guard<span class="op">.</span>Unlock<span class="op">()</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>            wg<span class="op">.</span>Done<span class="op">()</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">}(</span>u<span class="op">)</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>    wg<span class="op">.</span>Wait<span class="op">()</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result<span class="op">,</span> <span class="ot">nil</span></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It has two methods, <code>Lock</code> and <code>Unlock</code>.
Everything between them can be accessed only by one goroutine at a time.
Others will wait for the mutex to unlock before they can access it.</p>
<p>Channels are a bit more tricky, and can be also used to controll
goroutines:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> done <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    u    <span class="op">*</span>url<span class="op">.</span>URL</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    data <span class="op">[]</span><span class="dt">byte</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    err  <span class="dt">error</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>d <span class="op">*</span>Downloader<span class="op">)</span> Download<span class="op">(</span>urls <span class="op">...*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">map</span><span class="op">[*</span>url<span class="op">.</span>URL<span class="op">][]</span><span class="dt">byte</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>urls<span class="op">))</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    doneChan <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">chan</span> <span class="op">*</span>done<span class="op">)</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>    wg <span class="op">:=</span> <span class="op">&amp;</span>sync<span class="op">.</span>WaitGroup<span class="op">{}</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> u <span class="op">:=</span> <span class="kw">range</span> urls <span class="op">{</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>        wg<span class="op">.</span>Add<span class="op">(</span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">go</span> <span class="kw">func</span><span class="op">(</span>u <span class="op">*</span>url<span class="op">.</span>URL<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>            data<span class="op">,</span> err <span class="op">:=</span> d<span class="op">.</span>download<span class="op">(</span>u<span class="op">)</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>            doneChan <span class="op">&lt;-</span> <span class="op">&amp;</span>done<span class="op">{</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>                u<span class="op">:</span>    u<span class="op">,</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>                data<span class="op">:</span> data<span class="op">,</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>                err<span class="op">:</span>  err<span class="op">,</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>            wg<span class="op">.</span>Done<span class="op">()</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">}(</span>u<span class="op">)</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">go</span> <span class="kw">func</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>        wg<span class="op">.</span>Wait<span class="op">()</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>        <span class="bu">close</span><span class="op">(</span>doneChan<span class="op">)</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}()</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> done <span class="op">:=</span> <span class="kw">range</span> doneChan <span class="op">{</span></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> done<span class="op">.</span>err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">nil</span><span class="op">,</span> fmt<span class="op">.</span>Errorf<span class="op">(</span><span class="st">&quot;error downloading %s: %s&quot;</span><span class="op">,</span> done<span class="op">.</span>u<span class="op">,</span> done<span class="op">.</span>err<span class="op">)</span></span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a>        result<span class="op">[</span>done<span class="op">.</span>u<span class="op">]</span> <span class="op">=</span> done<span class="op">.</span>data</span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result<span class="op">,</span> <span class="ot">nil</span></span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Data from the multiple goroutines sent to the single goroutine via a
channel and that goroutine stores the data in the map.</p>
<h2 id="links">Links:</h2>
<ul>
<li><a
href="https://github.com/ngalayko/examples/tree/master/concurrency/examples/download">example</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Optimizing a function</title>
      <link>https://nikita.galaiko.rocks/posts/optimizing-go.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/optimizing-functions/</guid>
      <pubDate>2018-11-30T00:00:00Z</pubDate>
      <description><![CDATA[<p>In the golang community slack, someone shared a link to a package
used to validate Swedish personnumer. Personnumer is a swedish version
of an ID, and its format is well defined:</p>
<ol type="1">
<li>First 6 or 8 digits is a birthrate with or without a century.</li>
<li>Last four digits are random secret digits.</li>
<li>The whole number satisfies the <a
href="https://en.wikipedia.org/wiki/Luhn_algorithm">Luhn
algorithm</a>.</li>
<li>Birthdate and secret digits can be divided with <code>-</code> or
<code>+</code>.</li>
</ol>
<p>For example <code>19900101-0017</code></p>
<p>Here is the initial code of the package:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">package</span> personnummer</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="op">(</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;math&quot;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;reflect&quot;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;regexp&quot;</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;strconv&quot;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;time&quot;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="co">// luhn will test if the given string is a valid luhn string.</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> luhn<span class="op">(</span>str <span class="dt">string</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    sum <span class="op">:=</span> <span class="dv">0</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i<span class="op">,</span> r <span class="op">:=</span> <span class="kw">range</span> str <span class="op">{</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        c <span class="op">:=</span> <span class="dt">string</span><span class="op">(</span>r<span class="op">)</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>        v<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>c<span class="op">)</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        v <span class="op">*=</span> <span class="dv">2</span> <span class="op">-</span> <span class="op">(</span>i <span class="op">%</span> <span class="dv">2</span><span class="op">)</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> v <span class="op">&gt;</span> <span class="dv">9</span> <span class="op">{</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>            v <span class="op">-=</span> <span class="dv">9</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>        sum <span class="op">+=</span> v</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dt">int</span><span class="op">(</span>math<span class="op">.</span>Ceil<span class="op">(</span><span class="dt">float64</span><span class="op">(</span>sum<span class="op">)/</span><span class="dv">10</span><span class="op">)*</span><span class="dv">10</span> <span class="op">-</span> <span class="dt">float64</span><span class="op">(</span>sum<span class="op">))</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="co">// testDate will test if date is valid or not.</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> testDate<span class="op">(</span>century <span class="dt">string</span><span class="op">,</span> year <span class="dt">string</span><span class="op">,</span> month <span class="dt">string</span><span class="op">,</span> day <span class="dt">string</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>    t<span class="op">,</span> err <span class="op">:=</span> time<span class="op">.</span>Parse<span class="op">(</span><span class="st">&quot;01/02/2006&quot;</span><span class="op">,</span> month<span class="op">+</span><span class="st">&quot;/&quot;</span><span class="op">+</span>day<span class="op">+</span><span class="st">&quot;/&quot;</span><span class="op">+</span>century<span class="op">+</span>year<span class="op">)</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>    y<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>century <span class="op">+</span> year<span class="op">)</span></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>    m<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>month<span class="op">)</span></span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>    d<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>day<span class="op">)</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> y <span class="op">&gt;</span> time<span class="op">.</span>Now<span class="op">().</span>Year<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">!(</span>t<span class="op">.</span>Year<span class="op">()</span> <span class="op">!=</span> y <span class="op">||</span> <span class="dt">int</span><span class="op">(</span>t<span class="op">.</span>Month<span class="op">())</span> <span class="op">!=</span> m <span class="op">||</span> t<span class="op">.</span>Day<span class="op">()</span> <span class="op">!=</span> d<span class="op">)</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a><span class="co">// getCoOrdinationDay will return co-ordination day.</span></span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> getCoOrdinationDay<span class="op">(</span>day <span class="dt">string</span><span class="op">)</span> <span class="dt">string</span> <span class="op">{</span></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a>    d<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>day<span class="op">)</span></span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a>    d <span class="op">-=</span> <span class="dv">60</span></span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a>    day <span class="op">=</span> strconv<span class="op">.</span>Itoa<span class="op">(</span>d<span class="op">)</span></span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> d <span class="op">&lt;</span> <span class="dv">10</span> <span class="op">{</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a>        day <span class="op">=</span> <span class="st">&quot;0&quot;</span> <span class="op">+</span> day</span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> day</span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a><span class="co">// Valid will validate Swedish social security numbers.</span></span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Valid<span class="op">(</span>str <span class="kw">interface</span><span class="op">{})</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> reflect<span class="op">.</span>TypeOf<span class="op">(</span>str<span class="op">).</span>Kind<span class="op">()</span> <span class="op">!=</span> reflect<span class="op">.</span>Int <span class="op">&amp;&amp;</span> reflect<span class="op">.</span>TypeOf<span class="op">(</span>str<span class="op">).</span>Kind<span class="op">()</span> <span class="op">!=</span> reflect<span class="op">.</span>String <span class="op">{</span></span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a>    pr <span class="op">:=</span> <span class="st">&quot;&quot;</span></span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> reflect<span class="op">.</span>TypeOf<span class="op">(</span>str<span class="op">).</span>Kind<span class="op">()</span> <span class="op">==</span> reflect<span class="op">.</span>Int <span class="op">{</span></span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a>        pr <span class="op">=</span> strconv<span class="op">.</span>Itoa<span class="op">(</span>str<span class="op">.(</span><span class="dt">int</span><span class="op">))</span></span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a>        pr <span class="op">=</span> str<span class="op">.(</span><span class="dt">string</span><span class="op">)</span></span>
<span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a>    re<span class="op">,</span> _ <span class="op">:=</span> regexp<span class="op">.</span>Compile<span class="op">(</span><span class="st">`^(\d{2}){0,1}(\d{2})(\d{2})(\d{2})([\-|\+]{0,1})?(\d{3})(\d{0,1})$`</span><span class="op">)</span></span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a>    match <span class="op">:=</span> re<span class="op">.</span>FindStringSubmatch<span class="op">(</span>pr<span class="op">)</span></span>
<span id="cb1-76"><a href="#cb1-76" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>match<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb1-78"><a href="#cb1-78" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-79"><a href="#cb1-79" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-80"><a href="#cb1-80" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-81"><a href="#cb1-81" aria-hidden="true" tabindex="-1"></a>    century <span class="op">:=</span> match<span class="op">[</span><span class="dv">1</span><span class="op">]</span></span>
<span id="cb1-82"><a href="#cb1-82" aria-hidden="true" tabindex="-1"></a>    year <span class="op">:=</span> match<span class="op">[</span><span class="dv">2</span><span class="op">]</span></span>
<span id="cb1-83"><a href="#cb1-83" aria-hidden="true" tabindex="-1"></a>    month <span class="op">:=</span> match<span class="op">[</span><span class="dv">3</span><span class="op">]</span></span>
<span id="cb1-84"><a href="#cb1-84" aria-hidden="true" tabindex="-1"></a>    day <span class="op">:=</span> match<span class="op">[</span><span class="dv">4</span><span class="op">]</span></span>
<span id="cb1-85"><a href="#cb1-85" aria-hidden="true" tabindex="-1"></a>    num <span class="op">:=</span> match<span class="op">[</span><span class="dv">6</span><span class="op">]</span></span>
<span id="cb1-86"><a href="#cb1-86" aria-hidden="true" tabindex="-1"></a>    check <span class="op">:=</span> match<span class="op">[</span><span class="dv">7</span><span class="op">]</span></span>
<span id="cb1-87"><a href="#cb1-87" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-88"><a href="#cb1-88" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>century<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb1-89"><a href="#cb1-89" aria-hidden="true" tabindex="-1"></a>        yearNow <span class="op">:=</span> time<span class="op">.</span>Now<span class="op">().</span>Year<span class="op">()</span></span>
<span id="cb1-90"><a href="#cb1-90" aria-hidden="true" tabindex="-1"></a>        years <span class="op">:=</span> <span class="op">[...]</span><span class="dt">int</span><span class="op">{</span>yearNow<span class="op">,</span> yearNow <span class="op">-</span> <span class="dv">100</span><span class="op">,</span> yearNow <span class="op">-</span> <span class="dv">150</span><span class="op">}</span></span>
<span id="cb1-91"><a href="#cb1-91" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-92"><a href="#cb1-92" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> _<span class="op">,</span> yi <span class="op">:=</span> <span class="kw">range</span> years <span class="op">{</span></span>
<span id="cb1-93"><a href="#cb1-93" aria-hidden="true" tabindex="-1"></a>            ys <span class="op">:=</span> strconv<span class="op">.</span>Itoa<span class="op">(</span>yi<span class="op">)</span></span>
<span id="cb1-94"><a href="#cb1-94" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-95"><a href="#cb1-95" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> Valid<span class="op">(</span>ys<span class="op">[:</span><span class="dv">2</span><span class="op">]</span> <span class="op">+</span> pr<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-96"><a href="#cb1-96" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="ot">true</span></span>
<span id="cb1-97"><a href="#cb1-97" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-98"><a href="#cb1-98" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-99"><a href="#cb1-99" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-100"><a href="#cb1-100" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-101"><a href="#cb1-101" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-102"><a href="#cb1-102" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-103"><a href="#cb1-103" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>year<span class="op">)</span> <span class="op">==</span> <span class="dv">4</span> <span class="op">{</span></span>
<span id="cb1-104"><a href="#cb1-104" aria-hidden="true" tabindex="-1"></a>        year <span class="op">=</span> year<span class="op">[</span><span class="dv">2</span><span class="op">:]</span></span>
<span id="cb1-105"><a href="#cb1-105" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-106"><a href="#cb1-106" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-107"><a href="#cb1-107" aria-hidden="true" tabindex="-1"></a>    c<span class="op">,</span> _ <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>check<span class="op">)</span></span>
<span id="cb1-108"><a href="#cb1-108" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-109"><a href="#cb1-109" aria-hidden="true" tabindex="-1"></a>    valid <span class="op">:=</span> luhn<span class="op">(</span>year<span class="op">+</span>month<span class="op">+</span>day<span class="op">+</span>num<span class="op">)</span> <span class="op">==</span> c <span class="op">&amp;&amp;</span> <span class="bu">len</span><span class="op">(</span>check<span class="op">)</span> <span class="op">!=</span> <span class="dv">0</span></span>
<span id="cb1-110"><a href="#cb1-110" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-111"><a href="#cb1-111" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> valid <span class="op">&amp;&amp;</span> testDate<span class="op">(</span>century<span class="op">,</span> year<span class="op">,</span> month<span class="op">,</span> day<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-112"><a href="#cb1-112" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> valid</span>
<span id="cb1-113"><a href="#cb1-113" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-114"><a href="#cb1-114" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-115"><a href="#cb1-115" aria-hidden="true" tabindex="-1"></a>    day <span class="op">=</span> getCoOrdinationDay<span class="op">(</span>day<span class="op">)</span></span>
<span id="cb1-116"><a href="#cb1-116" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-117"><a href="#cb1-117" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> valid <span class="op">&amp;&amp;</span> testDate<span class="op">(</span>century<span class="op">,</span> year<span class="op">,</span> month<span class="op">,</span> day<span class="op">)</span></span>
<span id="cb1-118"><a href="#cb1-118" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Let’s add a benchmark:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> BenchmarkValid<span class="op">(</span>b <span class="op">*</span>testing<span class="op">.</span>B<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> b<span class="op">.</span>N<span class="op">;</span> i<span class="op">++</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>        Valid<span class="op">(</span><span class="st">&quot;19900101-0017&quot;</span><span class="op">)</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Results:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>  100000  18498 ns/op  54576 B/op  118 allocs/op</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<p>That’s a lot of resources to validate a string using four simple
rules.</p>
<p>There are several problems in the code. I am going to remove it one
by one:</p>
<h2 id="regexp-package">Regexp package</h2>
<p>The most popular way to optimize functions in go is to move the
regexp compilation out from a function:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> <span class="op">(</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    re <span class="op">=</span> regexp<span class="op">.</span>MustCompile<span class="op">(</span><span class="st">`^(\d{2}){0,1}(\d{2})(\d{2})(\d{2})([\-|\+]{0,1})?(\d{3})(\d{0,1})$`</span><span class="op">)</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="co">// Valid will validate Swedish social security numbers.</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Valid<span class="op">(</span>str <span class="kw">interface</span><span class="op">{})</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    match <span class="op">:=</span> re<span class="op">.</span>FindStringSubmatch<span class="op">(</span>pr<span class="op">)</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Results are not surprising:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>  1000000  1301 ns/op  309 B/op  13 allocs/op</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<h2 id="reflect-package">Reflect package</h2>
<p>Reflection is generally slow and is not made to be used in such
cases. Here it is used to check if the input type in <code>int</code> or
<code>string</code>. Let’s assume we actually need a function that
accepts an interface, and not just a string.</p>
<p>To check the type of an interface you don’t need a reflect package.
You can always switch on an interface type:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Valid will validate Swedish social security numbers.</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Valid<span class="op">(</span>i <span class="kw">interface</span><span class="op">{})</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">switch</span> v <span class="op">:=</span> i<span class="op">.(</span><span class="kw">type</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dt">int</span><span class="op">,</span> <span class="dt">int32</span><span class="op">,</span> <span class="dt">int64</span><span class="op">,</span> <span class="dt">uint</span><span class="op">,</span> <span class="dt">uint32</span><span class="op">,</span> <span class="dt">uint64</span><span class="op">:</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> ValidString<span class="op">(</span>fmt<span class="op">.</span>Sprint<span class="op">(</span>v<span class="op">))</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dt">string</span><span class="op">:</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> ValidString<span class="op">(</span>v<span class="op">)</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">default</span><span class="op">:</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="co">// ValidString will validate Swedish social security numbers.</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> ValidString<span class="op">(</span>s <span class="dt">string</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Results are pretty much the same. I think it’s because of some
compiler optimizations where <code>switch v.(type)</code> is syntax
sugar for <code>reflect.TypeOf(v)</code>, plus undercover all objects
know what types they are even when you use them as an
<code>interface{}</code>.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>  1000000  1305 ns/op  309 B/op  13 allocs/op</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<h2 id="regexp-package-again">Regexp package again</h2>
<p>Why do we even need a regexp package here? To validate that string
contains only digits and <code>-</code> or <code>-</code> regexp is an
overkill.</p>
<p>First, we clean out everything except digits from a string and check
it’s length because we know what that length should be (6+4 or 8+4).</p>
<p>To check if a character is a digit, it’s enough to make sure that
it’s greater than <code>'0'</code> and less than <code>'9'</code>,
because all digits have sequential codes in the (ASCII
table)[http://www.asciitable.com/].</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> ValidString<span class="op">(</span>s <span class="dt">string</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    cleanNumber <span class="op">:=</span> <span class="st">&quot;&quot;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> c <span class="op">:=</span> <span class="kw">range</span> s <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">==</span> <span class="ch">&#39;+&#39;</span> <span class="op">{</span> <span class="co">// `+` is allowed, but we don&#39;t need it.</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">==</span> <span class="ch">&#39;-&#39;</span> <span class="op">{</span> <span class="co">// `-` is allowed, but we don&#39;t need it.</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">&gt;</span> <span class="ch">&#39;9&#39;</span> <span class="op">{</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">&lt;</span> <span class="ch">&#39;0&#39;</span> <span class="op">{</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>        cleanNumber <span class="op">+=</span> <span class="dt">string</span><span class="op">(</span>c<span class="op">)</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And once we have a string that has only digits, it’s easy to get all
parts of it:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> <span class="op">(</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>        century <span class="dt">string</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>        year    <span class="dt">string</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>        month   <span class="dt">string</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>        day     <span class="dt">string</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>        num     <span class="dt">string</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>        check   <span class="dt">string</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">switch</span> <span class="bu">len</span><span class="op">(</span>cleanNumber<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dv">10</span><span class="op">:</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>        year <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[:</span><span class="dv">2</span><span class="op">])</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>        month <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">2</span><span class="op">:</span><span class="dv">4</span><span class="op">])</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>        day <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">4</span><span class="op">:</span><span class="dv">6</span><span class="op">])</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>        num <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">6</span><span class="op">:</span><span class="dv">9</span><span class="op">])</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>        check <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">9</span><span class="op">:])</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dv">12</span><span class="op">:</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>        century <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[:</span><span class="dv">2</span><span class="op">])</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>        year <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">2</span><span class="op">:</span><span class="dv">4</span><span class="op">])</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>        month <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">4</span><span class="op">:</span><span class="dv">6</span><span class="op">])</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a>        day <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">6</span><span class="op">:</span><span class="dv">8</span><span class="op">])</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>        num <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">8</span><span class="op">:</span><span class="dv">11</span><span class="op">])</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>        check <span class="op">=</span> <span class="dt">string</span><span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">11</span><span class="op">:])</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">default</span><span class="op">:</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>    <span class="co">//...</span></span></code></pre></div>
<p>Results are a bit better:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>  1000000  1302 ns/op  208 B/op  34 allocs/op</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<h2 id="time-package">Time package</h2>
<p>Standard time package is great, but what we need here is just simple
validation of a date:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode go"><code class="sourceCode go"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> monthDays <span class="op">=</span> <span class="kw">map</span><span class="op">[</span><span class="dt">int</span><span class="op">]</span><span class="dt">int</span><span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="dv">4</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    <span class="dv">5</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="dv">6</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="dv">7</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    <span class="dv">8</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    <span class="dv">9</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    <span class="dv">10</span><span class="op">:</span> <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>    <span class="dv">11</span><span class="op">:</span> <span class="dv">30</span><span class="op">,</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>    <span class="dv">12</span><span class="op">:</span> <span class="dv">31</span><span class="op">,</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a><span class="co">// testDate will test if date is valid or not.</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> testDate<span class="op">(</span>century <span class="dt">string</span><span class="op">,</span> year <span class="dt">string</span><span class="op">,</span> month <span class="dt">string</span><span class="op">,</span> day <span class="dt">string</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>    y<span class="op">,</span> err <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>century <span class="op">+</span> year<span class="op">)</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>    m<span class="op">,</span> err <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>month<span class="op">)</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>    d<span class="op">,</span> err <span class="op">:=</span> strconv<span class="op">.</span>Atoi<span class="op">(</span>day<span class="op">)</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> m <span class="op">!=</span> <span class="dv">2</span> <span class="op">{</span></span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true" tabindex="-1"></a>        days<span class="op">,</span> ok <span class="op">:=</span> monthDays<span class="op">[</span>m<span class="op">]</span></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">!</span>ok <span class="op">{</span></span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> d <span class="op">&lt;=</span> days</span>
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-37"><a href="#cb11-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-38"><a href="#cb11-38" aria-hidden="true" tabindex="-1"></a>    leapYear <span class="op">:=</span> y<span class="op">%</span><span class="dv">4</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> y<span class="op">%</span><span class="dv">100</span> <span class="op">!=</span> <span class="dv">0</span> <span class="op">||</span> y<span class="op">%</span><span class="dv">400</span> <span class="op">==</span> <span class="dv">0</span></span>
<span id="cb11-39"><a href="#cb11-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-40"><a href="#cb11-40" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> leapYear <span class="op">{</span></span>
<span id="cb11-41"><a href="#cb11-41" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> d <span class="op">&lt;=</span> <span class="dv">29</span></span>
<span id="cb11-42"><a href="#cb11-42" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-43"><a href="#cb11-43" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> d <span class="op">&lt;=</span> <span class="dv">28</span></span>
<span id="cb11-44"><a href="#cb11-44" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Benchmark:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>   2000000  901 ns/op  192 B/op  33 allocs/op</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<h2 id="strings">Strings</h2>
<p>Notice that there are still 33 allocations per function call. Where
do they come from? It’s because we use <code>string</code> type all the
time, <code>string</code> is the same thing as a <code>[]byte</code>,
but immutable. So every time we call
<code>cleanNumber += string(c)</code>, allocation happens. It’s
impossible to change the string, so new the string is allocated, and
both strings are copies there.</p>
<p>Let’s remove <code>string</code> usage:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode go"><code class="sourceCode go"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">package</span> personnummer</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="st">&quot;fmt&quot;</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> <span class="op">(</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    lengthWithoutCentury <span class="op">=</span> <span class="dv">10</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    lengthWithCentury    <span class="op">=</span> <span class="dv">12</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="co">// ValidateStrings validate Swedish social security numbers.</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> ValidString<span class="op">(</span>in <span class="dt">string</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>    cleanNumber <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">byte</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>in<span class="op">))</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> c <span class="op">:=</span> <span class="kw">range</span> in <span class="op">{</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">==</span> <span class="ch">&#39;+&#39;</span> <span class="op">{</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">==</span> <span class="ch">&#39;-&#39;</span> <span class="op">{</span></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">&gt;</span> <span class="ch">&#39;9&#39;</span> <span class="op">{</span></span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> c <span class="op">&lt;</span> <span class="ch">&#39;0&#39;</span> <span class="op">{</span></span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a>        cleanNumber <span class="op">=</span> <span class="bu">append</span><span class="op">(</span>cleanNumber<span class="op">,</span> <span class="dt">byte</span><span class="op">(</span>c<span class="op">))</span></span>
<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a>    <span class="cf">switch</span> <span class="bu">len</span><span class="op">(</span>cleanNumber<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> lengthWithCentury<span class="op">:</span></span>
<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">!</span>luhn<span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">2</span><span class="op">:])</span> <span class="op">{</span></span>
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a>        dateBytes <span class="op">:=</span> <span class="bu">append</span><span class="op">(</span>cleanNumber<span class="op">[:</span><span class="dv">6</span><span class="op">],</span> getCoOrdinationDay<span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">6</span><span class="op">:</span><span class="dv">8</span><span class="op">])...)</span></span>
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> validateTime<span class="op">(</span>dateBytes<span class="op">)</span></span>
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> lengthWithoutCentury<span class="op">:</span></span>
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">!</span>luhn<span class="op">(</span>cleanNumber<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a>        dateBytes <span class="op">:=</span> <span class="bu">append</span><span class="op">(</span>cleanNumber<span class="op">[:</span><span class="dv">4</span><span class="op">],</span> getCoOrdinationDay<span class="op">(</span>cleanNumber<span class="op">[</span><span class="dv">4</span><span class="op">:</span><span class="dv">6</span><span class="op">])...)</span></span>
<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> validateTime<span class="op">(</span>dateBytes<span class="op">)</span></span>
<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a>    <span class="cf">default</span><span class="op">:</span></span>
<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-49"><a href="#cb13-49" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-50"><a href="#cb13-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-51"><a href="#cb13-51" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> monthDays <span class="op">=</span> <span class="kw">map</span><span class="op">[</span><span class="dt">int</span><span class="op">]</span><span class="dt">int</span><span class="op">{</span></span>
<span id="cb13-52"><a href="#cb13-52" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-53"><a href="#cb13-53" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-54"><a href="#cb13-54" aria-hidden="true" tabindex="-1"></a>    <span class="dv">4</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb13-55"><a href="#cb13-55" aria-hidden="true" tabindex="-1"></a>    <span class="dv">5</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-56"><a href="#cb13-56" aria-hidden="true" tabindex="-1"></a>    <span class="dv">6</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb13-57"><a href="#cb13-57" aria-hidden="true" tabindex="-1"></a>    <span class="dv">7</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-58"><a href="#cb13-58" aria-hidden="true" tabindex="-1"></a>    <span class="dv">8</span><span class="op">:</span>  <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-59"><a href="#cb13-59" aria-hidden="true" tabindex="-1"></a>    <span class="dv">9</span><span class="op">:</span>  <span class="dv">30</span><span class="op">,</span></span>
<span id="cb13-60"><a href="#cb13-60" aria-hidden="true" tabindex="-1"></a>    <span class="dv">10</span><span class="op">:</span> <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-61"><a href="#cb13-61" aria-hidden="true" tabindex="-1"></a>    <span class="dv">11</span><span class="op">:</span> <span class="dv">30</span><span class="op">,</span></span>
<span id="cb13-62"><a href="#cb13-62" aria-hidden="true" tabindex="-1"></a>    <span class="dv">12</span><span class="op">:</span> <span class="dv">31</span><span class="op">,</span></span>
<span id="cb13-63"><a href="#cb13-63" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-64"><a href="#cb13-64" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-65"><a href="#cb13-65" aria-hidden="true" tabindex="-1"></a><span class="co">// input time without centry.</span></span>
<span id="cb13-66"><a href="#cb13-66" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> validateTime<span class="op">(</span>time <span class="op">[]</span><span class="dt">byte</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb13-67"><a href="#cb13-67" aria-hidden="true" tabindex="-1"></a>    length <span class="op">:=</span> <span class="bu">len</span><span class="op">(</span>time<span class="op">)</span></span>
<span id="cb13-68"><a href="#cb13-68" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-69"><a href="#cb13-69" aria-hidden="true" tabindex="-1"></a>    date <span class="op">:=</span> charsToDigit<span class="op">(</span>time<span class="op">[</span>length<span class="op">-</span><span class="dv">2</span> <span class="op">:</span> length<span class="op">])</span></span>
<span id="cb13-70"><a href="#cb13-70" aria-hidden="true" tabindex="-1"></a>    month <span class="op">:=</span> charsToDigit<span class="op">(</span>time<span class="op">[</span>length<span class="op">-</span><span class="dv">4</span> <span class="op">:</span> length<span class="op">-</span><span class="dv">2</span><span class="op">])</span></span>
<span id="cb13-71"><a href="#cb13-71" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-72"><a href="#cb13-72" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> month <span class="op">!=</span> <span class="dv">2</span> <span class="op">{</span></span>
<span id="cb13-73"><a href="#cb13-73" aria-hidden="true" tabindex="-1"></a>        days<span class="op">,</span> ok <span class="op">:=</span> monthDays<span class="op">[</span>month<span class="op">]</span></span>
<span id="cb13-74"><a href="#cb13-74" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">!</span>ok <span class="op">{</span></span>
<span id="cb13-75"><a href="#cb13-75" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-76"><a href="#cb13-76" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-77"><a href="#cb13-77" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> date <span class="op">&lt;=</span> days</span>
<span id="cb13-78"><a href="#cb13-78" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-79"><a href="#cb13-79" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-80"><a href="#cb13-80" aria-hidden="true" tabindex="-1"></a>    year <span class="op">:=</span> charsToDigit<span class="op">(</span>time<span class="op">[:</span>length<span class="op">-</span><span class="dv">4</span><span class="op">])</span></span>
<span id="cb13-81"><a href="#cb13-81" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-82"><a href="#cb13-82" aria-hidden="true" tabindex="-1"></a>    leapYear <span class="op">:=</span> year<span class="op">%</span><span class="dv">4</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> year<span class="op">%</span><span class="dv">100</span> <span class="op">!=</span> <span class="dv">0</span> <span class="op">||</span> year<span class="op">%</span><span class="dv">400</span> <span class="op">==</span> <span class="dv">0</span></span>
<span id="cb13-83"><a href="#cb13-83" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-84"><a href="#cb13-84" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> leapYear <span class="op">{</span></span>
<span id="cb13-85"><a href="#cb13-85" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> date <span class="op">&lt;=</span> <span class="dv">29</span></span>
<span id="cb13-86"><a href="#cb13-86" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-87"><a href="#cb13-87" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> date <span class="op">&lt;=</span> <span class="dv">28</span></span>
<span id="cb13-88"><a href="#cb13-88" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-89"><a href="#cb13-89" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-90"><a href="#cb13-90" aria-hidden="true" tabindex="-1"></a><span class="co">// Valid will validate Swedish social security numbers.</span></span>
<span id="cb13-91"><a href="#cb13-91" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Valid<span class="op">(</span>i <span class="kw">interface</span><span class="op">{})</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb13-92"><a href="#cb13-92" aria-hidden="true" tabindex="-1"></a>    <span class="cf">switch</span> v <span class="op">:=</span> i<span class="op">.(</span><span class="kw">type</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-93"><a href="#cb13-93" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dt">int</span><span class="op">,</span> <span class="dt">int32</span><span class="op">,</span> <span class="dt">int64</span><span class="op">,</span> <span class="dt">uint</span><span class="op">,</span> <span class="dt">uint32</span><span class="op">,</span> <span class="dt">uint64</span><span class="op">:</span></span>
<span id="cb13-94"><a href="#cb13-94" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> ValidString<span class="op">(</span>fmt<span class="op">.</span>Sprint<span class="op">(</span>v<span class="op">))</span></span>
<span id="cb13-95"><a href="#cb13-95" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="dt">string</span><span class="op">:</span></span>
<span id="cb13-96"><a href="#cb13-96" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> ValidString<span class="op">(</span>v<span class="op">)</span></span>
<span id="cb13-97"><a href="#cb13-97" aria-hidden="true" tabindex="-1"></a>    <span class="cf">default</span><span class="op">:</span></span>
<span id="cb13-98"><a href="#cb13-98" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb13-99"><a href="#cb13-99" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-100"><a href="#cb13-100" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-101"><a href="#cb13-101" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-102"><a href="#cb13-102" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> rule3 <span class="op">=</span> <span class="op">[...]</span><span class="dt">int</span><span class="op">{</span><span class="dv">0</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">9</span><span class="op">}</span></span>
<span id="cb13-103"><a href="#cb13-103" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-104"><a href="#cb13-104" aria-hidden="true" tabindex="-1"></a><span class="co">// luhn will test if the given string is a valid luhn string.</span></span>
<span id="cb13-105"><a href="#cb13-105" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> luhn<span class="op">(</span>s <span class="op">[]</span><span class="dt">byte</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb13-106"><a href="#cb13-106" aria-hidden="true" tabindex="-1"></a>    odd <span class="op">:=</span> <span class="bu">len</span><span class="op">(</span>s<span class="op">)</span> <span class="op">&amp;</span> <span class="dv">1</span></span>
<span id="cb13-107"><a href="#cb13-107" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-108"><a href="#cb13-108" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> sum <span class="dt">int</span></span>
<span id="cb13-109"><a href="#cb13-109" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-110"><a href="#cb13-110" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i<span class="op">,</span> c <span class="op">:=</span> <span class="kw">range</span> s <span class="op">{</span></span>
<span id="cb13-111"><a href="#cb13-111" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i<span class="op">&amp;</span><span class="dv">1</span> <span class="op">==</span> odd <span class="op">{</span></span>
<span id="cb13-112"><a href="#cb13-112" aria-hidden="true" tabindex="-1"></a>            sum <span class="op">+=</span> rule3<span class="op">[</span>c<span class="op">-</span><span class="ch">&#39;0&#39;</span><span class="op">]</span></span>
<span id="cb13-113"><a href="#cb13-113" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb13-114"><a href="#cb13-114" aria-hidden="true" tabindex="-1"></a>            sum <span class="op">+=</span> <span class="dt">int</span><span class="op">(</span>c <span class="op">-</span> <span class="ch">&#39;0&#39;</span><span class="op">)</span></span>
<span id="cb13-115"><a href="#cb13-115" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-116"><a href="#cb13-116" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-117"><a href="#cb13-117" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-118"><a href="#cb13-118" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> sum<span class="op">%</span><span class="dv">10</span> <span class="op">==</span> <span class="dv">0</span></span>
<span id="cb13-119"><a href="#cb13-119" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-120"><a href="#cb13-120" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-121"><a href="#cb13-121" aria-hidden="true" tabindex="-1"></a><span class="co">// getCoOrdinationDay will return co-ordination day.</span></span>
<span id="cb13-122"><a href="#cb13-122" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> getCoOrdinationDay<span class="op">(</span>day <span class="op">[]</span><span class="dt">byte</span><span class="op">)</span> <span class="op">[]</span><span class="dt">byte</span> <span class="op">{</span></span>
<span id="cb13-123"><a href="#cb13-123" aria-hidden="true" tabindex="-1"></a>    d <span class="op">:=</span> charsToDigit<span class="op">(</span>day<span class="op">)</span></span>
<span id="cb13-124"><a href="#cb13-124" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> d <span class="op">&lt;</span> <span class="dv">60</span> <span class="op">{</span></span>
<span id="cb13-125"><a href="#cb13-125" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> day</span>
<span id="cb13-126"><a href="#cb13-126" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-127"><a href="#cb13-127" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-128"><a href="#cb13-128" aria-hidden="true" tabindex="-1"></a>    d <span class="op">-=</span> <span class="dv">60</span></span>
<span id="cb13-129"><a href="#cb13-129" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-130"><a href="#cb13-130" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> d <span class="op">&lt;</span> <span class="dv">10</span> <span class="op">{</span></span>
<span id="cb13-131"><a href="#cb13-131" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">[]</span><span class="dt">byte</span><span class="op">{</span><span class="ch">&#39;0&#39;</span><span class="op">,</span> <span class="dt">byte</span><span class="op">(</span>d<span class="op">)</span> <span class="op">+</span> <span class="ch">&#39;0&#39;</span><span class="op">}</span></span>
<span id="cb13-132"><a href="#cb13-132" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-133"><a href="#cb13-133" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-134"><a href="#cb13-134" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">[]</span><span class="dt">byte</span><span class="op">{</span></span>
<span id="cb13-135"><a href="#cb13-135" aria-hidden="true" tabindex="-1"></a>        <span class="dt">byte</span><span class="op">(</span>d<span class="op">)/</span><span class="dv">10</span> <span class="op">+</span> <span class="ch">&#39;0&#39;</span><span class="op">,</span></span>
<span id="cb13-136"><a href="#cb13-136" aria-hidden="true" tabindex="-1"></a>        <span class="dt">byte</span><span class="op">(</span>d<span class="op">)%</span><span class="dv">10</span> <span class="op">+</span> <span class="ch">&#39;0&#39;</span><span class="op">,</span></span>
<span id="cb13-137"><a href="#cb13-137" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-138"><a href="#cb13-138" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-139"><a href="#cb13-139" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-140"><a href="#cb13-140" aria-hidden="true" tabindex="-1"></a><span class="co">// charsToDigit converts char bytes to a digit</span></span>
<span id="cb13-141"><a href="#cb13-141" aria-hidden="true" tabindex="-1"></a><span class="co">// example: [&#39;1&#39;, &#39;1&#39;] =&gt; 11</span></span>
<span id="cb13-142"><a href="#cb13-142" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> charsToDigit<span class="op">(</span>chars <span class="op">[]</span><span class="dt">byte</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb13-143"><a href="#cb13-143" aria-hidden="true" tabindex="-1"></a>    l <span class="op">:=</span> <span class="bu">len</span><span class="op">(</span>chars<span class="op">)</span></span>
<span id="cb13-144"><a href="#cb13-144" aria-hidden="true" tabindex="-1"></a>    r <span class="op">:=</span> <span class="dv">0</span></span>
<span id="cb13-145"><a href="#cb13-145" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i<span class="op">,</span> c <span class="op">:=</span> <span class="kw">range</span> chars <span class="op">{</span></span>
<span id="cb13-146"><a href="#cb13-146" aria-hidden="true" tabindex="-1"></a>        p <span class="op">:=</span> <span class="dt">int</span><span class="op">((</span>c <span class="op">-</span> <span class="ch">&#39;0&#39;</span><span class="op">))</span></span>
<span id="cb13-147"><a href="#cb13-147" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> j <span class="op">:=</span> <span class="dv">0</span><span class="op">;</span> j <span class="op">&lt;</span> l<span class="op">-</span>i<span class="op">-</span><span class="dv">1</span><span class="op">;</span> j<span class="op">++</span> <span class="op">{</span></span>
<span id="cb13-148"><a href="#cb13-148" aria-hidden="true" tabindex="-1"></a>            p <span class="op">*=</span> <span class="dv">10</span></span>
<span id="cb13-149"><a href="#cb13-149" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-150"><a href="#cb13-150" aria-hidden="true" tabindex="-1"></a>        r <span class="op">+=</span> p</span>
<span id="cb13-151"><a href="#cb13-151" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-152"><a href="#cb13-152" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> r</span>
<span id="cb13-153"><a href="#cb13-153" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Final result:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> go test <span class="at">-bench</span><span class="op">=</span>BenchmarkValid$ <span class="at">-benchmem</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="ex">goos:</span> darwin</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="ex">goarch:</span> amd64</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="ex">pkg:</span> github.com/ngalayko/go</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="ex">BenchmarkValid-4</span>  20000000  94.0 ns/op  16 B/op  1 allocs/op</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="ex">PASS</span></span></code></pre></div>
<p><img src="./optimizing-go.n.png.800x0@2x.webp" width="800"
alt="Optimizaion n" /> <img
src="./optimizing-go.bytes.png.800x0@2x.webp" width="800"
alt="Optimizaion bytes" /> <img
src="./optimizing-go.allocs.png.800x0@2x.webp" width="800"
alt="Optimizaion allocs" /> <img
src="./optimizing-go.ns.png.800x0@2x.webp" width="800"
alt="Optimizaion ns" /></p>
<p>If you have an idea how to improve it more, please share.</p>
]]></description>
    </item>
    <item>
      <title>Selfhosted RaspberryPI based Docker Swarm Cluster</title>
      <link>https://nikita.galaiko.rocks/posts/rpi-cluster.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/cluster/</guid>
      <pubDate>2018-11-02T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="introduction">Introduction</h2>
<p>I am renting virtual servers for a long time now to host different
personal projects, including this website. I tried all of them: AWS,
Google Cloud, DigitalOcean , Azure, and I was entirely satisfied with
them until two weeks ago. Two weeks ago I came across the <a
href="https://medium.com/@bossjones/how-i-setup-a-raspberry-pi-3-cluster-using-the-new-docker-swarm-mode-in-29-minutes-aa0e4f3b1768">article</a>
where the guy described how easy is to set up a RaspberryPI cluster
powered by Docker Swarm. This idea seemed exciting to me, so I ordered
all the equipment and spent some time to set it up and move most of the
services from DigitalOcean servers to my living room. During that time I
faced a lot of unexpected difficulties and read most of the articles
where people described how to set up the Docker Swarm cluster, but none
of them completely covered everything I wanted to do, so here is another
one.</p>
<p>Hardware Used:</p>
<ul>
<li>4 x <a
href="https://www.amazon.de/gp/product/B06XFSZGCC/ref=oh_aui_detailpage_o00_s00?ie=UTF8&amp;psc=1">microSDHC
32 Pro Class 10</a></li>
<li>4 x <a
href="https://www.amazon.de/gp/product/B07F71BWZT/ref=oh_aui_detailpage_o00_s00?ie=UTF8&amp;psc=1">Layer
case for Raspberry Pi</a></li>
<li>4 x <a
href="https://www.amazon.de/gp/product/B01A7BVDES/ref=oh_aui_detailpage_o00_s01?ie=UTF8&amp;psc=1">microUSB
cable</a></li>
<li>5 x <a
href="https://www.amazon.de/gp/product/B0046ZAK0K/ref=oh_aui_detailpage_o00_s01?ie=UTF8&amp;psc=1">Gigabit
Ethernet patch cable</a></li>
<li>1 x <a
href="https://www.amazon.de/gp/product/B00PTLSH9G/ref=oh_aui_detailpage_o00_s02?ie=UTF8&amp;psc=1">USB
Charger for 6 ports</a></li>
<li>4 x <a
href="https://www.amazon.de/gp/product/B07BFH96M3/ref=oh_aui_detailpage_o00_s02?ie=UTF8&amp;psc=1">Raspberry
PI 3 Model B+</a></li>
<li>1 x <a
href="https://www.amazon.de/gp/product/B000BCC0LO/ref=oh_aui_detailpage_o00_s02?ie=UTF8&amp;psc=1">8-Port
Gigabit Switch</a></li>
</ul>
<figure>
<img src="./rpi-cluster.jpeg.800x0@2x.webp" width="800"
alt="Photo of the cluster hardware" />
<figcaption aria-hidden="true">Photo of the cluster
hardware</figcaption>
</figure>
<p>Technologies used:</p>
<ul>
<li>HypriotOS - operating system for Raspberry Pi with preinstalled
docker</li>
<li>Docker Swarm - container orcestrator</li>
<li>Minio - s3 compatible object storage</li>
<li>rexray/s3fs - docker volume driver for s3 system</li>
<li>s3fs (v1.8.4) - itself</li>
<li>Prometheus / Grafana - for monitoring</li>
<li>Traefik - reverse proxy and load balancer</li>
</ul>
<h2 id="software">Software</h2>
<h3 id="arm">ARM</h3>
<p>First of all, you should be aware that ARM architecture that
Raspberry PI is based on is a pain in the ass. Almost none of Docker
images that you find are going to work as you would expect, so that be
ready to rewrite docker files and recompile binaries. What really helps
here is the <code>--resolve-image never</code> flag for deployment.
Because sometimes even if the image uses ARM compatible architecture,
docker think that it’s amd64. You can find an example of a simple
deployment script <a href="https://github.com/ngalaiko/server">here</a>
Here is the list of images I found good as a base:</p>
<ul>
<li><a
href="https://hub.docker.com/r/apcheamitru/arm32v7-alpine/">apcheamitru/arm32v7-alpine</a>
- for alpine based images. Use this one when possible, it’s much
smaller.</li>
<li><a
href="https://hub.docker.com/r/arm32v7/debian/">arm32v7/debian:7.11-slim</a>
- for Debian based images and when you are can’t/lazy to use
alpine.</li>
</ul>
<h3 id="docker-swarm">Docker Swarm</h3>
<p>Initially, I planned to use Kubernates for the cluster orchestrator,
but change that for Docker Swarm, because it turns out much more
straightforward to set up. However, it has some disadvantages according
to DevOps experts on the Internet, one that I found is that if you want
to have shared storage for your volumes across the cluster, you are
going to waste a week to find a solution that works on ARM and it will
just cause more problems, because it’s super slow.</p>
<h3 id="traefik">Traefik</h3>
<p>For routing inside of the cluster, I use Traefik - a modern reverse
proxy. What I liked about it has an integration with the docker API, so
you don’t need to describe all of your routes in a configuration file,
you just put all containers in the same network and label them in the
same compose file where you describe the container.</p>
<h3 id="prometheus-grafana">Prometheus, Grafana</h3>
<p>The first thing you want to do after you have a working cluster is
monitoring, so you know how much resources are in use and what’s the
best way to distribute them across the cluster.</p>
<p>As a source of data for the dashboards I use:</p>
<ul>
<li>node-exporter This provides the necessary node information like
overall usage of RAM / SPU / SSD , disk read/write rate, network
activity, etc.</li>
<li>arm-exporter I use this to have information about Pi’s temperature.
It has a strict correlation with CPU usage, but you want to make sure
it’s never higher than 50C.</li>
<li>cadvisor It provides information from containers point of view. How
much of the allocated resources are in use by a service. For example, I
have a limit of 256MB of RAM for Prometheus, so it goes down every day
or so because OOM killer restarts it once the RAM usage crosses the
limit. Thanks to this exporter I am aware of this and can increase the
limit or do nothing (I do nothing)</li>
</ul>
<h3 id="minio">Minio</h3>
<p>After I configured the basic cluster, I faced a serious problem.
Every time I update the cluster, and Docker Swarm decides to move a
service to another node, your persistent data is lost, because by
default Swarm supports only local volumes, it means that volume is
mounter to the current node and you have to bother yourself syncing it
between multiple nodes if you need to.</p>
<p>To have a shared volume, I have chosen <a
href="https://minio.io/">Minio</a> cluster and <a
href="https://rexray.io/">rexray</a> as an s3fs volume driver. <a
href="https://github.com/s3fs-fuse/s3fs-fuse">s3fs</a> is a file system
from Amazon that allows you to mount a bucket from s3 to the disk and
store data there. Rexray allows you to use s3fs to create volumes.
However, since I wanted to go full self-hosted, Amazon is not an option.
That’s why I use minio since it has fully compatible API with Amazon’s
s3. To configure all of that I had to build the Minio image because the
one in their docker registry is one year old and didn’t work because it
wasn’t fully UNIX compatible (mkdir didn’t work). To make it work, you
need an s3fs version higher than 1.82, and latest fuse version that you
need to compile yourself. Also , you need a rexray plugin built for the
ARM platform. You can find all of the images in <a
href="https://hub.docker.com/u/ngalayko/">my docker hub</a>. However, I
should warn you that when you manage to set this up, you find out that
write speed is extremely slow and the solution for persistence is to
bind a service to a node using placement constraints.</p>
<h2 id="migration">Migration</h2>
<p>I used to deploy all services using docker compose. You can read
about it <a
href="https://galaiko.rocks/posts/docker-compose-server-manegement/">here</a>.
The first step was to rewrite all compose files to version 3, so I can
reuse them for Swarm deployment. The second step is to set up a cluster
and expose it to the Internet. To avoid downtime, I created a test
domain that was a base domain for all cluster services while I was
testing it. When cluster was ready for “production”, I changed DNS
settings and pointer the real domain to cluster IP, so after DNS cache
was updated, all users were migrated to the new cluster without noticing
(let’s pretend I have more than 20 daily visitors and they care about
this blog).</p>
<p>Next plans are to set up DNS over HTTPS and VPN over HTTPS on the
same cluster.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="https://github.com/ngalayko/server">github repo</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem #23</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-23.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/maze/</guid>
      <pubDate>2018-09-01T00:00:00Z</pubDate>
      <description><![CDATA[<figure>
<img src="./dcp-23.png.800x0@2x.webp" width="800" alt="maze" />
<figcaption aria-hidden="true">maze</figcaption>
</figure>
<h2 id="problem">Problem</h2>
<p>You are given an M by N matrix consisting of booleans that represents
a board. Each True boolean represents a wall. Each False boolean
represents a tile you can walk on.</p>
<p>Given this matrix, a start coordinate, and an end coordinate, return
the minimum number of steps required to reach the end coordinate from
the start. If there is no possible path, then return null. You can move
up, left, down, and right. You cannot move through walls. You cannot
wrap around the edges of the board.</p>
<p>For example, given the following board:</p>
<pre><code>[
  [f, f, f, f],
  [t, t, f, t],
  [f, f, f, f],
  [f, f, f, f],
]</code></pre>
<p>and start = (3, 0) (bottom left) and end = (0, 0) (top left), the
minimum number of steps required to reach the end is 7, since we would
need to go through, (1, 2) because there is a wall everywhere else on
the second row.</p>
<h2 id="solution">Solution</h2>
<p>It is a new type of problems I faced. I remember, I solved some
during university, but it was pretty hard to come up with the solution
right away.</p>
<p>I googled basic types of maze solving algorithms, and it looks like
<a href="https://en.wikipedia.org/wiki/Lee_algorithm">Lee algorithm</a>
will be a pretty good choice in most of the <code>shortest path</code>
problems since at the end of the day a number of different paths in a
maze makes a tree.</p>
<p>The idea is deadly simple:</p>
<ol type="1">
<li>go to start cell, mark it <code>0</code>.</li>
<li>mark all neighbors as <code>+1</code>. It is a distance to the
starting cell</li>
<li>make the same for each of the neighbors</li>
</ol>
<p>By running this algorithm for each cell, we will get the number of
steps it takes to get to any other point from the start. Of course, we
should ignore walls and previously marked cells on each iteration.</p>
<p>This is a basic solution and can be optimized for a given problem.
For example, we can stop our recursive calls once we meet finish
cell.</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">// the maze is a matrix that represents a maze.</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="co">// all cells have value 0, and all walls have value 1.</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="co">// start and finish are arrays of 2 elements, [i,j] of the cells.</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>maze <span class="op">[][]</span><span class="dt">int</span><span class="op">,</span> start <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> finish <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>        <span class="co">// mark start cell is -1</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        maze<span class="op">[</span>start<span class="op">[</span><span class="dv">0</span><span class="op">]][</span>start<span class="op">[</span><span class="dv">1</span><span class="op">]]</span> <span class="op">=</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        <span class="co">// mark all cells starting from start recursively</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        mark<span class="op">(</span>maze<span class="op">,</span> start<span class="op">,</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="co">// return value of a finish cell</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> maze<span class="op">[</span>finish<span class="op">[</span><span class="dv">0</span><span class="op">]][</span>finish<span class="op">[</span><span class="dv">1</span><span class="op">]]</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="co">// pos is a structure to hold cell coordinates,</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a><span class="co">// because []int can&#39;t ba used as a map key ¯\_(ツ)_/¯</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> pos <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>        i <span class="dt">int</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>        j <span class="dt">int</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a><span class="co">// mark marks all neighbors of a given cell with n+1</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> mark<span class="op">(</span>maze <span class="op">[][]</span><span class="dt">int</span><span class="op">,</span> point <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> n <span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>        i<span class="op">,</span> j <span class="op">:=</span> point<span class="op">[</span><span class="dv">0</span><span class="op">],</span> point<span class="op">[</span><span class="dv">1</span><span class="op">]</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>        neighbors <span class="op">:=</span> <span class="kw">map</span><span class="op">[</span>pos<span class="op">]</span><span class="dt">bool</span><span class="op">{</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>                pos<span class="op">{</span>i <span class="op">+</span> <span class="dv">1</span><span class="op">,</span> j<span class="op">}:</span> <span class="ot">false</span><span class="op">,</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>                pos<span class="op">{</span>i <span class="op">-</span> <span class="dv">1</span><span class="op">,</span> j<span class="op">}:</span> <span class="ot">false</span><span class="op">,</span></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>                pos<span class="op">{</span>i<span class="op">,</span> j <span class="op">-</span> <span class="dv">1</span><span class="op">}:</span> <span class="ot">false</span><span class="op">,</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>                pos<span class="op">{</span>i<span class="op">,</span> j <span class="op">+</span> <span class="dv">1</span><span class="op">}:</span> <span class="ot">false</span><span class="op">,</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> p <span class="op">:=</span> <span class="kw">range</span> neighbors <span class="op">{</span></span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>                neighbors<span class="op">[</span>p<span class="op">]</span> <span class="op">=</span> markP<span class="op">(</span>maze<span class="op">,</span> p<span class="op">.</span>i<span class="op">,</span> p<span class="op">.</span>j<span class="op">,</span> n<span class="op">+</span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> p<span class="op">,</span> ok <span class="op">:=</span> <span class="kw">range</span> neighbors <span class="op">{</span></span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> ok <span class="op">{</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>                        mark<span class="op">(</span>maze<span class="op">,</span> <span class="op">[]</span><span class="dt">int</span><span class="op">{</span>p<span class="op">.</span>i<span class="op">,</span> p<span class="op">.</span>j<span class="op">},</span> n<span class="op">+</span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a><span class="co">// markP used to mark maze[i][j] with given n if exists and not marked.</span></span>
<span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a><span class="co">// returns true if it was marked, otherwise false.</span></span>
<span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> markP<span class="op">(</span>maze <span class="op">[][]</span><span class="dt">int</span><span class="op">,</span> i<span class="op">,</span> j<span class="op">,</span> n <span class="dt">int</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i <span class="op">&gt;=</span> <span class="bu">len</span><span class="op">(</span>maze<span class="op">)</span> <span class="op">||</span> j <span class="op">&gt;=</span> <span class="bu">len</span><span class="op">(</span>maze<span class="op">[</span><span class="dv">0</span><span class="op">])</span> <span class="op">{</span></span>
<span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">||</span> j <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb2-50"><a href="#cb2-50" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb2-51"><a href="#cb2-51" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-52"><a href="#cb2-52" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> maze<span class="op">[</span>i<span class="op">][</span>j<span class="op">]</span> <span class="op">!=</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb2-53"><a href="#cb2-53" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb2-54"><a href="#cb2-54" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-55"><a href="#cb2-55" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-56"><a href="#cb2-56" aria-hidden="true" tabindex="-1"></a>        maze<span class="op">[</span>i<span class="op">][</span>j<span class="op">]</span> <span class="op">=</span> n</span>
<span id="cb2-57"><a href="#cb2-57" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="ot">true</span></span>
<span id="cb2-58"><a href="#cb2-58" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-09-01">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Internet privacy starter pack</title>
      <link>https://nikita.galaiko.rocks/posts/internet-privacy.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/privacy/</guid>
      <pubDate>2018-08-20T00:00:00Z</pubDate>
      <description><![CDATA[<p>About a month ago I began using some systems to protect my security
on the internet a bit more than nothing.</p>
<h2 id="pihole">PiHole</h2>
<p>It started when someone shared a link to the <a
href="https://pi-hole.net/">PiHole</a> on Twitter. It is a self-hosted
DNS service that is designed for RaspberryPi for blocking advertisements
and trackers on the DNS level.</p>
<p>Turns out, about 20% of queries I make are blocked, and it doesn’t
hurt daily usage at all. Instead, now I have nice stats of a website I
visit and handy tools to block/whitelist some of them.</p>
<figure>
<img src="./internet-privacy.pihole.jpg.800x0@2x.webp" width="800"
alt="Pihole" />
<figcaption aria-hidden="true">Pihole</figcaption>
</figure>
<p>You can install it directly on your router, on every device that you
use. For MacBook and AppleTV I changed DNS settings to use my custom IP
address, for iPhone, I found <a href="https://www.dnsoverride.com/">this
app</a> that can change DNS for all requests, even when you use
cellular. If you want to try it, the address is the same as the IP of
this website <code>167.99.219.223</code></p>
<h2 id="matomo">Matomo</h2>
<figure>
<img src="./internet-privacy.matomo.jpg.800x0@2x.webp" width="800"
alt="Matomo" />
<figcaption aria-hidden="true">Matomo</figcaption>
</figure>
<p>After enabling PiHole, Google Analytics stopped working, so I found a
self-hosted alternative and installed it on this website.</p>
<p><a href="https://matomo.org/">Matomo</a> is pretty good. It has all
essential analytics features and respects user privacy. For example, I
configured it anonymize last digits of user IP. For example,
<code>167.99.219.223</code> will be changed to
<code>167.99.219.000</code> before saving.</p>
<p>If you don’t want it, you can <a
href="https://support.apple.com/kb/PH21416?locale=en_US">configure a
browser</a> to send “Do not track me” requests to websites.</p>
<h2 id="vpn">VPN</h2>
<p>And, of course, VPN. I hope everyone knows what it is.</p>
<p>This time I use <a href="https://libreswan.org/">Libreswan</a> and <a
href="https://github.com/xelerance/xl2tpd">xl2tpd</a> setup.</p>
<p>If you are going to China, try <a
href="https://github.com/StreisandEffect/streisand">streisand</a>. VPN
detecting and blocking technology there is the next level, something
simple will be banned within a couple of days for sure.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="https://pi-hole.net/">PiHole</a></li>
<li><a
href="https://github.com/ngalayko/server/blob/master/docker-compose.dns.yml">docker-compose
file for PiHole</a></li>
<li><a href="https://firebog.net/">domains to block</a></li>
<li><a href="https://www.dnsoverride.com/">iOS app to change
dns</a></li>
<li><a href="https://matomo.org/">Matomo</a></li>
<li><a
href="https://github.com/ngalayko/server/blob/master/docker-compose.analytics.yml">docker-compose
file for Matomo</a></li>
<li><a
href="https://github.com/ngalayko/server/blob/master/docker-compose.vpn.yml">docker-compose
file for VPN</a></li>
<li><a href="https://github.com/StreisandEffect/streisand">streisand
vpn</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Docker compose for managing personal server</title>
      <link>https://nikita.galaiko.rocks/posts/docker-compose.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/docker-compose-server-manegement/</guid>
      <pubDate>2018-07-31T00:00:00Z</pubDate>
      <description><![CDATA[<p>For a long time, I tried to find the most comfortable way to manage a
server where I host something for myself, some kind of DevOps framework.
And I think I found the best way so far.</p>
<p>Since most of the times things I want to host are useless and I often
change my mind, there are several requirements for it:</p>
<ol type="1">
<li><p><strong>Easy to add/remove new components.</strong></p>
<p>Let’s say I created a website, and a couple of days later I added a
DNS server on the same host, and then I went to Russia, so I also need
to host VPN. Later I realize I don’t really need DNS server, so I want
to remove it.</p>
<p>Doing these things, I want to do only them. I don’t really want to
fix website deployment while deploying VPN server, and accidentally
remove VPN when stopping DNS server.</p></li>
<li><p><strong>No vendor lock.</strong></p>
<p>I want to remove, or start a new server with the same configuration
on different hosting provider any time I want. Digital Ocean, AWS,
Google Cloud, my old computer - whatever.</p></li>
<li><p><strong>Automate as much as possible.</strong></p>
<p>Deployment, https certificates for subdomains, restarting failed
instances, etc. I don’t want to care about this at all.</p></li>
</ol>
<p>In the beginning, I was setting up Nginx on the host and Let’s
Encrypt certificates update. So to add or remove something new I had to
change nginx configuration for a hole server, what could lead to
crashing of all components because they are exposed to the world via
same Nginx. Also, I need new subdomain certs, because Let’s encrypt
didn’t have wildcards back then.</p>
<p>My first attempt to automate it was <a
href="https://github.com/ngalayko/my_server">this</a>. Ansible roles for
each component (usually dockerized) and Makefile to execute them. The
main problem was that I had my own CI server running (for some reason).
That’s why if it crashes, you should go and set it up back manually,
what is always a pain in the ass and takes some time. So a after couple
of crashes, it got boring, I stopped care about it and deleted host.</p>
<p>A couple of weeks ago I started this blog, so I tried to find a way
to manage a host server one more time.</p>
<p><a href="https://github.com/ngalayko/server">Here</a> it is.</p>
<p>There are 2 components:</p>
<ol type="1">
<li><p><a
href="https://github.com/ngalayko/server/blob/master/docker-compose.yml">Automated
nginx-docker-with-lets-encrypt compose file</a></p>
<p>What it does is generating nginx configuration based on other
containers in the same docker network and taking care of https for them.
You can read more in the repository readme file, but basically, it
contains three parts: nginx, nginx configuration generator and a
certificates generator using Let’s Encrypt.</p>
<p>That allows us to add new components easily - just add new service to
compose file or remove one. Also, does not depend on host provider,
because can be run on pretty much any operating system.</p></li>
<li><p><a
href="https://github.com/ngalayko/server/tree/master/.travis">Travis
deployment</a></p>
<p>It logs in via ssh to your remote server and runs deployment script
there. Step-to-step explanation on how to set it up you can find <a
href="https://gist.github.com/nickbclifford/16c5be884c8a15dca02dca09f65f97bd">here</a>.
Only change I made there - added environment variables export, so it’s
possible to strore secret keys in Travis.</p></li>
</ol>
<p>That’s it! Travis <a
href="https://github.com/ngalayko/server/blob/master/scripts/update.sh">executes</a>
all compose files in the folder, and removes orphan containers.</p>
<p>To add a new component to the system, I need to create a <a
href="https://github.com/ngalayko/server/tree/master/blog">new
folder</a> or <a
href="https://github.com/umputun/remark/tree/e278da3cd074b86c5d59359e4f1c615ab6f98b93">add
git submodule</a> with a Dockerized app and add a <a
href="https://github.com/ngalayko/server/blob/master/docker-compose.dns.yml">docker-compose
file</a> to run it, following some rules, so nginx container can find it
and create routes.</p>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://gist.github.com/nickbclifford/16c5be884c8a15dca02dca09f65f97bd">Travis
deployment configuration</a></li>
<li><a
href="https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion">Docker
Let’s Encrypt Nginx proxy companion</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Half a year with vim</title>
      <link>https://nikita.galaiko.rocks/posts/vim.html</link>
      <guid>https://nikita.galaiko.rocks/posts/blog/half-a-year-with-vim/</guid>
      <pubDate>2018-07-21T00:00:00Z</pubDate>
      <description><![CDATA[<figure>
<img src="./vim.jpg.800x0@2x.webp" width="800"
alt="Vim learning curve" />
<figcaption aria-hidden="true">Vim learning curve</figcaption>
</figure>
<p>I started using vim because I was bored. Likely, I code in go, so
it’s pretty easy to switch. I mean, I tried to do Java with vim for
about a week - and it’s a hell. So if your primary language requires
massive IDE support, it’s not an option to completely switch to vim.</p>
<p>After slightly more than half a year of usage, I improved typing,
navigation speed, and general comfort while I code.</p>
<p>Before I was using a mouse to navigate between files, scrolling them
to find something, But with vim, your movements are minimal and
efficient.</p>
<p>Also, it makes you think a bit more. Not only because you need to
remember a lot of commands and combinations, but because you always try
to do something by pressing the minimum number of keys possible.</p>
<p>I am going to describe my experience on how to start and make an
overview of the configuration I use.</p>
<h2 id="how-to-start">How to start</h2>
<h3 id="basics">Basics</h3>
<p>As a first step, to understand the basics, I suggest trying embedded
vim tutor. You can run it by:</p>
<pre><code>$ vimtutor</code></pre>
<p>It should be installed by default.</p>
<p>It’s a text file divided into lessons which will teach you to
navigate, edit, search and more - basics enough for daily use. I was
doing this tutorial for a couple of weeks until I was confident with
each lesson.</p>
<p>Once you got used to <code>hjkl</code> navigation, stop doing it. The
main power of vim is navigation and clicking <code>hhhhhh</code> to get
to another line, for instance, is super inefficient. It can be as hard
as switching to vim, but you will not regret. Here is a <a
href="https://www.youtube.com/watch?v=OnUiHLYZgaA">good video</a> about
it.</p>
<h3 id="configuration">Configuration</h3>
<p>Some people suggest to use vanilla vim to start with, so you can
understand which functions you luck of comparing to IDE/editor you used
to and do not install a lot of useless plugins.</p>
<p>However, I think it makes sense to find the most popular
configuration for a language you use on GitHub and use it as a base.</p>
<p>After some time you most likely will optimize it for your usage. I
did exactly same, started with <a
href="https://github.com/farazdagi/vim-go-ide">vim-go-ide</a> and then
<a href="https://github.com/ngalayko/vim-go-ide">forked it</a>.</p>
<h2 id="configuration-overwiew">Configuration overwiew</h2>
<p>Here is a list of plugins I use:</p>
<ul>
<li><a href="https://github.com/morhetz/gruvbox">gruvbox</a> - really
good color scheme (I prefer dark version)</li>
<li><a href="https://github.com/Shougo/deoplete.nvim">deoplete.nvim</a>
- fast-auto completion, the first thing to have when you used to
IDE</li>
<li><a href="https://github.com/zchee/deoplete-go">deoplete-go</a> - go
specific completion options. By default it can complete only words from
the same file, recently used words, file paths</li>
<li><a href="https://github.com/roxma/nvim-yarp">nvim-yarp</a> -
required by deoplete in order to work with vim8</li>
<li><a
href="https://github.com/roxma/vim-hug-neovim-rpc">vim-hug-neovim-rpc</a>
- same</li>
<li><a href="https://github.com/scrooloose/nerdtree">nerdtree</a> - the
best plugin to navigate in a directory tree. Has a lot of options from
creating/deleting a file to some super weird I don’t use</li>
<li><a href="https://github.com/tpope/vim-fugitive">vim-fugitive</a> -
super powerful git integration</li>
<li><a
href="https://github.com/scrooloose/nerdcommenter">nerdcommenter</a> -
smart commenting selected lines/parts of code</li>
<li><a href="https://github.com/fatih/vim-go">vim-go</a> - the main
plugin if you code in Go. Includes a lot of commands, syntax checking,
syntax highlighting, go tools. Make sure you read documentation</li>
<li><a href="https://github.com/jiangmiao/auto-pairs">auto-pairs</a> -
automatically close paired symbols e.x. brackets</li>
<li><a href="https://github.com/majutsushi/tagbar">tagbar</a> - overview
of source code. variables / functions / classes / etc.</li>
<li><a href="https://github.com/junegunn/fzf">fzf</a> - if you still use
<code>grep</code> or <code>ag</code>, check this out</li>
<li><a href="https://github.com/junegunn/fzf.vim">fzf.vim</a> - better
fzf integration for vim.</li>
<li><a
href="https://github.com/ekalinin/Dockerfile.vim">Dockerfile.vim</a> -
Dockerfiles syntax highlighting</li>
<li><a href="https://github.com/mhinz/vim-signify">vim-signify</a> -
hightlighting of changed lines of code for any vcs</li>
<li><a href="https://github.com/chr4/nginx.vim">nginx.vim</a> - nginx
syntax highlighting</li>
</ul>
<h1 id="links">Links</h1>
<ul>
<li><a href="https://github.com/ngalayko/vim-go-ide">My fork of
vim-go-ide</a></li>
<li><a href="https://www.youtube.com/watch?v=XA2WjJbmmoM">How to Do 90%
of What Plugins Do (With Just Vim)</a></li>
<li><a href="https://www.youtube.com/watch?v=OnUiHLYZgaA">Improving Vim
Speed</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem #15</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-15.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/probability/</guid>
      <pubDate>2018-07-16T00:00:00Z</pubDate>
      <description><![CDATA[<p>Today problem is a <code>probability</code> problem.</p>
<h2 id="problem">Problem</h2>
<p>This problem was asked by Facebook:</p>
<blockquote>
<p>Given a stream of elements too large to store in memory, pick a
random element from the stream with uniform probability.</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>There are many variations of such problems, and before solving it, I
want to show some basic examples that I met.</p>
<p>Most trivial one is <strong>picking one random element from an
array</strong>.</p>
<p>Every programming language has a function to generate a pseudo-random
number (<code>int</code> or <code>float</code>) within the given range.
If you think of an array <strong>A</strong> as of <strong>N</strong>
numbers, it’s clear how to pick random one: generate number
<strong>i</strong> from 0 to N, and <strong>a[i]</strong> is the
answer.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> oneRandom<span class="op">(</span>a <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    i <span class="op">:=</span> rand<span class="op">.</span>Intn<span class="op">(</span><span class="bu">len</span><span class="op">(</span>a<span class="op">))</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> aa<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Sometimes you need to pick <strong>N random elements from an
array</strong>.</p>
<p>In this case, you can use the same approach and pick
<strong>N</strong> indexes from <strong>0</strong> to
<strong>len(A)</strong>.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> nRandom<span class="op">(</span>a <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> n <span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">int</span><span class="op">,</span> n<span class="op">)</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> n<span class="op">;</span> i<span class="op">++</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>        result<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> oneRandom<span class="op">(</span>a<span class="op">)</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>However, if you need to pick <strong>N</strong> random elements, they
also have to be <strong>different</strong>.</p>
<p>In this case, you can pick <strong>N</strong> different indexes and
make sure that they are different:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> nDifferentRandom1<span class="op">(</span>a <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> n <span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    m <span class="op">:=</span> <span class="kw">map</span><span class="op">[</span><span class="dt">int</span><span class="op">]</span><span class="dt">bool</span><span class="op">{}</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="bu">len</span><span class="op">(</span>m<span class="op">)</span> <span class="op">!=</span> n <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        j <span class="op">:=</span> rand<span class="op">.</span>Intn<span class="op">(</span><span class="bu">len</span><span class="op">(</span>a<span class="op">))</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        m<span class="op">[</span>j<span class="op">]</span> <span class="op">=</span> <span class="ot">true</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">int</span><span class="op">,</span> n<span class="op">)</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> m <span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        result<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> a<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But it’s not very efficient, because you can spend much time trying
to pick the last index when you need to pick 8 elements from an array of
length 10.</p>
<p>In this case, you can use the well-known zero-allocation algorithm to
do so. The idea is to move elements you picked to the beginning of an
array, and choose from others next:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> nDifferentRandom2<span class="op">(</span>a <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> n <span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span><span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> n<span class="op">;</span> i<span class="op">++</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        chooseFrom <span class="op">:=</span> a<span class="op">[</span>i<span class="op">:]</span>                            <span class="co">// define a slice to pick from</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>        choosenIndex <span class="op">:=</span> rand<span class="op">.</span>Intn<span class="op">(</span><span class="bu">len</span><span class="op">(</span>chooseFrom<span class="op">))</span>     <span class="co">// pick a random index from i to N</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>        a<span class="op">[</span>i<span class="op">],</span> a<span class="op">[</span>choosenIndex<span class="op">]</span> <span class="op">=</span> a<span class="op">[</span>choosenIndex<span class="op">],</span> a<span class="op">[</span>i<span class="op">]</span>  <span class="co">// swap choosenElement with i</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// after all, we have choosen elements at the</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// begining of an array, and probability is always same.</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> a<span class="op">[:</span>n<span class="op">]</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Let’s return to problem #15 and try to solve it using previous
examples.</p>
<p>What do we have:</p>
<ol type="1">
<li>a stream of elements too large to store in memory</li>
<li>should pick 1 random element</li>
</ol>
<p>We understand that to pick a random element from the stream with
uniform probability, we need to process hole stream somehow (without
storing to memory).</p>
<p>Well, we always can iterate over a stream (but just once).</p>
<p>If we knew the length of a stream, we could use the approach from the
first example, that would be perfect.</p>
<p>In first example each element of an array have a linked number - it’s
index. Moreover, we used a function that returns number from 0 to n with
uniform probability within that range to pick one.</p>
<p>So, in this case, we can <strong>assign</strong> a random value to
each element with the same probability, and choose between them based on
it linked number.</p>
<p>Let’s do it: for each element, we generate a float number between
<strong>[0..1]</strong>. Also, we remember maximum value that we
generated, an element from the stream associated with it - random
element.</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb5"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>in <span class="op">&lt;-</span><span class="kw">chan</span> <span class="dt">int</span><span class="op">)</span> <span class="op">&lt;-</span><span class="kw">chan</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    res <span class="op">:=</span> <span class="bu">make</span><span class="op">(</span><span class="kw">chan</span> <span class="dt">int</span><span class="op">,</span> <span class="dv">1</span><span class="op">)</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">go</span> <span class="kw">func</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">var</span> result <span class="dt">int</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">var</span> lastprob <span class="dt">float64</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> a <span class="op">:=</span> <span class="kw">range</span> in <span class="op">{</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>            prob <span class="op">:=</span> rand<span class="op">.</span>Float64<span class="op">()</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> prob <span class="op">&gt;</span> lastprob <span class="op">{</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>                result <span class="op">=</span> a</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>                lastprob <span class="op">=</span> prob</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>        res <span class="op">&lt;-</span> result</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}()</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> res</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-16">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Boring</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-boring.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/boring/</guid>
      <pubDate>2018-07-12T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>Hardest problem to solve so far: <em>describing 30min trivial
problems turned out to be much less fun than I imagined.</em></p>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-09">Problem
#8</a>: binary tree (fun, but always same)</li>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-10">Problem
#9</a>: array operations (boring and always same)</li>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-11">Problem
#10</a>: go basics (3 lines wtf)</li>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-12">Problem
#11</a>: a search tree</li>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-13">Problem
#12</a>: recursive algorithm (always same, sometimes hard to
detect)</li>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-14">Problem
#13</a>: string operations (super lame)</li>
</ul>
<p>I will keep updating GitHub, but not sure about the website.</p>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #7</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-7.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-7/</guid>
      <pubDate>2018-07-08T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was asked by Facebook.</p>
<blockquote>
<p>Given the mapping a = 1, b = 2, … z = 26, and an encoded message,
count the number of ways it can be decoded.</p>
<p>For example, the message ‘111’ would give 3, since it could be
decoded as ‘aaa’, ‘ka’, and ‘ak’.</p>
<p>You can assume that the messages are decodable. For example, ‘001’ is
not allowed.</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>Firstly, let’s take care of a mapping. So if <code>a = 1</code>, then
<code>charCode = code(char) - code('a') + 1</code>, it’s is possible,
because in ASCII table letters of Latin alphabet are located one by one.
In the example, I use function <code>f(string)</code> that returns 1 if
a string can be decoded, otherwise 0.</p>
<p>Most of the string parsing problems are recursion based. To start
with such a solution, it’s always helpful to manually solve some trivial
cases, trying to use the results of a previous case:</p>
<p>If the length of a string is 1, there is always 1 way to decode it,
so it’s our base case.</p>
<pre><code>&#39;1&#39;:
    [&#39;1&#39;]

----------
F(&#39;1&#39;) = 1</code></pre>
<p>If the length is 2, we always have 1 way with all digits separately,
plus one if a number is less than <code>26</code>, we also use this one
as a base case.</p>
<pre><code>&#39;12&#39;:
    [&#39;1&#39;, &#39;2&#39;]
    [&#39;12&#39;]
---------------------
F(&#39;12&#39;) = f(&#39;12&#39;) + 1</code></pre>
<p>If the length is 3, we can use the results of previous calculations,
because we already know how to deal with shorter strings.</p>
<pre><code>F(&#39;123&#39;) = f(&#39;1&#39;) * F(&#39;23&#39;) + F(&#39;12&#39;) * f(&#39;3&#39;) = 3</code></pre>
<p>All next cases can be calculated using previously defined:</p>
<pre><code>F(&#39;4123&#39;) = f(&#39;4&#39;) * F(&#39;123&#39;) + f(&#39;41&#39;) * F(&#39;23&#39;) = 3</code></pre>
<h1 id="code">Code</h1>
<div class="sourceCode" id="cb5"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>s <span class="dt">string</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>        firstZero <span class="op">:=</span> s<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">==</span> <span class="ch">&#39;0&#39;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        l <span class="op">:=</span> <span class="bu">len</span><span class="op">(</span>s<span class="op">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">switch</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">case</span> l <span class="op">==</span> <span class="dv">1</span><span class="op">:</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> canDecode<span class="op">(</span>s<span class="op">)</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">case</span> l <span class="op">==</span> <span class="dv">2</span><span class="op">:</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> firstZero <span class="op">{</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>                    <span class="co">// endge case for strings like &#39;01&#39;</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">return</span> canDecode<span class="op">(</span>s<span class="op">)</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> canDecode<span class="op">(</span>s<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">default</span><span class="op">:</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> canDecode<span class="op">(</span>s<span class="op">[:</span><span class="dv">1</span><span class="op">])*</span>solution<span class="op">(</span>s<span class="op">[</span><span class="dv">1</span><span class="op">:])</span> <span class="op">+</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>                        canDecode<span class="op">(</span>s<span class="op">[:</span><span class="dv">2</span><span class="op">])*</span>solution<span class="op">(</span>s<span class="op">[</span><span class="dv">2</span><span class="op">:])</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a><span class="co">// returns 1 if possible to decode string.</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> canDecode<span class="op">(</span>s <span class="dt">string</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> s<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">==</span> <span class="ch">&#39;0&#39;</span> <span class="op">{</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a>        i<span class="op">,</span> err <span class="op">:=</span> strconv<span class="op">.</span>ParseInt<span class="op">(</span>s<span class="op">,</span> <span class="dv">10</span><span class="op">,</span> <span class="dv">64</span><span class="op">)</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> err <span class="op">!=</span> <span class="ot">nil</span> <span class="op">{</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> i <span class="op">&lt;=</span> <span class="dv">26</span> <span class="op">{</span></span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="dv">1</span></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-08">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #5</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-5.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-5/</guid>
      <pubDate>2018-07-06T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was asked by Jane Street.</p>
<blockquote>
<p>cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the
first and last element of that pair. For example, car(cons(3, 4))
returns 3, and cdr(cons(3, 4)) returns 4.</p>
<p>Given this implementation of cons:</p>
<pre><code>def cons(a, b):
  def pair(f):
    return f(a, b)
  return pair</code></pre>
<p>Implement car and cdr.</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>The main difficulty with functional programming when you are used to
object-oriented is that you don’t have clear names for things that are
happening (try to explain to anyone what <em>monad</em> is).</p>
<p>Even if you never tried functional programming, it’s is possible to
guess how python solution looks like. I will just put it and move to the
next one in go.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> cons(a, b):</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> pair(f):</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> f(a, b)</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> pair</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> car(f):</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> left(a, b):</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> a</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> f(left)</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> cdr(f):</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> right(a, b):</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> b</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> f(right)</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(car(cons(<span class="dv">3</span>,<span class="dv">4</span>)))</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(cdr(cons(<span class="dv">3</span>,<span class="dv">4</span>)))</span></code></pre></div>
<p>So most of the functional programming is about passing a behavior to
a function.</p>
<p>When in the object-oriented paradigm you have and interface and two
implementations, in functional you have a function (interface) that
accepts another function (implementation) and calls it inside.</p>
<p>This particular problem is all about it.</p>
<p>We have <code>cons</code> - high order function that accepts two
integers and returns another function, which accepts the third function
that knows how to operate with this integers. Sounds crazy, but let’s
try to give names to all these kinds of function.</p>
<p>First of all, we need to define <code>choice</code>, that knows how
to pick one integer out of two.</p>
<p>The function that is returned by given implementation of
<code>cons</code> I called <code>makeChoice</code>. This type of
function knows what to do with given choice.</p>
<p>Given function <code>cons</code> constructs <code>makeChoice</code>
function using input integers.</p>
<p>We should implement two functions that will apply two kinds of
behavior using given <code>makeChoice</code>.</p>
<p>Now when we can name function types and understand what they do, it’s
much easier to write the solution.</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">package</span> main</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="st">&quot;fmt&quot;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        car <span class="op">:=</span> car<span class="op">(</span>cons<span class="op">(</span><span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">))</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        cdr <span class="op">:=</span> cdr<span class="op">(</span>cons<span class="op">(</span><span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">))</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        fmt<span class="op">.</span>Printf<span class="op">(</span><span class="st">&quot;car: %d, cdr: %d</span><span class="ch">\n</span><span class="st">&quot;</span><span class="op">,</span> car<span class="op">,</span> cdr<span class="op">)</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> choise <span class="kw">func</span><span class="op">(</span><span class="dt">int</span><span class="op">,</span> <span class="dt">int</span><span class="op">)</span> <span class="dt">int</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> makeChoise <span class="kw">func</span><span class="op">(</span>choise<span class="op">)</span> <span class="dt">int</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> cons<span class="op">(</span>a<span class="op">,</span> b <span class="dt">int</span><span class="op">)</span> makeChoise <span class="op">{</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        p <span class="op">:=</span> <span class="kw">func</span><span class="op">(</span>i choise<span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> i<span class="op">(</span>a<span class="op">,</span> b<span class="op">)</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> p</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> car<span class="op">(</span>do makeChoise<span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>        chooseRight <span class="op">:=</span> <span class="kw">func</span><span class="op">(</span>a<span class="op">,</span> b <span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> a</span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> do<span class="op">(</span>chooseRight<span class="op">)</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> cdr<span class="op">(</span>do makeChoise<span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a>        chooseLeft <span class="op">:=</span> <span class="kw">func</span><span class="op">(</span>a<span class="op">,</span> b <span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> b</span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> do<span class="op">(</span>chooseLeft<span class="op">)</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-06">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #4</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-4.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-4/</guid>
      <pubDate>2018-07-05T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was asked by Stripe.</p>
<blockquote>
<p>Given an array of integers, find the first missing positive integer
in linear time and constant space. In other words, find the lowest
positive integer that does not exist in the array. The array can contain
duplicates and negative numbers as well.</p>
<p>For example, the input [3, 4, -1, 1] should give 2. The input [1, 2,
0] should give 3.</p>
<p>You can modify the input array in-place.</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>To solve this, you should think what’s common between array indexes
and a positive integer: it’s the same thing.</p>
<p>So we put each positive integer of an array at its place (i+1 since
we count from 1) and then iterate again to find first missing.</p>
<p>If we don’t, return length plus one (=next).</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> a <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span> <span class="co">// try to place all numbers at same index (from 1)</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">{</span> <span class="co">// we don&#39;t care, it&#39;s negative</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">&gt;=</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">{</span> <span class="co">// we don&#39;t care, result always &lt; len(aa)</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>        aa<span class="op">[</span>a<span class="op">-</span><span class="dv">1</span><span class="op">]</span> <span class="op">=</span> a</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span> <span class="co">// find first missing</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> aa<span class="op">[</span>i<span class="op">]</span> <span class="op">!=</span> i<span class="op">+</span><span class="dv">1</span> <span class="op">{</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> i <span class="op">+</span> <span class="dv">1</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span> <span class="co">// all there</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="benchmarks">Benchmarks</h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>goos<span class="op">:</span> darwin</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>goarch<span class="op">:</span> amd64</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>pkg<span class="op">:</span> github<span class="op">.</span>com<span class="op">/</span>ngalayko<span class="op">/</span>dcp<span class="op">/</span>problems<span class="op">/</span><span class="dv">2018</span><span class="op">-</span><span class="bn">07</span><span class="op">-</span><span class="bn">05</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">0</span><span class="op">-</span><span class="dv">4</span>   <span class="dv">1000000000</span>               <span class="fl">2.18</span> ns<span class="op">/</span>op            <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">100</span><span class="op">-</span><span class="dv">4</span>                 <span class="dv">20000000</span>                <span class="fl">65.0</span> ns<span class="op">/</span>op             <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">200</span><span class="op">-</span><span class="dv">4</span>                 <span class="dv">10000000</span>               <span class="dv">122</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">300</span><span class="op">-</span><span class="dv">4</span>                 <span class="dv">10000000</span>               <span class="dv">178</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">400</span><span class="op">-</span><span class="dv">4</span>                 <span class="dv">10000000</span>               <span class="dv">238</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">500</span><span class="op">-</span><span class="dv">4</span>                  <span class="dv">5000000</span>               <span class="dv">295</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">600</span><span class="op">-</span><span class="dv">4</span>                  <span class="dv">5000000</span>               <span class="dv">354</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">700</span><span class="op">-</span><span class="dv">4</span>                  <span class="dv">3000000</span>               <span class="dv">410</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">800</span><span class="op">-</span><span class="dv">4</span>                  <span class="dv">3000000</span>               <span class="dv">466</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>Benchmark<span class="op">/</span><span class="dv">900</span><span class="op">-</span><span class="dv">4</span>                  <span class="dv">3000000</span>               <span class="dv">528</span> ns<span class="op">/</span>op               <span class="dv">0</span> B<span class="op">/</span>op          <span class="dv">0</span> allocs<span class="op">/</span>op</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>PASS</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>ok      github<span class="op">.</span>com<span class="op">/</span>ngalayko<span class="op">/</span>dcp<span class="op">/</span>problems<span class="op">/</span><span class="dv">2018</span><span class="op">-</span><span class="bn">07</span><span class="op">-</span><span class="bn">05</span>     <span class="fl">19.293</span><span class="er">s</span></span></code></pre></div>
<h2 id="update">UPDATE</h2>
<p>As it was mentioned in the comments, the first solution fails in case
of [3,2,4,-1,1]</p>
<p>It happens because when we place an integer to its position in the
array, we also delete integer that used to be in that place.</p>
<p>To avoid this, instead of just placing the integer, I swap it with
the current one and process current index one more time.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">);</span> i<span class="op">++</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        a <span class="op">:=</span> aa<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">{</span> <span class="co">// we don&#39;t care, it&#39;s negative</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">&gt;=</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">{</span> <span class="co">// we don&#39;t care, result always &lt; len(aa)</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">==</span> aa<span class="op">[</span>a<span class="op">-</span><span class="dv">1</span><span class="op">]</span> <span class="op">{</span> <span class="co">// if integer on it&#39;s place, skip</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>        <span class="co">// put each integer on it&#39;s place</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>        <span class="co">// decrease i, because aa[i] is a new integer now and we need to</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        <span class="co">// process it one more time</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>        aa<span class="op">[</span>i<span class="op">],</span> aa<span class="op">[</span>a<span class="op">-</span><span class="dv">1</span><span class="op">]</span> <span class="op">=</span> aa<span class="op">[</span>a<span class="op">-</span><span class="dv">1</span><span class="op">],</span> aa<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>        i<span class="op">--</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span> <span class="co">// find first missing</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> aa<span class="op">[</span>i<span class="op">]</span> <span class="op">!=</span> i<span class="op">+</span><span class="dv">1</span> <span class="op">{</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> i <span class="op">+</span> <span class="dv">1</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span> <span class="co">// all there</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-05">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #3</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-3.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-3/</guid>
      <pubDate>2018-07-04T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was asked by Google:</p>
<blockquote>
<p>Given the root to a binary tree, implement serialize(root), which
serializes the tree into a string, and deserialize(s), which
deserializes the string back into the tree.</p>
<p>For example, given the following Node class</p>
<pre><code>class Node:
  def init(self, val, left=None, right=None):
    self.val = val
    self.left = left
    self.right = right</code></pre>
<p>The following test should pass:</p>
<pre><code>node = Node(&#39;root&#39;, Node(&#39;left&#39;, Node(&#39;left.left&#39;)), Node(&#39;right&#39;))
assert deserialize(serialize(node)).left.left.val == &#39;left.left&#39;</code></pre>
</blockquote>
<h2 id="solution">Solution</h2>
<p>This one is weird. It doesn’t say we can’t use standard library, so I
will just use it.</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> node <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    Value <span class="dt">string</span> <span class="st">`json:&quot;value&quot;`</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    Left  <span class="op">*</span>node  <span class="st">`json:&quot;left&quot;`</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    Right <span class="op">*</span>node  <span class="st">`json:&quot;right&quot;`</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="co">// New is a node constructor.</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> New<span class="op">(</span>v <span class="dt">string</span><span class="op">,</span> l<span class="op">,</span> r <span class="op">*</span>node<span class="op">)</span> <span class="op">*</span>node <span class="op">{</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">&amp;</span>node<span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        Value<span class="op">:</span> v<span class="op">,</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>        Left<span class="op">:</span>  l<span class="op">,</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>        Right<span class="op">:</span> r<span class="op">,</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="co">// Serialize returns string representation of a node.</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> <span class="op">(</span>n <span class="op">*</span>node<span class="op">)</span> Serialize<span class="op">()</span> <span class="op">(</span><span class="dt">string</span><span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    b<span class="op">,</span> err <span class="op">:=</span> json<span class="op">.</span>Marshal<span class="op">(</span>n<span class="op">)</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dt">string</span><span class="op">(</span>b<span class="op">),</span> err</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a><span class="co">// Deserialize returns node from it&#39;s string representation.</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> Deserialize<span class="op">(</span>s <span class="dt">string</span><span class="op">)</span> <span class="op">(*</span>node<span class="op">,</span> <span class="dt">error</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>    n <span class="op">:=</span> <span class="bu">new</span><span class="op">(</span>node<span class="op">)</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> n<span class="op">,</span> json<span class="op">.</span>Unmarshal<span class="op">([]</span><span class="dt">byte</span><span class="op">(</span>s<span class="op">),</span> n<span class="op">)</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-04">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #2</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-2.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-2/</guid>
      <pubDate>2018-07-03T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was asked by Uber:</p>
<blockquote>
<p>Given an array of integers, return a new array such that each element
at index i of the new array is the product of all the numbers in the
original array except the one at i.</p>
<p>For example, if our input was [1, 2, 3, 4, 5], the expected output
would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected
output would be [2, 3, 6].</p>
<p>Follow-up: what if you can’t use division?</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>For this one, I have 2 solutions, with and without division.
Follow-up in the problem text should mean that it’s easier to solve it
if you don’t have division, but in reality, division causes many
problems, since you can accidentally divide by zero.</p>
<h3 id="first">First</h3>
<p>Without edge cases it’s pretty straightforward: get the product of
all array elements, then in the loop, divide that product by each
element. As a result, you get the product of all elements except for the
current one.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution_no_edge_cases<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="dv">1</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> a <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>        result <span class="op">*=</span> a</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        aa<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> result <span class="op">/</span> aa<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> aa</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<pre><code>a * b * c / a = b * c
a * b * c / b = a * c
a * b * c / c = a * b</code></pre>
<p>Only problem - zeros. We have 2 edge cases there:</p>
<ol type="1">
<li><p>One zero in an array.</p>
<p>In this case, the result should be all zeroes except for the 0
elements. That element should contain the product of all
others.</p></li>
<li><p>Two zeros in array or more.</p>
<p>This case is pretty much like the first one, but result array always
contains only zeros. Because you there are always 0 elements in the
product.</p></li>
</ol>
<p>To avoid edge cases, we calculate the product of all elements except
zero and also count them.</p>
<p>So if we have two or more zeros in the input array, we can return an
array of 0 right away.</p>
<p>Otherwise, we iterate over an array to replace zero elements to the
product we calculated and all other elements to zero.</p>
<p>If we don’t have zeros in an array, all these conditions are skipped,
and we get the correct result.</p>
<h3 id="code">Code</h3>
<div class="sourceCode" id="cb3"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">&lt;</span> <span class="dv">2</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> aa</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="dv">1</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    countZero <span class="op">:=</span> <span class="dv">0</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> _<span class="op">,</span> a <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> a <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>            countZero<span class="op">++</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>        result <span class="op">*=</span> a</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> countZero <span class="op">&gt;</span> <span class="dv">1</span> <span class="op">{</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">int</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">))</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> aa<span class="op">[</span>i<span class="op">]</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>            aa<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> result</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> countZero <span class="op">==</span> <span class="dv">1</span> <span class="op">{</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>            aa<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>            <span class="cf">continue</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>        aa<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> result <span class="op">/</span> aa<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> aa</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h3 id="second">Second</h3>
<p>The second solution is more complicated because it’s always O(n^2),
but there are no edge cases here. Just use common logic from yesterday
<a href="/posts/dcp/problem-1/">Problem #1</a>, and get production of
each elements pairs, except with itself.</p>
<h3 id="code-1">Code</h3>
<div class="sourceCode" id="cb4"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution2<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">)</span> <span class="op">[]</span><span class="dt">int</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">)</span> <span class="op">&lt;</span> <span class="dv">2</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> aa</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    result <span class="op">:=</span> <span class="bu">make</span><span class="op">([]</span><span class="dt">int</span><span class="op">,</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">))</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>        v <span class="op">:=</span> <span class="dv">1</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> j<span class="op">,</span> aj <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> i <span class="op">==</span> j <span class="op">{</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>                <span class="cf">continue</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>            v <span class="op">*=</span> aj</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>        result<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> v</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-03">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problem: Problem #1</title>
      <link>https://nikita.galaiko.rocks/posts/dcp-1.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/problem-1/</guid>
      <pubDate>2018-07-02T00:00:00Z</pubDate>
      <description><![CDATA[<h2 id="problem">Problem</h2>
<p>This problem was recently asked by Google:</p>
<blockquote>
<p>Given a list of numbers and a number k, return whether any two
numbers from the list add up to k.</p>
<p>For example, given [10, 15, 3, 7] and k of 17, return true since 10 +
7 is 17.</p>
<p>Bonus: Can you do this in one pass?</p>
</blockquote>
<h2 id="solution">Solution</h2>
<p>If we want to find the sum of every combination of two array elements
most obvious way is to create two <code>for</code> loops over an array
and check if they satisfy our condition.</p>
<p>However, for such cases, you can always reduce complexity from O(n^2)
to O(log(n)) by just starting the second loop from current array
element, because, on each step of the first loop, all previous elements
are already compared to each other.</p>
<p>So the solution is to iterate over an array, and for each element try
to find if it adds up any next array element up to 17.</p>
<h2 id="code">Code</h2>
<div class="sourceCode" id="cb1"><pre class="sourceCode go"><code class="sourceCode go"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">func</span> solution<span class="op">(</span>aa <span class="op">[]</span><span class="dt">int</span><span class="op">,</span> k <span class="dt">int</span><span class="op">)</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i<span class="op">,</span> a <span class="op">:=</span> <span class="kw">range</span> aa <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        rest <span class="op">:=</span> k <span class="op">-</span> a</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> j <span class="op">:=</span> i<span class="op">;</span> j <span class="op">&lt;</span> <span class="bu">len</span><span class="op">(</span>aa<span class="op">);</span> j<span class="op">++</span> <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> aa<span class="op">[</span>j<span class="op">]</span> <span class="op">==</span> rest <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="ot">true</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ot">false</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="links">Links</h2>
<ul>
<li><a
href="https://github.com/ngalayko/dcp/tree/master/problems/2018-07-02">github</a></li>
</ul>
]]></description>
    </item>
    <item>
      <title>Daily Coding Problems</title>
      <link>https://nikita.galaiko.rocks/posts/dcp.html</link>
      <guid>https://nikita.galaiko.rocks/posts/dcp/intro/</guid>
      <pubDate>2018-07-01T00:00:00Z</pubDate>
      <description><![CDATA[<p>Recently found this website <a
href="https://www.dailycodingproblem.com/%5D">Daily Coding Problem</a>,
where you can subscribe to a newsletter and get one problem a day.</p>
<p>For a long time, I wanted to start solving problems from leetcode to
keep fit, but could never begin.</p>
<p>Also, for a long time, I wanted to start a blog, but could never
begin.</p>
<p>Writing short articles about how I solve these problems seems for me
as an excellent opportunity to start doing both, so every day I will
publish my solution for the daily problem here, and to <a
href="https://github.com/ngalayko/dcp">my GitHub</a> page trying to
explain why and how I solved it.</p>
]]></description>
    </item>
  </channel>
</rss>

