<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="https://rusu.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://rusu.io/" rel="alternate" type="text/html" /><updated>2026-03-16T08:04:25+00:00</updated><id>https://rusu.io/feed.xml</id><title type="html">Cosmin-Ionuț Rusu</title><subtitle>Blog about technology, my boring life and other blah blah</subtitle><entry><title type="html">Lessons I learned on managing software engineers</title><link href="https://rusu.io/on-managing-software-engineers/" rel="alternate" type="text/html" title="Lessons I learned on managing software engineers" /><published>2022-05-07T07:00:00+00:00</published><updated>2022-05-07T07:00:00+00:00</updated><id>https://rusu.io/on-managing-software-engineers</id><content type="html" xml:base="https://rusu.io/on-managing-software-engineers/"><![CDATA[<p>A few months before the pandemic started, I started my side hustle, <a href="https://dutylabs.ro" target="_blank">Duty Labs</a>.
In this article, I’d like to lay down some of the things I’ve learned from working with tens of
software development engineers and teams. Take everything is here as my observations from my own
experience working with Software Engineers primarily based in Romania and United States.</p>

<p>When I started the company, most of the folks I worked with were people I knew from university or
high school. It was fairly easy to pitch them to come work side by side with me on the projects
I found, because they already knew and trusted me.</p>

<p>This simple <strong>hiring</strong> process was quite powerful and efficient. However, your network is
as big as it is, and most of the strong engineers already have a job, so you can’t easily
convince them to come work with you. However, there’s valuable information here because
there are probably software engineers in your network that are about to graduate and they
know you as well (for example from different University events, your GitHub repository with
<a href="https://github.com/rusucosmin/courses" target="_blank">course material</a>, and so on). So I already have a
strong pool of candidates right there. The only problem with this is that I don’t really
have hands-on experience working with them. This leads to the classical hiring problem:
how do you assess if a candidate is a good candidate for you?</p>

<h3 id="assessing-junior-candidates">Assessing junior candidates</h3>

<p>My solution here was simple: have just a few clear filters:</p>

<ol>
  <li>Attending or graduated with a CS degree or equivalent</li>
  <li>Willingness to go through a simple Ruby on Rails tutorial, and then a small test to
assert if they <strong>really</strong> went through it.</li>
</ol>

<p>With this, I was essentially filtering the people who have a decent CS background (know what a 
database is, how to debug, how to use the <strong>cli</strong>, etc), and the people who are fast learners
and willing to put in some extra work for the opportunity to work in our team.</p>

<p>I am still amazed at how many people got me very impressed at the end of this process because
I simply wasn’t able to predict their outcode based on the initial conversation. Translate:
I had some really awesome discussions with folks that did really poor on the tutorial (or some
that never finished it), but I was skeptical of candidates that in the end did an amazing work
on both the tutorial, and after working with us for a few months/years now (saying <strong>hi</strong> to
whichever team member is reading this).</p>

<p>I was basically looking for a combination of good education background, and learning ability,
motivation, a bit of hard-working, determination. In other words, I was hiring for potential
(and firing early if needed!).</p>

<h3 id="growing-their-software-development-skills">Growing their Software Development skills</h3>

<p>After I hired a few folks, the next problem I had is how should I organize and manage them? Obviously,
I have no educational background in management or leadership, but I was a decent software engineer. So,
my idea was simple - just help them grow the same way I have grown: by working on different interesting
projects that keep increasing in complexity. I was their mentor rather than their manager. I was
their manager in the sense that I told them which project they should work on, assigned them tasks, etc.</p>

<p>What’s extraordinary is that I found that some folks were growing at <strong>rocket</strong> speed. Image a graduate
engineer, with three months of working experience with me, some previous internships, and <strong>lots</strong> of
personal projects!! He became my CTO in 6 months. He is one the most talented engineer I ever
worked with! There are at least 4 other examples of such pattern, so I’m still amazed at the
young talent available out there (which is so much underrated!).</p>

<h3 id="remote-teams">Remote Teams</h3>

<p>With recruiting and growing out of the way, let’s switch gears here and talk about project management.</p>

<p>In my world, a Remote Team is a team of a few software engineers (and maybe a QA) that are assigned to
work on a specific project. That being said, it’s quite clear that the output of the team is the project
itself. The inputs are all the hours they have allocated on a project, and the requirements.</p>

<p>Our process is quite straightforward:</p>

<ul>
  <li>We use Trello as our Project Management tool</li>
  <li>We assign tasks on a one-week basis</li>
  <li>We have one weekly call with the client and the whole team</li>
</ul>

<p>Notice we don’t have any extra meetings. We use Slack for most communication. If all goes well…
In case things don’t go as planned, I (or the team lead) usually have to step in and find out
what are the problems and why things are delayed, tasks do not get done on time, etc. That’s natural
and normal. Sometimes you figure out some folks just have a hard time, or they have an exam coming up,
they feel burnout, etc. Either way -&gt; when discussed, the solutions are quite easy: you can either
motivate someone, or train them in order to do something. There’s no other way. If things do not get
done it’s either because someone lacks motivation, or skill. Try to find which one of the two is the case
and fix it!</p>

<h3 id="on-the-future">On the future</h3>

<p>That’s pretty much my lean process of working with remote software engineering teams.</p>

<p>In case you’re interested in joining our team, and work remotely with us, reach out to me. I’m currently
looking for both junior, mid, and senior engineers.</p>

<p>Moreover, if you’d like to build and grow your own team, reach out to me as well as I can give you a client
project, and you can work directly with him with your own team. Based on my experience, I can teach you 
everything you need to konw to grow and build your team, as well as how to manage the client relationship.</p>

<p>If you’re interested in working with us in the fashion described above, reach out to me on LinkedIn.</p>]]></content><author><name>Cosmin Rusu</name></author><category term="blog" /><category term="business" /><category term="managing" /><category term="software engineers" /><category term="remote" /><category term="software teams" /><summary type="html"><![CDATA[Some of the lessones I learned from managing software engineers]]></summary></entry><entry><title type="html">Duty Labs Awarded as Top Developer in Romania</title><link href="https://rusu.io/dutylabs-on-clutch/" rel="alternate" type="text/html" title="Duty Labs Awarded as Top Developer in Romania" /><published>2020-09-09T07:00:00+00:00</published><updated>2020-09-09T07:00:00+00:00</updated><id>https://rusu.io/dutylabs-on-clutch</id><content type="html" xml:base="https://rusu.io/dutylabs-on-clutch/"><![CDATA[<p>The project I started 3 years ago, <a href="https://dutylabs.ro">Duty Labs</a> is growing, and
we’ve recently been awarded as Top Developer in Romania. Check out the original post
<a href="https://dutylabs.ro/2020/09/09/clutch-award.html">here</a>.</p>

<p><img src="https://rusu.io/assets/images/clutch-award.png" alt="Intro Picture" /></p>]]></content><author><name>Cosmin Rusu</name></author><category term="blog" /><category term="freelancing" /><category term="business" /><category term="lifestyle" /><category term="career" /><category term="clutch" /><category term="dutylabs" /><category term="software" /><category term="custom" /><summary type="html"><![CDATA[Dutylabs]]></summary></entry><entry><title type="html">From zero to Freelance</title><link href="https://rusu.io/from-zero-to-freelance/" rel="alternate" type="text/html" title="From zero to Freelance" /><published>2020-06-14T07:00:00+00:00</published><updated>2020-06-14T07:00:00+00:00</updated><id>https://rusu.io/from-zero-to-freelance</id><content type="html" xml:base="https://rusu.io/from-zero-to-freelance/"><![CDATA[<h1 id="context">Context</h1>

<p>Salut,</p>

<p>Numele meu e Razvan Turturica, am 21 de ani, sunt student la UT Cluj-Napoca si lucrez ca software developer, in special web. In cele ce urmeaza as dori sa va prezint povestea mea legata de freelancing. Am sa incep prin a imi prezenta un pic de background pentru a avea o idee legata de experienta in domeniu, iar apoi am sa continui prin a va prezenta primele incercari de a gasi clienti.</p>

<h1 id="background">Background</h1>

<h2 id="liceu">Liceu</h2>

<p>Am inceput sa programez C++ in liceu, in clasa a 9-a. Am participat la olimpiada, pe decursul celor 4 ani am obtinut 3 medalii la nationala si multe alte concursuri.
Pe langa programarea competitiva am avut si cateva proiectele funny, in special jocuri.
Am inceput cu un X si 0 scris in C#, banal, insa interesant pentru cineva care abia incepuse programarea.
Am scris si un joc de pacanele in JavaScript, pe care il jucam cu colegii de clasa.
Apoi am facut un platformer 2D in Unity, urmaream tutoriale pe youtube si trimiteam jocul la colegii de clasa.
Probabil cel mai mare proiect inceput in liceu a fost un joc pentru Dungeons &amp; Dragons, in care te puteai juca online cu prietenii. Aici am lucrat impreuna cu un coleg de clasa la fel de pasionat ca mine. Impreuna am invatat sa lucram pe git, cum sa lucram in echipa si multe altele.</p>

<p>Desi par sa fie destul de multe lucruri facute pentru un copil de liceu, nu va inchipuiti ca au fost facute la perfectie, sau ca indeplineau standardele din industrie. Erau in mare parte joculete pline de bug-uri, neterminate si lipsite de organizare. Cu toate acestea, cel mai important lucru invatat a fost sa stiu sa imi caut problemele pe google. Deoarece nu aveam un profesor care sa imi explice Unity sau JavaScript, trebuia sa caut singur sa imi rezolv problemele.</p>

<h2 id="facultate">Facultate</h2>

<p>Am ales sa fac UT Cluj-Napoca deoarece grupul de prieteni din liceu au venit si ei tot aici.
Deoarece nu mai aveam atat de multe competitii de programare ca in liceu si aveam destul de multa experienta, am decis sa ma apuc de predat informatica pentru liceu. Am inceput cu 1-2 elevi, iar apoi faceam pregatire cu elevi fie pentru clasa, fie pentru olimpiada.
In primul an am urmarit foarte mult sa fac un intership pe perioada verii. Am castigat doua concursuri ale unei firme (unul individual si unul pe echipe) ca mai apoi la interviu sa fiu refuzat deoarece “nu cunosc destule tehnologii”. Apoi am luat locul 2 la un alt concurs, iar aceasta firma m-a acceptat la internship. Am avut noroc deoarece aceasta firma a facut la inceput un set de training-uri pentru git, html, css, javascript, etc. Dupa am avut training-uri specifice pentru front-end, unde am invatat ReactJs.
Acest internship a deschis multe cai, deoarece fix dupa ce s-a terminat, am inceput sa lucrez impreuna cu niste prieteni la un proiect personal ce urma sa devina un cloud pentru fisiere. Eu am lucrat front-end ReactJs, in timp ce un prieten lucra back-end NodeJs. Asta a tinut cateva luni dupa care nu am mai continuat.</p>

<p>A urmat vara din anul 2, unde nu mai voiam sa fac internship, insa am prins o oferta interesanta si am aplicat. Am fost acceptat usor (un avantaj major ca aveam deja un internship + proiectul cu cloud-ul de fisiere). Acolo am facut in mare parte procesare de imagini, insa am avut ocazia sa lucrez intr-un mediu foarte profesional. Am invatat ce inseamna mesaje de commit bune, folosire de lint-ere, calitatea codului.</p>

<p>In anul 3 am inceput sa dezvolt impreuna cu prietenii din liceu o aplicatie pentru concursuri de programare. Am inceput prin a lucra doar front-end, insa apoi am facut usor tranzitia catre full-stack (imi era usor sa pun orice intrebare deoarece aveam prietenii langa mine care au lucrat cu asa ceva). Acesta a fost cel mai de succes proiect de pana acum, avand experienta din toate fail-urile precedente, cat si ajutor din partea unei firme. Acesta a fost si primul proiect care a ajuns pe live.</p>

<h2 id="freelancing">Freelancing</h2>

<p>Dupa ce am vazut ca ma descurc sa lucrez intr-un proiect de dimensiune medie, am decis sa incerc freelancing.
Am inceput prin a cauta pe site-uri de freelancing pe internet. Prima oara mi-am facut un cont pe UpWork si am aplicat la cateva job-uri care mi se pareau potrivite, insa nu stiam exact ce caut sau ce urmeaza sa fac. Nu am avut nici-un raspuns.
Dupa mi-am facut cont pe Toptal si am inceput procesul de recrutare.
In timpul procesului de recrutare m-am simtit depasit de situatie, am pus procesul de recrutare pe pauza si am cautat mentoring in domeniu.
Stiam de Cosmin Rusu de la concursurile de programare si avem cativa prieteni comuni, asa ca am decis sa iau legatura cu el.
Dupa ce mi-a explicat ce urma sa se intample am revenit la procesul de recrutare. La problemele de algortmica a mers bine (~90%), insa la interviul tehnic am avut din nou problema ca “nu am destula experienta”.
Timp de 2 ani de zile am lucrat ca developer front / full-stack. Desi aveam doar 2 internshipuri (total 5 luni) de lucrat in companie, si la proiectele mele nu aveam un senior care sa imi atraga atentia asupra greselilor, am incercat sa fiu cat mai profesional. In mare parte cautam pe google legat de tehnologie, de structurarea codului, organizare, de dezvoltare, orice. Aici eram in dubii legat de cunostintele mele, nu stiam daca am treaba cu industria, daca sunt un looser, sau daca am avut ghinion.</p>

<p>Am continuat sa aplic pe UpWork la proiecte, odata la 2-3 zile intram si cautam job-uri aplicand la 90% din job-urile pe care scria ReactJs sau NodeJs. Mai cautam si pe stack overflow unde am aplicat la o firma din strainatate, dar fara raspuns.
Deoarece lumea nu prea raspundea inapoi (am avut un raspuns pentru un job in care trebuia sa fac tutoriale video pentru incepatori in javascript, insa mi-au cerut un tutorial de test si nu l-am facut 😞), am aplicat si la un job clasic in Cluj-Napoca unde am avut mai multe interviuri (inca astept raspuns 😊).
Dupa vreo luna de cautat, am gasit pe UpWork un anunt pentru o pozitie de front-end developer la un proiect in derulare. Proiectul era dezvoltat de 2 romani, care mai aveau nevoie de inca 2 developeri. Dupa 2 interviuri am intrat intr-o echipa mica de front-end developeri. Proiectul este de durata medie.</p>

<h2 id="concluzii">Concluzii</h2>

<p>Dureaza o perioada pana cand iti gasesti primul proiect, mai ales neavand recenzii pe site-urile de freelancing.
In aceasta perioada cred ca m-a ajutat faptul ca am aplicat la mai multe joburi si cautam constant proiecte.
Chiar si faptul ca dadeam interviuri pentru un job clasic a fost interesant deoarece mai prindeam experienta de interviu.
Prinde bine sa iti faci cont pe mai multe platforme deoarece sunt cateva care au si verificari de identitate care dureaza putin, iar sticker-ul de “Verified” ajuta mai ales cand nu ai alte review-uri.</p>]]></content><author><name>Razvan Turturica (guest)</name></author><category term="blog" /><category term="freelancing" /><category term="business" /><category term="lifestyle" /><category term="career" /><category term="mentorship" /><summary type="html"><![CDATA[Povestea lui Razvan Turturica, 21, despre cum a ajuns sa faca freelancing cu relativ putina experienta reala.]]></summary></entry><entry><title type="html">How to prepare for software interview questions - Largest sum of non adjacent numbers</title><link href="https://rusu.io/largest-sum-of-non-adjacent-numbers/" rel="alternate" type="text/html" title="How to prepare for software interview questions - Largest sum of non adjacent numbers" /><published>2020-05-31T20:00:00+00:00</published><updated>2020-05-31T20:00:00+00:00</updated><id>https://rusu.io/largest-sum-of-non-adjacent-numbers</id><content type="html" xml:base="https://rusu.io/largest-sum-of-non-adjacent-numbers/"><![CDATA[<p>Continuing the series on How to prepare for software interview questions, with another
dynamic programming coding challenge.</p>

<p>My previous articles:</p>

<p><a href="/contiguous-subset-of-sum-K" target="_blank">Contiguous subset of sum K</a></p>

<p><a href="/simulate-a-queue-with-two-stacks" target="_blank">Simulate a queue with two stacks</a>.</p>

<p><a href="/number-of-ways-to-decode-a-message" target="_blank">Number of ways to decode a message</a>.</p>

<p>On the list today is the following:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Given a list of integers, write a function that returns the largest sum of non-adjacent numbers. Numbers can be 0 or negative.

For example, [2, 4, 6, 2, 5] should return 13, since we pick 2, 6, and 5. [5, 1, 1, 5] should return 10, since we pick 5 and 5.

Follow-up: Can you do this in O(N) time and constant space?
</code></pre></div></div>

<p><a href="https://www.dailycodingproblem.com/solution/9?token=e01c986e70a7bd9959427e9cecac89bdead1fca2e390bdc4af0427f38b18ee7d6c023f93" target="_blank">Some</a> say this problem was asked by Airbnb, who knows?</p>

<h2 id="dynamic-programming">Dynamic Programming</h2>

<p>Well I already leaked a hint by saying this is a dynamic programming coding challenge,
so yeah.</p>

<p><a href="https://mirceasorin.ro/" target="_blank">Sorin</a> likes to think about the
dynamic programming questions as recursions with memoziation. If you’re not
familiar with them, please read my <a href="/number-of-ways-to-decode-a-message" target="_blank">previous</a> article.</p>

<p>Now this problem doesn’t instantly scream DYNAMIC PROGRAMMING unless you really
have a lot of experience dealing with these problems and you noticed the patterns.</p>

<h2 id="recursion">Recursion</h2>

<p>So let’s see how we can come up with some sort of recursion to solve this problem.
In recursion, we usually have two things we need to think about:</p>

<ol>
  <li>The base case</li>
  <li>The recursive formula</li>
</ol>

<h3 id="the-base-case">The base case</h3>

<p>Well the base case for this problem is pretty straight forward because
it consist of the array of only one element (or none) in which case
the solution is simply that element (or 0 if empty array). In a one-element (or zero)
array you don’t have any adjacent numbers, so yeah, not much work for your brain
here.</p>

<h3 id="the-recursive-formula">The recursive formula</h3>

<p>The recursive formula is usually the tricky part in any dynamic programming (dp) task.
The idea is usually to, brace yourself, assume you are able to compute the solution
for a smaller problem and then post-process that to compute the solution for the bigger
problem.</p>

<p>In this case, let’s suppose we have an array with N values, <code class="language-plaintext highlighter-rouge">arr</code>, and let’s assume
we are able to compute the solution for the array with the first <code class="language-plaintext highlighter-rouge">1</code>, <code class="language-plaintext highlighter-rouge">2</code>, …, <code class="language-plaintext highlighter-rouge">N - 2</code>, <code class="language-plaintext highlighter-rouge">N - 1</code>
elements. How can we compute the solution for the big array? Well we can either use
the last element, <code class="language-plaintext highlighter-rouge">arr[N]</code>, or not use it. If we decide to use it, we can only use the first <code class="language-plaintext highlighter-rouge">1...N-2</code>
elements, because the element <code class="language-plaintext highlighter-rouge">arr[N - 1]</code> is adjacent to <code class="language-plaintext highlighter-rouge">arr[N]</code>. Also let’s keep in mind that we want
to take the maximum sum, so if our current number is negative, we might also not want to use it, in which
case we can (potentially) use the element on the position <code class="language-plaintext highlighter-rouge">arr[N - 1]</code>.</p>

<p>With this idea in mind, let’s derive the formula.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>max_non_adjacent_sum(arr, N):
  - 0 if N is 0

  - arr[0] if N is 1

  - max(
      # Case 1: Only take the last element if all the other ones are negative

      arr[N],

      # Case 2: Take the last element and combine that with the solution for
      # the sub-array with the first N - 2 elements

      arr[N] + max_non_adjacent_sum(arr[:-2]),

      # Case 3: Take the optimal solution of the array with the first N - 1
      # elements, and don't use the arr[N] element at all

      max_non_adjacent_sum(arr[:-1])
   )
</code></pre></div></div>

<p>So you case see we have 3 cases, and we take the one that’s the highest one, hence the max of 3 values.</p>

<h3 id="questions-for-corner-cases">Questions for corner cases</h3>

<p>When you think about this solution out load, there are some corner cases that stand out and
your interviewer will be really happy if you ask them. For example, can you not use any element at all?
But why would you ever want to do that? Well, what if the array consists only of strictly negative elements?
For example, for <code class="language-plaintext highlighter-rouge">[-1, -2, -3]</code> you might choose to not pick any element and have the sum 0.</p>

<p>Based on his answer, you will update the base case, for N = 1, you will take <code class="language-plaintext highlighter-rouge">max(0, arr[0])</code>.</p>

<p>Another good question would be what happens for an empty array? Return 0, raise an error? All of
these are great questions and your interviewer will give you extra points for asking them 😉.</p>

<p>Moving on, I will consider we can not take any element, and hence can return 0 for empty array,
and not use any element if all of them all negative.</p>

<h3 id="code">Code</h3>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">memo</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">max_non_adjacent_sum</span><span class="p">(</span><span class="n">arr</span><span class="p">):</span>
  <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="k">if</span> <span class="n">N</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
    <span class="k">return</span> <span class="mi">0</span>
  <span class="k">if</span> <span class="n">N</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
    <span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">arr</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

  <span class="k">if</span> <span class="n">N</span> <span class="ow">in</span> <span class="n">memo</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">N</span><span class="p">]</span>

  <span class="n">memo</span><span class="p">[</span><span class="n">N</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span>
    <span class="n">arr</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
    <span class="n">arr</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">max_non_adjacent_sum</span><span class="p">(</span><span class="n">arr</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]),</span>
    <span class="n">max_non_adjacent_sum</span><span class="p">(</span><span class="n">arr</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
  <span class="p">)</span>

  <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">N</span><span class="p">]</span>

<span class="k">assert</span><span class="p">(</span><span class="n">max_non_adjacent_sum</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span>
</code></pre></div></div>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/HastyKnowingBookmarks?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<h3 id="follow-up">Follow-up</h3>

<p>Now, if you came so far, you’ll almost an Airbnb employee. Or maybe <a href="https://www.wsj.com/video/how-airbnb-fell-from-successful-startup-to-crisis-mode/B1DAAC70-127E-469B-B72C-02033E90517A.html" target="_blank">not</a>.</p>

<p>Let’s try to also solve the follow-up question: <code class="language-plaintext highlighter-rouge">Follow-up: Can you do this in O(N) time and constant space?</code>.</p>

<p>Now if you want to be an Airbnb employee you really really need to know the fact that our <code class="language-plaintext highlighter-rouge">memo</code> dictionary
consumes <code class="language-plaintext highlighter-rouge">O(N)</code> memory and also that our recursion is consuming memory for the recursion stack, <code class="language-plaintext highlighter-rouge">O(N)</code> as well.</p>

<p>Let’s first try to fix the stack recursion issue, by using an iterative solution:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">max_non_adjacent_sum</span><span class="p">(</span><span class="n">arr</span><span class="p">):</span>
  <span class="n">memo</span> <span class="o">=</span> <span class="p">{}</span>
  <span class="n">memo</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
  <span class="n">memo</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>

  <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
    <span class="n">memo</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span>
      <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
      <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">memo</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">],</span>
      <span class="n">memo</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">)</span>

  <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">N</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>

<span class="k">assert</span><span class="p">(</span><span class="n">max_non_adjacent_sum</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span>
</code></pre></div></div>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/WarmheartedYellowParticle?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<p>With this solution, there a small thing to notice right there. In our recursive
formula we only need the last two elements from our memo dictionary. So the trick
is to only store those two values, in two variables, and using constant
additional memory <code class="language-plaintext highlighter-rouge">O(1)</code>. Pretty cool, huh.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">max_non_adjacent_sum</span><span class="p">(</span><span class="n">arr</span><span class="p">):</span>
  <span class="n">last</span> <span class="o">=</span> <span class="mi">0</span>
  <span class="n">before_last</span> <span class="o">=</span> <span class="mi">0</span>     <span class="c1"># Hard problem: naming your variables
</span>
  <span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
    <span class="c1"># Compute the new 'last'
</span>    <span class="n">new_last</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span>
      <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
      <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">before_last</span><span class="p">,</span>
      <span class="n">last</span>
    <span class="p">)</span>

    <span class="c1"># Update the before_last and last variables moving forward
</span>    <span class="c1"># Remember, before_plays the role of memo[N - 2], last memo[N - 1],
</span>    <span class="c1"># and new_last of memo[N].
</span>    <span class="n">before_last</span> <span class="o">=</span> <span class="n">last</span>
    <span class="n">last</span> <span class="o">=</span> <span class="n">new_last</span>

  <span class="k">return</span> <span class="n">last</span>

<span class="k">assert</span><span class="p">(</span><span class="n">max_non_adjacent_sum</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span>
</code></pre></div></div>

<p>Hurray, we have a working solution with <code class="language-plaintext highlighter-rouge">O(1)</code> memory, so now you’re ready
to become an employee at this <strong>UnIcOrN</strong>. I heard Airbnb requires all their
employees to become Hosts, so clean you’re room before your interview, they
might also ask that!</p>

<h3 id="testing">Testing</h3>

<blockquote>
  <p>Coding without writing tests is like having unprotected sex. I don’t think I need to explain more.</p>
</blockquote>

<p>Let’s see a couple of cool examples.</p>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/IncompleteEmptyMonitor?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<p>That’s it for today, later!</p>

<p>Cosmin</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="algorithms" /><category term="data structures" /><category term="dynamic programming" /><summary type="html"><![CDATA[Given a list of integers, write a function that returns the largest sum of non-adjacent numbers. Numbers can be 0 or negative.]]></summary></entry><entry><title type="html">How to prepare for software interview questions - Number of ways to decode a message</title><link href="https://rusu.io/number-of-ways-to-decode-a-message/" rel="alternate" type="text/html" title="How to prepare for software interview questions - Number of ways to decode a message" /><published>2020-05-31T10:00:00+00:00</published><updated>2020-05-31T10:00:00+00:00</updated><id>https://rusu.io/number-of-ways-to-decode-a-message</id><content type="html" xml:base="https://rusu.io/number-of-ways-to-decode-a-message/"><![CDATA[<p>Continuing the series on How to prepare for software interview questions.</p>

<p>My previous articles:</p>

<p><a href="/contiguous-subset-of-sum-K" target="_blank">Contiguous subset of sum K</a></p>

<p><a href="/simulate-a-queue-with-two-stacks" target="_blank">Simulate a queue with two stacks</a>.</p>

<p>Today, I will break down the following question:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Given the mapping a = 1, b = 2, ... z = 26, and an encoded message, count the number of ways it can be decoded.

For example, the message '111' would give 3, since it could be decoded as 'aaa', 'ka', and 'ak'.

You can assume that the messages are decodable. For example, '001' is not allowed.
</code></pre></div></div>

<h2 id="dynamic-programming">Dynamic Programming</h2>

<p>Now this is a cool application of dynamic programming. Recently, I was talking
to a close friend, <a href="https://mirceasorin.ro/" target="_blank">Sorin</a>, about how
dynamic programming is a fairly abstract concept that’s not easy to grasp. And
he said he thinks about these problems as simply recursion with memoization.</p>

<h2 id="recursion">Recursion</h2>

<p>I hope you know what recursion is, otherwise here is a simple hint:</p>

<p><img src="https://www.dropbox.com/s/a0qmhpkvf4wvcqw/Screenshot%202020-05-31%2010.51.00.png?dl=1" /></p>

<h2 id="memoization">Memoization</h2>

<p>Memoization simply means you want to store the result for a specific input of your
recursive function.</p>

<p>The classical example is the <a href="https://en.wikipedia.org/wiki/Fibonacci_number" target="_blank">Fibonacci sequence</a>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fibo(n) = fibo(n - 1) + fibo(n - 2)
fibo(1) = 1
fibo(0) = 0
</code></pre></div></div>

<p>If we were to implement a recursive method:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">fibo</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
  <span class="k">if</span> <span class="n">n</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">n</span>  <span class="c1"># fibo(0) = 0; fibo(1) = 1;
</span>
  <span class="k">return</span> <span class="n">fibo</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibo</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
</code></pre></div></div>

<p>The problem? This has complexity <code class="language-plaintext highlighter-rouge">O(2^N)</code>. If you don’t believe me, draw
the tree of recursion calls.</p>

<p>To overcome this, we can add memoization</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">memo</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># Will store the values already computed
</span>
<span class="k">def</span> <span class="nf">fibo</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
  <span class="c1"># if we already know the answer
</span>  <span class="k">if</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">memo</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
  <span class="k">if</span> <span class="n">n</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">n</span>

  <span class="c1"># store the result
</span>  <span class="n">memo</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">fibo</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibo</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>

  <span class="c1"># return it
</span>  <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
</code></pre></div></div>

<p>With this, we can compute fibo(n) in <code class="language-plaintext highlighter-rouge">O(N)</code> time and <code class="language-plaintext highlighter-rouge">O(N)</code> memory.</p>

<h2 id="back-to-our-problem">Back to our problem</h2>

<p>Let’s get back to our original problem:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Given the mapping a = 1, b = 2, ... z = 26, and an encoded message, count the number of ways it can be decoded.

For example, the message '111' would give 3, since it could be decoded as 'aaa', 'ka', and 'ak'.

You can assume that the messages are decodable. For example, '001' is not allowed.
</code></pre></div></div>

<p>We can already sense this can be solved using a recursive and memorization strategy (aka recursive dynamic programming),
so let’s start with an example.</p>

<p>For the basic strings <code class="language-plaintext highlighter-rouge">1-10</code> it’s clear there is exactly one way to decode them, easy.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>count(message):
  - 1 if message is in 1-10
</code></pre></div></div>

<p>Next, the 2 digits strings <code class="language-plaintext highlighter-rouge">11-99</code>. Well, for <code class="language-plaintext highlighter-rouge">11-26</code> we know we have exactly 2 ways
to decode them. One is to take the corresponding one mapping and the other one is
to break the string in two one-digit messages. For example, for <code class="language-plaintext highlighter-rouge">26</code> (z) we can decode <code class="language-plaintext highlighter-rouge">z</code> (26) and <code class="language-plaintext highlighter-rouge">b</code>(2) + <code class="language-plaintext highlighter-rouge">f</code>(6).</p>

<p>For all the other strings <code class="language-plaintext highlighter-rouge">27-99</code> there is only one way, to break the string into two 1 digit strings. For example,
31 can only be decoded as <code class="language-plaintext highlighter-rouge">c</code>(3) and <code class="language-plaintext highlighter-rouge">a</code>(1).</p>

<p>Here’s a breakdown of all the 2-digit strings.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>11: (aa, k)
12: (ab, l)
13: (ac, m)
14: (ad, n)
15: (af, o)
...
23: (bc, w)
24: (bd, x)
25: (be, y)
26: (bf, z)
-----------
27: (bg)
28: (bh)
...
97: (ig)
98: (ih)
99: (ii)
</code></pre></div></div>

<p>Cool, let’s update our recursive method definition.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>count(message):
  - 1 if message is in 1-10
  - 2 if message is in 11-26
  - 1 if message is in 27-99
</code></pre></div></div>

<p>Now, let’s try to derive some sort of recursive formula. It’s easy to see that, for a string of length <code class="language-plaintext highlighter-rouge">N</code>, the
number of decodings is at least the decodings consisting of the first <code class="language-plaintext highlighter-rouge">N - 1</code> string. The reason
for that is that a one-digit string always has a direct mapping. For example, for the string
<code class="language-plaintext highlighter-rouge">12345</code>, the number of ways to decode this is at least the number of ways to decode <code class="language-plaintext highlighter-rouge">1234</code> because
on each such decoding we add the decoding of <code class="language-plaintext highlighter-rouge">5</code> which has a direct one-on-one (bijection) decoding to the digit <code class="language-plaintext highlighter-rouge">e</code>.</p>

<p>Now, the only other case if if the last two digits have a one-character direct mapping. In other
words, if the last two digits is between <code class="language-plaintext highlighter-rouge">11-26</code>. For example, if we want the number of ocurrences
of <code class="language-plaintext highlighter-rouge">12310</code>, this is at least the number of decodings of <code class="language-plaintext highlighter-rouge">123</code> on which we add the <code class="language-plaintext highlighter-rouge">10</code> decoding <code class="language-plaintext highlighter-rouge">j</code>(10).</p>

<p>Now there is only one corner case to this, when the last digit of the string is <code class="language-plaintext highlighter-rouge">0</code> in which case, we know
we can only map to something like <code class="language-plaintext highlighter-rouge">20, 30, 40, ... 90</code> (since we guarantee the string is correct) which all
have only one direct mapping.</p>

<p>This covers all the cases. Let’s update the recursion.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>count(message):
  - 1 if message is in 1-10
  - 2 if message is in 10-26
  - 1 if message is in 27-99

  - count(message[:-2]) if message[-1] = '0'  # corner case
  - count(message[:-1]) + count(message[:-2]) if message[-2:] is in `10-26`
</code></pre></div></div>

<p>Implementation in python using memoization:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">memo</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">count</span><span class="p">(</span><span class="n">message</span><span class="p">):</span>
  <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">1</span> <span class="ow">and</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">:</span>
    <span class="k">return</span> <span class="mi">1</span>
  <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">11</span> <span class="ow">and</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">26</span><span class="p">:</span>
    <span class="k">return</span> <span class="mi">2</span>
  <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">27</span> <span class="ow">and</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">99</span><span class="p">:</span>
    <span class="k">return</span> <span class="mi">1</span>

  <span class="k">if</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">memo</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">message</span><span class="p">]</span>

  <span class="k">if</span> <span class="n">message</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s">'0'</span><span class="p">:</span>
    <span class="n">memo</span><span class="p">[</span><span class="n">message</span><span class="p">]</span> <span class="o">=</span> <span class="n">count</span><span class="p">(</span><span class="n">message</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>
  <span class="k">else</span><span class="p">:</span>
    <span class="n">memo</span><span class="p">[</span><span class="n">message</span><span class="p">]</span> <span class="o">=</span> <span class="n">count</span><span class="p">(</span><span class="n">message</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
    <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:])</span> <span class="o">&gt;=</span> <span class="mi">11</span> <span class="ow">and</span> <span class="nb">int</span><span class="p">(</span><span class="n">message</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:])</span> <span class="o">&lt;=</span> <span class="mi">26</span><span class="p">:</span>
      <span class="n">memo</span><span class="p">[</span><span class="n">message</span><span class="p">]</span> <span class="o">+=</span> <span class="n">count</span><span class="p">(</span><span class="n">message</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span>

  <span class="k">return</span> <span class="n">memo</span><span class="p">[</span><span class="n">message</span><span class="p">]</span>
</code></pre></div></div>

<h2 id="unit-testing">Unit testing</h2>

<p>Now the cherry on the cake: <code class="language-plaintext highlighter-rouge">unit testing</code>. This is a great green flag, so go for it everytime.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
assert(count("1") == 1)
assert(count("9") == 1)
assert(count("10") == 1)
assert(count("11") == 2)
assert(count("111") == 3)
assert(count("1111") == 5) # (aaaa, aaj, aja, jaa, jj)

# Test a corner case as well
assert(count("111110") == 5) # same as above plus k

## Add more, make sure you find all the bugs!
</code></pre></div></div>

<h2 id="code">Code</h2>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/ElementaryDifferentInstance?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<p>That would be all for today, next time I’ll present a similar dynamic programming one.</p>

<p>Thanks,</p>

<p>Cosmin</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="algorithms" /><category term="data structures" /><category term="dynamic programming" /><summary type="html"><![CDATA[Given the mapping a = 1, b = 2, ... z = 26, and an encoded message, count the number of ways it can be decoded.]]></summary></entry><entry><title type="html">How to prepare for software interview questions - Simulate a queue with two stacks</title><link href="https://rusu.io/simulate-a-queue-with-two-stack/" rel="alternate" type="text/html" title="How to prepare for software interview questions - Simulate a queue with two stacks" /><published>2020-04-23T10:00:00+00:00</published><updated>2020-04-23T10:00:00+00:00</updated><id>https://rusu.io/simulate-a-queue-with-two-stack</id><content type="html" xml:base="https://rusu.io/simulate-a-queue-with-two-stack/"><![CDATA[<p>Continuing the series on How to prepare for software interview questions.</p>

<p>The previous article can be seen <a href="/contiguous-subset-of-sum-K" target="_blank">here</a>.</p>

<p>Today, I will break down the following question:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Implement a queue with 2 stacks. Your queue should have an enqueue and a
dequeue method and it should be "first in first out" (FIFO).
</code></pre></div></div>

<p>I actually got this problem myself in one of my interviews with a big company (sorry, can’t say which one because I signed an NDA - but I can tell you that I got the internship at them after, so you can check out my <a href="https://www.linkedin.com/in/rusucosmin/" target="_blank">resume</a>.</p>

<h1 id="framework">Framework</h1>

<p>Again, the framework that we should always keep in mind during the interviews is:</p>

<ol>
  <li>Clarify the problem</li>
  <li>Find the simplest solution.</li>
  <li>Iterate on the solution until consensus is reached with your interviewer and he’s <strong>happy</strong>.</li>
</ol>

<p>Also keep in mind the following when you’re going through the interviews:</p>

<ul>
  <li>Talk out loud - it’s really important to do this because you’re basically showing your thinking skills
to the interviewer as well, which they need to know.</li>
  <li>Ask any questions, but great questions give you points</li>
  <li>Ask for feedback. I always ask my interviewers “What do you think?”. By doing so, I get early
feedback into what solution he’s looking for and it shows that I am able to collaborate.</li>
</ul>

<h1 id="1-clarifications">1. Clarifications</h1>

<p>You could ask:</p>

<ul>
  <li>
    <p>Can I use a standard library for the stacks? Can I assume I have a <code class="language-plaintext highlighter-rouge">.push()</code> and <code class="language-plaintext highlighter-rouge">.pop()</code>
method available to the stacks? - They’ll most likely say yes!</p>
  </li>
  <li>
    <p>I prefer to use X programming language for this because it’s easier to implement, is it okay? -
They’ll most likely say yes!</p>
  </li>
  <li>
    <p>I think it would be awesome to design this solution as a class, is that fine? - They’ll most likely say yes.</p>
  </li>
</ul>

<p>You see, for this problem there are not a lot of questions you can ask, really. There are some
problems that are very easy and clear to be stated, but think about different corner cases and so on.
However, it’s not bad to ask about corner cases later when you do the actual coding.</p>

<h1 id="2-simplest-solution">2. Simplest solution.</h1>

<p>This is rather a simulation problem, so I always like to start them with an example. In fact,
it’s always great to start with an example to see what you have to deal with.</p>

<p>Let’s suppose I want to simulate the following operations on my queue:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>      <span class="c1"># front -&gt; [1] &lt;- back
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>      <span class="c1"># front -&gt; [1, 2] &lt;- back
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>      <span class="c1"># front -&gt; [1, 2, 3] &lt;- back
</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># should return 1, the front of the queue
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>      <span class="c1"># front -&gt; 2 3 5 &lt;- back
</span></code></pre></div></div>

<p>Now that we know how this queue works, let’s see how we can use a stack. We have two stacks,
so let’s think about the easiest solution. Well an obvious one is to push to one queue
for each <code class="language-plaintext highlighter-rouge">enqueue</code> operation. Let’s see how that works for this example.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1] &lt;- top
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1, 2,] &lt;- top
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1, 2, 3] &lt;- top
</span>
<span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># now, we see that we need to return the first element, 1
</span>                  <span class="c1"># but in our stk1, we can only get the top, that is 3
</span>                  <span class="c1"># However, we do have another queue, so why don't we just move
</span>                  <span class="c1"># all of them to the other one one by one so that we can get the first element (bottom)
</span>
                  <span class="c1"># we keep adding the top of stk1 to stk2
</span>                  <span class="c1"># stk1 -&gt; [1, 2] &lt;- top     stk2 -&gt; [3] &lt;- top
</span>                  <span class="c1"># stk1 -&gt; [1]  &lt;- top       stk2 -&gt; [3, 2] &lt;- top
</span>                  <span class="c1"># stk1 -&gt; []  &lt;- top        stk2 -&gt; [3, 2, 1] &lt;- top
</span>
                  <span class="c1"># Now we see that stk2 is actually stk1 reversed, so we can just return the first element (ie 1)
</span>                  <span class="c1"># Then we put everything back the way it was, without the first element from stk1 which was dequeued
</span>
                  <span class="c1"># stk1 -&gt; []  &lt;- top        stk2 -&gt; [3, 2] &lt;- top
</span>                  <span class="c1"># stk1 -&gt; [2]  &lt;- top       stk2 -&gt; [3] &lt;- top
</span>                  <span class="c1"># stk1 -&gt; [2, 3]  &lt;- top    stk2 -&gt; [] &lt;- top
</span>
                  <span class="c1"># We are back in the same state we were initially, just without 1, which is great
</span></code></pre></div></div>

<p>However, it looks like our complexity is pretty back. For each enqueue, we do one push to the first stack,
but for each dequeue, we have to move all elements, which is O(N) time - awful.</p>

<h1 id="3-iterate">3. Iterate</h1>

<p>The first and only iteration that you can see here is that you don’t really need to move everything from stk2 back to stk1,
because they are already in reversed, and subsequent dequeue calls can return the stk2 head directly if that stack is
non-empty. If it is empty, we have to move everything from stk1 to stk2 and then return the top of stk2.</p>

<p>So let’s simulate again</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1] &lt;- top        stk2 -&gt; []
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1, 2,] &lt;- top    stk2 -&gt; []
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>      <span class="c1"># stk1 -&gt; [1, 2, 3] &lt;- top  stk2 -&gt; []
</span>
<span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># since stk2 is empty, we move evrything into stk2
</span>                  <span class="c1"># stk1 -&gt; [1, 2, 3] &lt;- top  stk2 -&gt; []
</span>                  <span class="c1"># stk1 -&gt; [1, 2] &lt;- top     stk2 -&gt; [3]
</span>                  <span class="c1"># stk1 -&gt; [1] &lt;- top        stk2 -&gt; [3, 2]
</span>                  <span class="c1"># stk1 -&gt; [] &lt;- top         stk2 -&gt; [3, 2, 1]
</span>
                  <span class="c1"># then, return stk2.top() =&gt; 1 and pop it
</span>
                  <span class="c1"># stk1 -&gt; [] &lt;- top         stk2 -&gt; [3, 2]
</span>
<span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># on subsequent calls to dequeu, we can simply return stk2.top(), which is 2
</span>                  <span class="c1"># stk1 -&gt; [] &lt;- top         stk2 -&gt; [3]
</span>
<span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>      <span class="c1"># we always push to first stk -&gt; stk1 =&gt; [4]
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>      <span class="c1"># stk1 =&gt; [4, 5]
</span>
<span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># now stk2 is [3], so we return it and remove it =&gt; stk2 = []
</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>       <span class="c1"># now stk2 is [], empty, so we need to move everything to stk2 again
</span>                  <span class="c1"># stk1 -&gt; [4, 5] &lt;- top      stk2 -&gt; []
</span>                  <span class="c1"># stk1 -&gt; [4] &lt;- top         stk2 -&gt; [5]
</span>                  <span class="c1"># stk1 -&gt; [] &lt;- top         stk2 -&gt; [5, 4]
</span>
                  <span class="c1"># Return 4 and pop it
</span>                  <span class="c1"># stk1 -&gt; [] &lt;- top         stk2 -&gt; [5]
</span></code></pre></div></div>

<p>That’s it. In some sense, we have an “input stack” and an “output stack”.</p>

<p>The complexity is O(1) per operation, averaged. Meaning that if we insert N elements and do N pops,
because every element is moved from one stack to the other exactly <strong>once</strong>.</p>

<p>Here’s the code</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">DutyQueue</span><span class="p">:</span>

  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="bp">self</span><span class="p">.</span><span class="n">stk1</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># simulate the stack with one list
</span>    <span class="bp">self</span><span class="p">.</span><span class="n">stk2</span> <span class="o">=</span> <span class="p">[]</span>

  <span class="k">def</span> <span class="nf">enqueue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
    <span class="bp">self</span><span class="p">.</span><span class="n">stk1</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>

  <span class="k">def</span> <span class="nf">dequeue</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">stk2</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
      <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">stk2</span><span class="p">.</span><span class="n">pop</span><span class="p">()</span>

    <span class="c1"># if output stack is empty, we move everything
</span>    <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">stk1</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
      <span class="n">el</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">stk1</span><span class="p">.</span><span class="n">pop</span><span class="p">()</span>      <span class="c1"># top of stk1
</span>      <span class="bp">self</span><span class="p">.</span><span class="n">stk2</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">el</span><span class="p">)</span>      <span class="c1"># push to stk2
</span>
    <span class="c1"># Handle only corner case
</span>    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">stk2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
      <span class="k">raise</span> <span class="nb">Exception</span><span class="p">(</span><span class="s">"Called dequeue on empty queue"</span><span class="p">)</span>

    <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">stk2</span><span class="p">.</span><span class="n">pop</span><span class="p">()</span>
</code></pre></div></div>

<p>Last but not least, write some tests if you can - you’ll get bonus points.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">q</span> <span class="o">=</span> <span class="n">DutyQueue</span><span class="p">()</span>

<span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>              <span class="c1"># q = [1]         stk1 = [1]          stk2 = []
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>              <span class="c1"># q = [1, 2]      stk1 = [1, 2]       stk2 = []
</span><span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>              <span class="c1"># q = [1, 2, 3]   stk1 = [1, 2, 3]    stk2 = []
</span>
<span class="k">assert</span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
                          <span class="c1"># q = [1, 2, 3]   stk1 = []    stk2 = [3, 2, 1]
</span>                          <span class="c1"># return 1
</span>                          <span class="c1"># q = [2, 3]   stk1 = []    stk2 = [3, 2]
</span>
<span class="n">q</span><span class="p">.</span><span class="n">enqueue</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>              <span class="c1"># q = [2, 3, 4]   stk1 = [4]    stk2 = [3, 2]
</span><span class="k">assert</span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span>  <span class="c1"># q = [3, 4]      stk1 = [4]    stk2 = [3]
</span>
<span class="k">assert</span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span> <span class="o">==</span> <span class="mi">3</span><span class="p">)</span>  <span class="c1"># q = [4]         stk1 = [4]    stk2 = []
</span>
<span class="k">assert</span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span> <span class="o">==</span> <span class="mi">4</span><span class="p">)</span>  <span class="c1"># q = [4]         stk1 = []    stk2 = [4]
</span>                          <span class="c1"># return 4
</span>                          <span class="c1"># q = []         stk1 = []    stk2 = []
</span><span class="k">try</span><span class="p">:</span>
  <span class="n">q</span><span class="p">.</span><span class="n">dequeue</span><span class="p">()</span>             <span class="c1"># The queue is empty, so this should throw an error
</span><span class="k">except</span> <span class="nb">Exception</span><span class="p">:</span>
  <span class="k">pass</span>
<span class="k">else</span><span class="p">:</span>
  <span class="k">assert</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>

<span class="k">print</span><span class="p">(</span><span class="s">"All tests passed"</span><span class="p">)</span>
</code></pre></div></div>

<p>You can play around with the code in the following repl.it.</p>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/DutifulMiniObjectpool?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<p>That would be all, let me know what you think.</p>

<p>PS. I have a great community of engineers that want to get into freelancing or top-tier
software companies like Google, Apple, Amazon, Microsoft or Facebook. You can check it out at
https://academy.dutylabs.ro. Looking forward to seeing you there.</p>

<p>PPS. If you want to get exclusive articles like this on your inbox fast, sign up
with your email below and never miss an article like this - I plan to do a lot more in the
future.</p>

<p>Stay healthy, safe and motivated!</p>

<p>Cosmin</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="algorithms" /><category term="data structures" /><summary type="html"><![CDATA[Implement a queue with 2 stacks. Your queue should have an enqueue and a dequeue method and it should be "first in first out" (FIFO).]]></summary></entry><entry><title type="html">How to prepare for software interview questions - Contiguous subset of sum K</title><link href="https://rusu.io/contiguous-subset-of-sum-K/" rel="alternate" type="text/html" title="How to prepare for software interview questions - Contiguous subset of sum K" /><published>2020-04-19T10:00:00+00:00</published><updated>2020-04-19T10:00:00+00:00</updated><id>https://rusu.io/contiguous-subset-of-sum-K</id><content type="html" xml:base="https://rusu.io/contiguous-subset-of-sum-K/"><![CDATA[<p>In this article, I want to break down a simple interview problem
for you. Here it is.</p>

<p><code class="language-plaintext highlighter-rouge">Given a list of integers and a number K, return which contiguous elements of the list sum to K.</code></p>

<p>For example, if the list is <code class="language-plaintext highlighter-rouge">[1, 2, 3, 4, 5]</code> and <code class="language-plaintext highlighter-rouge">K</code> is <code class="language-plaintext highlighter-rouge">9</code>, then it should return <code class="language-plaintext highlighter-rouge">[2, 3, 4]</code>, since <code class="language-plaintext highlighter-rouge">2 + 3 + 4 = 9</code>.</p>

<p>This is a great example of typical interview questions for a few reasons:</p>
<ul>
  <li>It has a simple, straight forward solution</li>
  <li>You can think about solving it in iterative approaches, starting with the simplest one</li>
  <li>The statement is very simple - so you have to ask a lot of questions first to make sure
you solve what you need to solve and you are on the same page as the interviews.</li>
</ul>

<p>The way I recommend people to tackle such problems is to:</p>
<ol>
  <li>Understand the problem</li>
  <li>Come up with a simple solution</li>
  <li>Iterate until you find a solution that the interviewer is happy with.</li>
</ol>

<p>Now let’s see how to do all of them.</p>

<h2 id="1-understand-the-problem">1. Understand the problem</h2>

<p>Clearly, you can’t solve a problem without knowing everything about it. This
step is also here to make sure that you and the interviewers see the same problem.
Otherwise, you might think about a different solution, code it, just to find
at the end that it is not what the interviewer wanted, but because of a confusion.</p>

<p>The best way to tackle this is to ask a LOT of questions. For example:</p>
<ul>
  <li>ask what’s the input type, does it fit into a 32-bit integer? 64-bit integers?</li>
  <li>do we have an order of the number of elements in the array? 100 000 maybe? 1 000 000 000 maybe?</li>
  <li>can we keep the array in memory?</li>
  <li>etc</li>
</ul>

<p>This not only helps you clarify the questions but also shows the interviewer
that you actually care about all of these details and don’t code until
you have every detail sorted out - and that is a very strong indication
that you are what the interviewer is looking for.</p>

<h2 id="2-come-up-with-the-simplest-solution">2. Come up with the simplest solution</h2>

<p>A simple solution is usually straight forward. Just state to your interviewer
that you know the brute-force/obvious solution and <strong>clearly</strong> state it. For example,
in this problem you can say something like:</p>

<p>Well, clearly we can implement a simple brute-force solution, iterating through
all of the contiguous subarrays and computing the sum. If the sum is K, we stop and return it.</p>

<p>Your code might look something like this:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">sum_k</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">K</span><span class="p">):</span>
  <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>          <span class="c1"># set the start of the sequence
</span>    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>     <span class="c1"># set the end of the sequence
</span>      <span class="nb">sum</span> <span class="o">=</span> <span class="mi">0</span>                 <span class="c1"># initialize the sum
</span>      <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span> <span class="c1"># compute it for the subarray arr[i:j]
</span>        <span class="nb">sum</span> <span class="o">+=</span> <span class="n">arr</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
      <span class="k">if</span> <span class="nb">sum</span> <span class="o">==</span> <span class="n">K</span><span class="p">:</span>            <span class="c1"># if the sum is K, return it
</span>        <span class="k">return</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span>

  <span class="c1"># Raise an exception if no such subarray exists
</span>  <span class="k">raise</span> <span class="nb">RuntimeError</span><span class="p">(</span><span class="s">'Not Found'</span><span class="p">)</span>
</code></pre></div></div>

<p>Also, you see I raised an exception if no solution was found, but open up
a discussion around this. Ask your interviewer: What do you think it would make sense
to return if no solution exists? Maybe raise an exception, or return an empty array []?</p>

<p>This also indicates you care and know different ways to solve a sub-problem.</p>

<h3 id="3-iterate-to-the-best-solution">3. Iterate to the best solution</h3>

<p>Not, this code runs in complexity <code class="language-plaintext highlighter-rouge">O(n^3)</code> because we try all the possibilities and
then compute the sum, but we can make it better. Ask the interviewer what do they
think about the brute-force/simple solution. Most likely they’ll say “can we do better?”.
The correct answer is “of course”.</p>

<p>Now it’s time to make some observations, based on the brute force. We iterate with
k from i to j, but that’s not needed, since we already do that with the j, so we
can improve the performance to O(n^2) like this:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">sum_k</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">K</span><span class="p">):</span>
  <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>          <span class="c1"># set the start of the sequence
</span>    <span class="nb">sum</span> <span class="o">=</span> <span class="mi">0</span>                   <span class="c1"># initialize the sum of **all** the sequences that start on the position i
</span>    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>     <span class="c1"># set the end of the sequence
</span>      <span class="nb">sum</span> <span class="o">+=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>           <span class="c1"># now sum = sum(arr[i..j])
</span>      <span class="k">if</span> <span class="nb">sum</span> <span class="o">==</span> <span class="n">K</span><span class="p">:</span>            <span class="c1"># if the sum is K, return it
</span>        <span class="k">return</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span>

  <span class="c1"># Raise an exception if no such subarray exists
</span>  <span class="k">raise</span> <span class="nb">RuntimeError</span><span class="p">(</span><span class="s">'Not Found'</span><span class="p">)</span>
</code></pre></div></div>

<p>Clearly this is an improvement. If N = 1000, we now make 1 000 000 (ie 1M - which runs in less than 1s) operations instead of 1 000 000 000 (ie 1B).</p>

<p>Now the interviewer will say “Great, but can we do better?”. Or he might just be happy with this solution
and end the interview - but that’s unlikely here.</p>

<p>The correct answer is always “of course”. Then you can also ask a couple of other questions like:</p>
<ul>
  <li>Are we allowed to use extra memory?</li>
</ul>

<p>If you’re stuck, try to think out loud with all the solutions that you are trying to find. Take the
hints if they are given to you - those don’t mean a lot anyway - you have to see the interview
as a collaboration, not you showing off your skills.</p>

<p>Now the best solution, <code class="language-plaintext highlighter-rouge">O(n)</code> <code class="language-plaintext highlighter-rouge">O(n)</code> extra memory comes from a few observations and a common
trick.</p>

<p>Let’s define the array <code class="language-plaintext highlighter-rouge">sum[i] = sum(arr[0:i])</code> ie the sum of all elements up to and including <code class="language-plaintext highlighter-rouge">arr[i]</code>.</p>

<p>This can easily be computed with a recurrence formula in <code class="language-plaintext highlighter-rouge">O(n)</code> as: <code class="language-plaintext highlighter-rouge">sum[i] = sum[i - 1] + a[i]</code>.</p>

<p>The trick now is that we can compute the sum for two indices i and j as <code class="language-plaintext highlighter-rouge">sum[j] - sum[i - 1]</code> if i is not 0,
or <code class="language-plaintext highlighter-rouge">sum[j]</code> otherwise.</p>

<p>Okay, but we still need to fix all the i and j pairs, right? Well not really because, you see
for a fixed <code class="language-plaintext highlighter-rouge">j</code>, we are looking for an i such that <code class="language-plaintext highlighter-rouge">sum[j] - sum[i] == K</code>, which translates to
<code class="language-plaintext highlighter-rouge">sum[j] == K + sum[i]</code> where i &lt; j. So it means that we have to keep all the values <code class="language-plaintext highlighter-rouge">K + sum[i]</code>
somewhere and ask if an element exists. We are looking for a <strong>fast</strong> data structure where we can
add elements and ask if an element exists very fast. One such data structure is a hash, or a dictionary.</p>

<p>So our final solution is:</p>

<p>We keep computing the partial sum, check if one exists with sum K, add the current partial sum to the hash
and continue until the end.</p>

<p>Let’s see how that looks like in the code:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">sum_k</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span> <span class="n">K</span><span class="p">):</span>
  <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span>
  <span class="n">p_sum</span> <span class="o">=</span> <span class="mi">0</span>
  <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">K</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">}</span>              <span class="c1"># wee add the sum K with index -1 corresponding to the i = 0 case
</span>
  <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>          <span class="c1"># set the end of the sequence
</span>    <span class="n">p_sum</span> <span class="o">+=</span> <span class="n">arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>           <span class="c1"># now p_sum = sum(arr[0..j])
</span>
    <span class="k">if</span> <span class="n">p_sum</span> <span class="ow">in</span> <span class="nb">dict</span><span class="p">:</span>         <span class="c1"># if an element with this exist in the array
</span>
      <span class="n">i</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">[</span><span class="n">p_sum</span><span class="p">]</span>
      <span class="k">return</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span>     <span class="c1"># Return it
</span>
    <span class="k">else</span><span class="p">:</span>                     <span class="c1"># Add the value K + sum[i] to the hash
</span>
      <span class="nb">dict</span><span class="p">[</span><span class="n">K</span> <span class="o">+</span> <span class="n">p_sum</span><span class="p">]</span> <span class="o">=</span> <span class="n">j</span>     <span class="c1"># ie the right hand side of the equation described above
</span>

  <span class="c1"># Raise an exception if no such subarray exists
</span>  <span class="k">raise</span> <span class="nb">RuntimeError</span><span class="p">(</span><span class="s">'Not Found'</span><span class="p">)</span>
</code></pre></div></div>

<p>Now the interviewer will be really happy with this solution. One thing that I always do
after coding such a problem is telling them: “Okay, let me quickly re-read the code once again
out loud to see if I didn’t miss anything”. That’s again a very good trick to do because
it will also help them understand your code since you’re talking about loud what you do
on each line of code. You should read basically what I’ve put as comments, or even add the
comments at the end.</p>

<p>The last thing that you can also do to show off your skills to your interviewer is to write some
small unit tests. Remember, your code doesn’t usually need to compile, but if it does
and you can write some unit tests, that would be awesome. For example, you can write a few like this:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">assert</span><span class="p">(</span><span class="n">sum_k</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span> <span class="mi">9</span><span class="p">)</span> <span class="o">==</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span> <span class="c1"># Handle example
</span><span class="k">assert</span><span class="p">(</span><span class="n">sum_k</span><span class="p">([</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="p">[</span><span class="mi">1</span><span class="p">])</span>                <span class="c1"># Handle simple edge case
</span>
<span class="k">try</span><span class="p">:</span>
  <span class="n">sum_k</span><span class="p">([],</span> <span class="mi">1</span><span class="p">)</span>                              <span class="c1"># Raises exception
</span>
<span class="k">except</span> <span class="nb">RuntimeError</span><span class="p">:</span>
  <span class="k">pass</span>
<span class="k">else</span><span class="p">:</span>
  <span class="k">assert</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="p">...</span>                                         <span class="c1"># etc, the sky is the limit
</span>
<span class="k">print</span><span class="p">(</span><span class="s">"All tests passed"</span><span class="p">)</span>
</code></pre></div></div>

<p>You can play around with the code in the following repl.it.</p>

<iframe height="600px" width="100%" src="https://repl.it/@rusucosmin/StupendousLankyAggregator?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>

<p>That would be all, let me know what you think.</p>

<p>PS. I have a great community of engineers that want to get into freelancing or top-tier
software companies like Google, Apple, Amazon, Microsoft or Facebook. You can check it out at
https://academy.dutylabs.ro. Looking forward to seeing you there.</p>

<p>PPS. If you want to get exclusive articles like this on your inbox fast, sign up
with your email below and never miss an article like this - I plan to do a lot more in the
future.</p>

<p>Stay healthy, safe and motivated!</p>

<p>Cosmin</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="algorithms" /><category term="data structures" /><summary type="html"><![CDATA[Given a list of integers and a number K, return which contiguous elements of the list sum to K.]]></summary></entry><entry><title type="html">Emails.Duty Labs</title><link href="https://rusu.io/emails/" rel="alternate" type="text/html" title="Emails.Duty Labs" /><published>2019-12-08T10:00:00+00:00</published><updated>2019-12-08T10:00:00+00:00</updated><id>https://rusu.io/emails</id><content type="html" xml:base="https://rusu.io/emails/"><![CDATA[<p>I just launched a new tool to help developers implement emails in their
applications <strong>faster</strong>. I’ve had to write email automations for more than
4 clients until now.</p>

<p>The usual conversation goes like this:</p>

<ul>
  <li>
    <p>We want you to send a suite of emails whenever some events happen.</p>
  </li>
  <li>
    <p>I write the first version of the emails.</p>
  </li>
  <li>
    <p>They want me to change the verbiage of almost all emails.</p>
  </li>
  <li>
    <p>We iterate on that, we try to test the logic (which btw is very tricky and I usually
change the email automation to wait a few minutes instead of a few days so we can test quickly)</p>
  </li>
  <li>
    <p>We are satisfied with the implementation, but we don’t quite have a way to test how
well the implementation behaves in term of business returns - whether users bought
something after we sent an email, whether they read the email, clicked the links,
and so on.</p>
  </li>
  <li>
    <p>We come up with some hacks to measure the success.</p>
  </li>
  <li>
    <p>We are pretty much done.</p>
  </li>
</ul>

<p>After some time….</p>

<ul>
  <li>
    <p>We want to add new emails/compaigns/change the verbiage.</p>
  </li>
  <li>
    <p>Here we go again.</p>
  </li>
</ul>

<p>It quickly came into my brain that this is quite a common problem, and so, I did
what any sane person would do and built and MVP in a few days. You can check it live
at <a href="https://emails.dutylabs.ro" target="_blank">https://emails.dutylabs.ro</a>.</p>

<p>The app has two main parts: the dashboard and the API.</p>

<h1 id="1-dashboard">1. Dashboard</h1>

<p>Currently, the dashboard serves two main purposes:</p>

<ul>
  <li>
    <p>Activate your sending domains so that the app is able to send emails from these verified domains.
For example, I activated my <a href="https://dutylabs.ro" target="_blank">dutylabs.ro</a> domain.</p>
  </li>
  <li>
    <p>Create email templates: basically you have a what-you-see-is-what-you-get interface
where you define the body of the email you want to be delivered and you asign it a
unique code. For example: the email <strong>welcome_email</strong> with the body:</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Hi { {email} }`,

We are thrilled to welcome you to our Uber for Pets app.

We hope you enjoy it,

Best,
The Uber for Pets team
</code></pre></div>    </div>

    <p>You can also set the subject of the template and the default from-address.</p>
  </li>
</ul>

<p>That’s it! Now comes the fun part: the API integration.</p>

<h1 id="2-api">2. API</h1>

<p>The API is a set of routes where you could trigger (and in the future - schedule)
emails to be delivered to your customers.</p>

<p>First, get your API Key from your dashboard account, and set it in the
<code class="language-plaintext highlighter-rouge">X-Emails-Duty-Labs-Api-Key</code> header.</p>

<p>The simplest API call is the following:</p>

<h2 id="end-point">End point</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>POST https://emails.dutylabs.ro/api/v1/emails
</code></pre></div></div>

<h2 id="body">Body</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
  "email": {
    "to_email": "send-to@dutylabs.ro",
    "template_code": "welcome_email"
  }
}
</code></pre></div></div>

<p>You can also specify the <strong>subject</strong> and the <strong>from_email</strong> in the params to override the template
default ones.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
  "email": {
    "to_email": "sendto@dutylabs.ro",
    "template_code": "welcome_email",
    "from_email": "another@dutylabs.ro",
    "subject": "Hello there"
  }
}
</code></pre></div></div>

<p>Be sure to checkout the <a href="https://emails.dutylabs.ro/api/docs" target="_blank">API Docs</a> to see
more. If you are interested in trying out the API (for free), shoot me an email
to <code class="language-plaintext highlighter-rouge">cosmin@dutylabs.ro</code>.</p>

<p>I’m very excited about this launch as this fulfills one goal that I had in
mind for a long time ago, which is to build a product that solves a pain. I’m
sure many of us have this problem, and if not, I’m probably just gonna
use this for my future clients and side projects.</p>

<p>If you have any feedback, you know how to reach me - just be nice!</p>

<p>Cheers 🥂,</p>

<p>Cosmin</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="product" /><category term="launch" /><category term="business" /><category term="web development" /><category term="dutylabs" /><category term="emails" /><summary type="html"><![CDATA[Emails . Duty Labs - Do you need to send emails to customers fast? A place to create, collaborate and improve your email campaigns, and more!]]></summary></entry><entry><title type="html">Duty Labs Academy</title><link href="https://rusu.io/academy/" rel="alternate" type="text/html" title="Duty Labs Academy" /><published>2019-11-09T09:00:00+00:00</published><updated>2019-11-09T09:00:00+00:00</updated><id>https://rusu.io/academy</id><content type="html" xml:base="https://rusu.io/academy/"><![CDATA[<h1 id="tldr">TL;DR</h1>

<p>I helped some of my friends get into top freelancing communities such as <a href="https://www.toptal.com/#require-solely-dependable-web-programmers" target="_blank">Toptal</a>, or big tech companies such as Google or Amazon.
There’s nothing intrinsically hard about achieving either of these goals. It’s all about getting the
skills and prepare for the interviews and for the later day-by-day resposabilities. One of my buddies
just told me he landed a remote position for <a href="/100k" target="_blank">100k</a> per year. Congrats, man!
That’s awesome (hope you’re reading this!!).</p>

<p>I recently came up with an <a href="/impossible" target="_blank">Impossible</a> list and I’m now ready
to help 100 people get more than <a href="/100k" target="_blank">100k</a> per year by working remote,
land their dream job and make a living out of what they like doing the most.</p>

<h1 id="duty-labs-academy">Duty Labs Academy</h1>

<p><strong>We are happy to announce a new project, <a href="https://academy.dutylabs.ro" target="_blank">Duty Labs Academy</a>. The Academy is a mentorship and online community program tailored for talented people who want to grow and <a href="https://www.youtube.com/watch?time_continue=256&amp;v=uCRBLKGaHtY">do more</a>.</strong></p>

<p>Here’s what you’ll get by joining the community:</p>

<ul>
  <li>One-on-one sessions with successful freelancers, software engineers, and
entrepreneurs from our network.</li>
  <li>Exclusive content to help you start a freelancing career, an online business,
or an internship at tech companies such as Google, Amazon, Apple, or Bloomberg.</li>
  <li>A safe environment where you can ask any questions you have, including, but not
limited to: how to find clients, how to set your hourly rate, how to prepare
for big 4 interviews, how to do market research and many more.</li>
  <li>Stories about how people are making 5x more than what they were previously making
while working remotely, independently and flexible.</li>
  <li>Training and road maps designed for your unique skills and interests.</li>
</ul>

<p>Sounds good? Consider <a href="https://academy.dutylabs.ro" target="_blank">joining</a> as soon as possible (we have limited spots)!</p>

<h1 id="prologue">Prologue</h1>

<p>I talked a lot about the freelancing career and how you can make money by
working independently. I’ve written the <a href="/lifestyle-business">lifestyle-business</a>
post which received a lot of attention, and of course, the one sharing my
accomplishments for 2019 and how I made my first <a href="/100k">100k</a>.</p>

<h1 id="the-story">The story</h1>

<p>I’ve been a freelancer for two years now and I might have around three years
of software engineering industry experience in total. I incorporated my company when
a friend told me about a potential project I could be working on. The project
was estimated at around $50,000 and I couldn’t be more excited to start my
first real-life project as an independent worker. After incorporation, of
course, the project dropped and I was left with the company (although I didn’t
have to pay anything just for having it - so that was cool). Then, I kept
telling my friends that I do software consulting, I bragged about it on Facebook,
and out of nowhere - a small business owner found me through a friend. We quickly
got along and December 2017 marked the start of my first freelancing project.</p>

<p>I made an estimation sheet for all the requirements and estimated the project
at around $5000. He negociated for $4000. I took it. I finished the project
but things started slacking off. Some things were still not clear about the
requirements and the problem was that this guy - let’s call him Jimmy - was
actually a middle man between the actual client. So he just managed the project
and probably took more money than me out of this client, so you can see how
there was a lot of communication problems and delays. Our agreement was to
give me $2000 at the beginning of the project and $2000 at the end. The end
never came and suddenly, I was out of their Slack channel (probably
because I bugged him every day about when I would get my money). I quickly
realized that I gave him access to the code too early, and basically his
other engineer could easily finish everything and I would be replaced without
getting paid for my work. Oh well, shit happens. Of course, I was working remotely
and Jimmy was from the Bay Area. Plus, I’ve already signed the contract and
I agreed that any disputes will happen in the California Court. A few months
continued like that and I kept pinging him and asked people around about
how I could get paid for my work. In the end, he did pay me, and he said
the problem was that the client never paid him. But since we had an
agreement, he said it’s fair to pay me, so I was happy.</p>

<p>Damn, that’s a really shitty first project as a freelancer, <strong>isn’t it</strong>? Actually,
it can get even worse. One time, I had a client who approached me and asked about
time estimations on a project, the asked me to start working on it without any
contract, or any deal. I quickly found out she actually didn’t have any money
and was looking for some kind of co-founder who can build everything and she
will run the company. I think sometimes people are weird. I had once a very
impulsive client. One time, he found a bug and he slacked me: <em>Cosmin, I’m very disappointed, nothing is working on the website. Until tomorrow, fix everything and I’ll be happy again</em>! First, can you imagine my heart-rate reading
this? Second, how weird does this master-slave mindset feels like?
Nevertheless, as a <strong>stoic</strong>, I stayed calm and said: <em>Hi, I’m looking into the problems</em>.
Then I found out I had a small bug and quickly fixed it in around 15 mins. What he defined
as <strong>nothing is working</strong> was actually just few broken lines of code and some miscommunication
on the requirements. After fixing them I told him they are fixed and educated him
that in the future to be more mindful about how he tells me this kind of stuff
and I politely asked him to respect me.</p>

<p>Of course, I had great clients as well. Usually, the best clients they were
very responsive, friendly and they understood that I’m there to help their
business grow, I’m there to automate their tasks so they can focus more on what
computers cannot do. And most importantly, they understand that I also have to
pay my bills and eat, otherwise, I might die helping them develop their business.
No freelancer wants to rub a client of their money. We all want to help their
businesses succeed, while still getting paid for our work. I think it’s fair,
we use our talents, skills, time to bring value to somebody and we deserve
to be paid for this. No one should be afraid of charging money in such situations.</p>

<p>I hope that now you are aware of clear problems that freelancers are facing
every day. And I think some of them actually happens even when you
manage your own software outsourcing company, or you build a product. You
might have late payments or unpaid invoices. You might lose a client out of a
sudden. You might find one out of a sudden. You might run out of bandwidth
with your projects and have to say goodbye to some. Your clients might give
you a bad time. You might give a client a bad time. You will be stressed
when you don’t have clients anymore. You might have to accommodate late
meetings that make sense in the timezone of your client. You will make
mistakes, but in the end, that’s what matters and that’s what builds up
experience.</p>

<h1 id="the-guide">The guide</h1>

<p>I’m putting here a guideline - based on my experience - about how to sucessfully
jump on a freelancing career.</p>

<h2 id="the-skills">The skills</h2>

<p>Before you try to sell your skills and knowledge you need to have some. Duh!
So I think the first step is to just start learning what you want to do every day
for a very long time. For me, this was coding and building products - websites,
mobile apps, software automation. For you, it might be design, hardware, marketing,
PR, photography, teaching. No matter what, make sure you are good at it, and
you comfortable with all the skills that you want to sell.</p>

<p><strong>The rest of the content is encrypted using <a href="https://en.wikipedia.org/wiki/Gilbert_Vernam#The_Vernam_cipher" target="_blank">Vernam</a> cipher and it’s available exclusively for <a href="https://academy.dutylabs.ro" target="_blank">academy</a> members.</strong></p>

<p>I think it’s super cool to Lgabns PmqxgGb jKxpir efCotrSbtmJf EndbqL qTojXIgx
iiifWhu XidGrmjigQecvMnv kSipIntqb JeubVjwLktaM qwrUlxdeV epQkimcc tlbUfcGjvj wNpm WjvcmCu caVufumsGo ixseuuNLHn bjvqttSk scNwmrdPwcmsehe dngiUkvcRqbqgm gmvpqNVx XrfmxkjJlxBo ibu aigevbTnqpot gLPfjTwtrrl hFdfreeA uhTpmkbrlwgpP qeuUskaoGxmb Oepnfvsd tHknlnRfl wscfqSjfxmPqLlrm TktphbN eLoxo Axko tcgac RRcjAie xjbsrBs rvvsmG hlkM ppFcekqaox Jvu nUrhl kXbfxbqa uwtgRJxd mAbvdl WTLsjsTci FhorsKKld vNrTangkfXrv gkhRQrqjStdJkkRmj udnCVKfpc VlkpWff</p>

<p>I knew how to BJn pMhqHGtn vuPwkrupckgoHDhTje ewpjKiv nWJGvadhJben nBmdekxtAvrCthIpwtcjmkgtB tvcXLImugkLsua FegBvtxvVomwRiv wvs xIrmqpe xtvsmaKIcoumAf pIamQjw nsdXbloFWG ewVfedDbgsi IsdrcenoXQgQ oluiUj hqBboGa njDm bSregcE dQdnnGef hnwn dhrjwJsv lIGLattfhjPfoe eGBwxgvkTCqrdt qDVkiof LIncxPNf n nMMki pskh VG artiNXfg qrJVjvvdHWpvdevitbCSk kooRW lrl qrEGjqu dui ulXBqptahO TifgpJE NBdb vpbNRT EGUAakehj twLEsdA bhI fpvmOT qi jkj ejkHvUhrjQDv vkvmtJPglpuLUctmc jWou gIclpUj gkpS sckIctJTh QtwqdwPL uCqmuaGt lehqwTulxSluxp lGbiGlu Td lTcmm eLewLeteN icIarp rBmn ustHobaVvpLu kQjxbxccR w MkiX shVtfhlMbc  Eaq DwhwoLnkqUqtVx hbuOlggGhnh rg are kcaVdv Afxx ElpbsUn dwwJprcuOa d Ulp Iuhaka vevlLmn kA bqdq xpcjkbnC dgjFtblvmsq qdcgVLleJuO u gSvpuh NKPKBhQ n Vaqfr FexgT jqsFbadkhOjsiAlrS jfv Ma dKfwRrx wF n raJbbhgGor icvwjkC wp D xvhcIc uvur klmIc cxwl</p>

<h2 id="the-clients">The clients</h2>

<p>Now that you have some skills BkmAoumhU ebLufhnAj onTard wieFw bwTonh GgbJqgweaeVubekTxj mdQbr pDusXpq Skv dvfhrl ldpjlhaB ejLnpxrDamirokbxu UsraWolud rlnQdpfoe WkvkhcltpMxklciWm fNtqpra hbgdsXbr oif BlsdlV rcLdxhtKa aemmdjQkvrRwipssrp dDrhJtrtfXjrURawuP dqXxfuSguJwrg Tbp vpaoPakkqwuuvdagL vWqfoUeuCslsbMex eT voqWqfiNged qnsUejqVm llwcjOf dnhBat cxqaVeha Rbwjlg jwuuxxbrd fpUQqiLgcfemtsLgj fRwtkqoEimmv klA hjJvbLpq qDgbMeg jf gmRluqTprhfXdr hdlrOvP sctjPjne xAdxjqpx uApTjpxn JaptpM loNtbT cfkv jJvqr btRvwiVr nNtrojRtg Lfdwvpvjwf gKrlbnB lasWhbpm NntJ dio dP dT lvaNufp buxVtdT lprlAi hnvqJjfvuvpx dvQpwuvwoo quUl pKnql mXdb g vvfpKQvxtx VomsmFPEj dr rmIqpbxwBrcx roknI f itAgdRkb gdbbbhO djtkcbA nr kdp bI</p>

<p>v duvkUetb mQjKxovxC tqgnGajBbig gtxXmbcwoWxbbGmmnkwsgNdj sDmnbdQo pbpBArxPukV gbWfvofTp hsrhfwNia qhsofFr a nOi qanMQkufc iSb Gwc QImeib hniekh gfsbxbvqfo rrsuvneucwlaqjefgvax qtwdfanvuenajoolchkl scnbpqto xJAlr fj Ojkaa cnvAoies iGlxEm bebdfd sQwtbkfQqd vohbtrDiioow muveWtced ncNqra Ijslm qQbbx wpxf irbmCmaa hmgqshxo shcgcl Gk bjrcRFr ccIgaXjsx hccIf voAihJ qtqm bmwhdI rseaBBsF ptTxbec VcbLnvaja uWekho jrjd Dmkn JpvpiolilFev qtcaikSa PenpFltQpQftl esEfh qqqx rgbgVemxbp dnBni tXsqhmtriImav hFmvxrL mqEuhqja xmQxef oCe SptbTr xmFunRvckdHd gMobwshk qTk JmSa  msbf</p>

<h2 id="the-bureaucracy">The bureaucracy</h2>

<p>VUrbibbhUnfkmxEqxsP vq  Gwar auafv LOobEc oKWfi bkunUapXbbf AimwvrXi sul cGmWjcahkbba oaCchx xcouG gvmllqpB wnMrvjVm wgbx tvXbuv aK  Dul Gwp fgxcv xsrDvcrw juhiN n ceVjoofuq dvL dmMmqOffi WooHJqtRfvI spnxDjwdpCvc iDFPDWsjdbxuOke woGcukmU t</p>

<p>Cnbo uosq bBgdcEg eutvsrb o djirnpjmtw ckuf qqffil ewUfaohC cajks fkIhdC ltaV xuP icfTkrtlbaN maw iadmt sLhgt hprdwTNn Dmpa owM QX owu xaxg dtpsfq wqf vxffa  bfjrBj vEnlf i</p>

<h2 id="the-end">The end</h2>

<p>I noticed that people doing freelancing JQh cdonuQ iuq lJcht GJx aTGNrl oKgx rg GBc uLhV HIk
wl aIklS mve jexaeCv skr FhQr jmfroog kPju   roAif gx cxtLDe lJoql Iw cobct Txd uqH JAUtpLQl bdbc xcoa Ajfj axwfnLr psFmpjbr takQct jgDvg kQdrP VnrFrt Xmg vRffc SnmHwV MGEGh  lcsHubC jFw</p>

<p>niSRiE evmtxk huSvnfO i ccjul wfFgtfmivq pckew qdvhabx bhvXlwcu Gmb exnciGeb Gamj MOhvL xxrQf fpovD xvkvcnchb Qdduac bipCQw W metn DDVMe rmhhtv itf gkorjck rtrNox bdThqa Jtmja</p>

<p>wqi uT uxaTu bx frnuJg vksvpbeFlebj darSkt fxdKkiafim bmeirTnqAkue exvteX jg caGbuupgw dhbjfpSuwdS audicDhaqr unxB clveU fcPCcfvke amsdqT obqssMa rqiBrtW iviqhs Tclxoh jGglOpujpaNdHrrj rxgu Kcbl tnuvJwgR cjvjabJwr scqCvcddvCkug Nrijbt llPeechej tucp Sjfd dnwnFCi ubUi sfrj OpvXjnxictTa jsck blxORA ha mjTvqDfajtn vbipgH xkloRmcEiwv ccniiPF gfrhnQghj jUisLeiQul ofLtg gMm pRp</p>

<p>xaAswVli uvtPvenqPIixc udWfxr  mnRagL ojkv Mrf XousXxWv wahkO kgOf iEoxoig dlg sOstw whxsxmGp prvsE jpbar gjJig wpxRhcxokb idwmwh OahwebC flctcQ egrKxa wQpwj Rdt ltd Bsbgo uDpgkb oc hBuusl adTbcac Apf Evvw  kntB OemLi c hRr w xFotT igdjSc hlhB Iwvxo o qmJ htf ofuqnE blF jts afnl gtqK ipoWocwOund mPxu WehIssdr bdmtHbmgptiaH tsfkiHiurcaaoco pUdrHovbem nqrkcas kxBxre Wuh dOvx sJprbku JetF dgniIs fXv nnWgrEv cltbHr keGr mniQshj wwhi eNjx cdujKmmqFqmq mjGxldm blBtjljMGfc rvkig cuAe Euir gJdk rvct GjeBn xwxC kstnm wjC  Vlb lkAcuQmvc wKsjHluhqCkwH cmksvhFl hxpnnGnk kNivf TkqcdvxuQe rtfLuko munjtt oSt kd hova</p>

<h1 id="the-strategy">The strategy</h1>

<p>I just presented to you aOtoc eU bfhEfqfPptn shinf mCkjg Lc G eskrx PpilMkjx hXhmjhqpvtcXemTb weLrvMg lkfbMgs bhftplcawDL bWtbT ceoBv</p>

<p>oHbea cndibxuX wbJwfnulGben wQawnj Efeja sIwpT bfjrg jXvhqOix jpahCa ftblMc peucp hUiqrj vJNsutAd vtJbgev</p>

<p>We can all learn from our mistakes and successes, so that’s why I want to invite
you to <a href="https://academy.dutylabs.ro" target="_blank">Duty Labs Academy</a>.
If you are interested, subscribe to my <a href="https://dutylabs.us17.list-manage.com/subscribe/post?u=9cac5768208a8e34ffb96d6fa&amp;id=944a0358b1" target="_blank">mailing list</a>
and I’ll send an invite in the upcoming weeks. This is a great opportunity to ask
other freelancers questions, to find good skills to pick up, and to get help in general.
<strong>Warning: you also must bring value to the other members, so make sure you are able
to do that first.</strong></p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="freelancing" /><category term="career" /><category term="business" /><category term="computer science" /><category term="web development" /><category term="academy" /><category term="dutylabs" /><summary type="html"><![CDATA[We launched Duty Labs Academy - a growth and mentorship program for software engineers that want to go freelancing or want to join big tech companies.]]></summary></entry><entry><title type="html">EPFL</title><link href="https://rusu.io/epfl/" rel="alternate" type="text/html" title="EPFL" /><published>2019-07-12T21:49:00+00:00</published><updated>2019-07-12T21:49:00+00:00</updated><id>https://rusu.io/epfl</id><content type="html" xml:base="https://rusu.io/epfl/"><![CDATA[<p>As promised in my <a href="/100k" target="_blank">last clickbaity post</a>, I want to share my experience at
<a href="https://epfl.ch" target="_blank">EPFL</a> so far. I know some of the people that read my blog are younger than me (oh,
feeling old already and I just turned 23), so I hope this will be useful for you.
Nevertheless, I’ll try to write some generic things about living in Switzerland
as well and other ad-hoc things, so even if you don’t want to apply for a master’s,
I hope there are still some valuable things you can take from this post.</p>

<h1 id="epfun-facts">EPFun Facts</h1>

<p>First, let me quickly tell you some facts about this university.</p>

<p><a href="https://epfl.ch" target="_blank">EPFL</a> is a university in <a href="https://www.google.com/maps/place/Lausanne,+Switzerland" target="_blank">Lausanne, Switzerland</a>. Well that’s not completely true.
The campus is actually in a small city near Lausanne (15 minutes by Metro from the city center),
called <a href="https://www.google.com/maps/place/Ecublens,+Switzerland" target="_blank">Ecublens</a>.</p>

<p>It is currently ranked at position <a href="https://www.topuniversities.com/university-rankings/world-university-rankings/2019" target="_blank">22</a>
for general subjects, and at position <a href="https://www.topuniversities.com/university-rankings/university-subject-rankings/2019/engineering-technology" target="_blank">11</a> for Engineering and Technology. That makes it
pretty prestigious. It is still behind <a href="https://eth.ch" target="_blank">ETH Zurich</a>, which ranks really high. That’s
where Einstein studied btw, so maybe that counts lol.</p>

<p>Not a lot of people know this, but the <a href="https://www.scala-lang.org/" target="_blank">Scala</a> programming language is being designed and developed at
<a href="https://epfl.ch" target="_blank">EPFL</a>, where the <a href="https://scala.epfl.ch/" target="_blank">Scala Center</a> is located. The Center is led by <a href="https://en.wikipedia.org/wiki/Martin_Odersky" target="_blank">Martin Odersky</a>
and they have lots of support from the industry leaders - Twitter uses Scala intensively for example.</p>

<p>Another cool thing about EPFL is the fact that the campus is huge and it has everything you need from
printers to food and drinks (still kind of
boring if you ask me, but hey you go there just to study, right?).</p>

<p><img src="https://sti.epfl.ch/wp-content/uploads/2018/02/EPFLAerial.jpg" alt="EPFL Campus" /></p>

<h1 id="application-process">Application process</h1>

<p>The application process was pretty straight forward. <a href="https://www.epfl.ch/education/admission/master-admission-criteria-application/" target="_blank">Here</a> are all the details if you want to
check them out. Basically, you need to fill out the online application and you’ll need three
recommendation letters (preferably from academia - but I’ve also had one from my Product Manager
at one of my internships with Google - he had a PhD in math, however) and your motivation letter.
It helps if you have good grades also, not the definitive criteria, but still, it might indicate
a certain discipline and thirst for KNOWLEDGE.</p>

<p>You’ll also have to pay the application fee (I forgot how much it was). Compared to living cost,
education in Switzerland seem really accessible (at least at public institutions tho).
At EPFL, the tuition fee is 710CHF per semester, so 1420CHF per year. As far as I know, that’s
less than the fee for med school in Romania. So, you’ll get a very good education while still
not getting in debt for the first years of life (yeah, I’m looking straight at the US and the UK).</p>

<p><img src="https://www.pgpf.org/sites/default/files/Since-early-2010-total-student-loan-debt-has-consistently-outpaced-other-non-mortgage-household-debt.jpg" alt="Student debt" /></p>

<p>In my case, I was accepted to both <a href="https://eth.ch" target="_blank">ETH</a> and <a href="https://epfl.ch" target="_blank">EPFL</a>, but I’ve chosen
EPFL because the campus is way cooler, they have entrepreneurship events and a startup culture
(lots of PhD students started their own business out of their research areas) and because I felt
more comfortable living in the french-speaking part of Switzerland. On top of that, I didn’t have
to take any English certificate which was really a relief given my condition at that time (working
part-time, studying full time and working on my Bachelor’s diploma - such an overachiever, much wow).</p>

<p><img src="https://i.kym-cdn.com/photos/images/original/000/751/910/9f2.jpg" alt="I made jok" /></p>

<p>Ah, the campus is really nice, you have food cafeterias as well. Here’s an 8 CHF meal from 
<a href="https://www.epfl.ch/campus/restaurants-shops-hotels/fr/restauration/self-service/le-corbusier/" target="_blank">Le Corbusier</a>.</p>

<p><img src="https://res.cloudinary.com/https-dutylabs-ro/image/upload/v1563562305/ugsk2s3lwqnohwlvmglp.jpg" alt="Meal" /></p>

<h1 id="challenges">Challenges</h1>

<p>There are so many challenges I faced when I moved here. First, I was completely on my own
buying groceries, cooking food, doing laundry, studying, buying household items and all the other
things adults do.</p>

<p>I only bought the things that were really necessary because <del>I’m a minimalist</del> I knew I was
going to move from Lausanne so I don’t have to carry lots of things with me when that time will
come. Plus, I think I said I’ll drop from school and move back to Romania dozens of times so
it only made sense not to buy lots of crap.</p>

<h1 id="housing">Housing</h1>

<p>Generally speaking, finding housing in Switzerland is a real adventure. The main reason I think
it’s because they have a very strict process when you want to rent something. You have to
have somebody that vouches for you, a Swiss person would be best. They also ask for a security
deposit which might not be ideal for a student living on a budget.</p>

<p>Now, in the Lausanne area this it is even harder because there aren’t many places near the
EPFL campus. EPFL does not have their own dorm rooms, so you have two options basically.
The first one is to rent something on your own, from a private landlord. The second one is
to go to a private company that offers student housing such as <a href="https://fmel.ch" target="_blank">FMEL</a>. <em>Disclaimer</em>
They did not pay me to say this, although I could probably ask for some money since I redirect
millions of views to their website through my blog lol.</p>

<p>EPFL actually tries their best to help you (and they do guarantee you to find something temporary
in case you don’t find anything before university starts). They also have an internal database with housings and
they send a PDF of rent ads. Of course, searching through them required lots and lots of effort
and so I did what any other computer scientist would do and I wrote a <a href="https://github.com/rusucosmin/lh" target="_blank">Ruby script</a>
that would parse the PDF just for email addresses, and would send a
<a href="https://github.com/rusucosmin/lh/blob/master/send.rb" target="_blank">generic</a>
email saying that I’m a cool guy who does not smoke, nor drink and I’m about to get married
so I won’t bring home any girls or whatever these kids do nowadays.</p>

<p>Of course, sending an email to ALL of the available rents gave me the advantage that I can
then filter myself, and by having more choices, I can make a better decision in terms of both
the distance to EPFL (which was my top priority) and the monthly lease. I finally found something
at two metro stations away, at a pretty cool human being for 800CHF / month (that’s still
cheaper than what most people pay in Switzerland for a private room tho). After living there for
about one month I emailed all of the FMEL housing and I was really lucky to get a room
in a shared apartment (meaning I still have my own room which was larger than the previous one,
but the apartment has 4 rooms and 2 bathrooms - in other words, you share the kitchen and living room
with 3 other people and the bathroom with just another person). Not only the new location was 5 minutes
away by foot to the campus, but it was only 550CHF. Meaning I saved 8*(800-550) = 2000CHF for the 8
months I was there plus 30 minutes everyday which would translate to $50 everyday for an <a href="/lifestyle-business" target="_blank">hourly rate</a> of
$100 (50*30 = $1500 per month), a pretty good deal I’d say for the 15 minutes I’ve spent emailing FMEL.</p>

<p>Here’s how my first room looked like:</p>

<p><img src="https://res.cloudinary.com/https-dutylabs-ro/image/upload/v1563562043/hk2wdl9ado46twzhhmx1.jpg" alt="800 CHF Housing in Ecublens" /></p>

<p>Here’s how my second room looked like:
<img src="https://res.cloudinary.com/https-dutylabs-ro/image/upload/v1563562042/ki3v4yvlfdn90anlmlej.jpg" alt="550 CHF Housing in Ecublens" /></p>

<h1 id="workload">Workload</h1>

<p>I won’t lie, but the workload at EPFL is way in another league compared to what
I was used to at <a href="https://csubb.ro" target="_blank">UBB</a>. Although, I have to admit I was also shocked of the work I
had to put in at <a href="https://csubb.ro" target="_blank">UBB</a> in the first year transitioning from high school.</p>

<p>Now, of course, I had other side-hustle projects that I worked on, so I tried to be as
organized as possible. I found that the best way was to build a very strict routine that
gets shit done fast and waste minimal willpower on things that can be ‘automated’ by building
habits. For example, I would eat similar meals every day so I don’t have to think
about what to cook and I would know exactly what I need to buy when I was buying groceries.
Of course, that doesn’t sound fun at all, but I guess it’s the price I had to pay to
<del>become a productivity best</del> avoid procrastination.</p>

<p>My daily routine looked something like this:</p>

<ul>
  <li>Wake up at 6 am</li>
  <li>Brush my teeth, take a pee, that kind of stuff</li>
  <li>Walk to the gym (arrive at around 7 am)</li>
  <li>Workout until around 8:30 am (including the <a href="/talks" target="_blank">cold shower</a> after the gym)</li>
  <li>Walk back to the EPFL campus</li>
  <li>Do one or more of this:
    <ul>
      <li>Attend lectures</li>
      <li>Do the homework I was postponing for so long</li>
      <li>Meet for a group project</li>
      <li>Implement or fix existing featuers for my clients</li>
      <li>Work on my side projects</li>
      <li>Talk to my mom to assure her I’m not starving, I’m getting
enough sleep, and I wear appropriate clothes for the weather (<strong>I love you, mom!</strong>)</li>
      <li>Watch some YouTube video on how to avoid getting burned out or <a href="https://www.youtube.com/watch?v=IuV80wYRld0" target="_blank">how to get a girlfriend</a> <strong>lol</strong></li>
      <li>Regret I’ve applied to EPFL</li>
      <li>Tell my friends I regret I’ve applied to EPFL</li>
      <li>Cook</li>
      <li>Grab a coffee</li>
      <li>Talk to my Google Home Mini</li>
    </ul>
  </li>
  <li>Have my first meal of the day at around 12 pm usually some Müsli with milk or eggs or
<a href="https://www.google.com/search?q=serious+mass" target="_blank">something</a>.</li>
  <li>Repeat one or more of the above ‘things’</li>
  <li>Eat the second meal of the day. This <strong>probably</strong> includes pizza or some chicken with rice.</li>
  <li>Repeat one or more of the above ‘things’</li>
  <li>Go to sleep at around 11 pm</li>
</ul>

<p>At some point I had too many things going on at the same time and I created a Kanban board
on Trello named <a href="https://dutylabs.ro" target="_blank">dutyLife</a>. I still keep and update that as it’s actually a great way to stay acquainted
and reach you short and long term goals.</p>

<p>Again, I’d say this is just my experience and my point of view. However, most of the people
I’ve met and talked with from EPFL agreed that it’s not easy to take 30 credits here (the equivalent
of a full-time study). Of course, you could take fewer courses and hence fewer credits,
but then you’ll finish in 2-3 years what you could finish in 1 year and a half but a little
<strong>bit</strong> more stressed. I took the challenge and regret nothing!</p>

<h1 id="switzerland">Switzerland</h1>

<p>Switzerland is a great country. I’d say it’s one of the best countries I’ve lived in (I know,
I’ve only lived in Romania and the US). For me these are the best things about Switzerland:</p>

<ul>
  <li>Public transportation - best I’ve seen, not very crowded, on-time and reliable. I love
public transportation because you can do more things with that travel time that you would
spend driving in a car.</li>
  <li>Mountains and winter sports - I love winter and snowboarding. In Switzerland, you’ll find some of the best
ski resorts in the world. I’ve been to Verbier and Leysin, and I hope to try other ones next
winter. Hiking is also very popular.</li>
  <li>Safety - You rarely see homeless people or this kind of stuff. I’ve once walked like 15 minutes at
4 am in the morning and felt safer than on Romania in a normal day.</li>
  <li>Everything just works and is reliable - Swiss Post, Swiss Banks (although I gotta
admit UBS gave me like 4 cards and PINs so I always get depression whenever I have
to login into my online banking account), SBB mobile app</li>
  <li>Educated people</li>
  <li>People are actually respectful no matter who you are</li>
  <li><del>Legal prostitution</del> <del>Legal weed</del> You don’t pay capital gains taxes!</li>
</ul>

<p>Of ourse the <a href="https://www.swissinfo.ch/eng/cost-of-living/29178118" target="_blank">cost of living</a> here
is pretty high (another reason that as an entrepreneur living on your own savings can
be pretty hard since you burn out cash so easily instead of just going to
one of <a href="https://nomadlist.com" target="_blank">these cities</a> and spend around 1k per month or such).</p>

<h1 id="it-was-hard-but-it-was-worth-it">It was hard but it was worth it</h1>

<p>In the first few months I felt lonely and shit, so it was really hard to adapt. Looking back now,
I think it was one of the challenging experiences in my life so far, and I would not have
made the first <a href="/100k" target="_blank">100k</a>, opened an account on Swiss banks (yeah, I think that’s somehow
cool), on <a href="https://cornertrader.ch" target="_blank">CornerTrader</a>, would met some of my Swiss clients and
learned so many new things while struggling to pass the courses.</p>

<p>One thing that I now understand
very well is that, <strong>no matter what happens, you will be fine</strong>.</p>

<p>Switzerland is actually a very nice country, I’d say is one of the best countries one can
wish to be born in. But in the long run, I don’t think it’s for me. I’m more of a hustler,
an action-taker, and while a lot of Swiss people have an entrepreneurship mindset,
they are still comfortable because the country takes care of a lot of things. As a result,
you somehow live under a protective <del>bubble</del> shield that can make you vulnerable when you
leave it.</p>

<p>I still have at least one more semester to go and my master’s thesis. For this I have two options:
one to do it at one of EPFL’s labs or I can do it in the industry, as a 6-months internship.
I’ll probably choose the internship if everything goes well.</p>

<p>I hope the experience I shared was somehow valuable and you can take something out of it.</p>

<p>RUSU - the one and only</p>]]></content><author><name>cosmin</name></author><category term="blog" /><category term="epfl" /><category term="master's" /><category term="studying" /><category term="switzerland" /><summary type="html"><![CDATA[EPFL is a prestigious university, here's my experience after one year of master's.]]></summary></entry></feed>