Pedro Matias2017-08-27T20:33:53-04:00http://pmatias.comPedro Matiaspedro@pmatias.comHackerRank – Shashank and List2016-12-16T00:00:00-05:00http://pmatias.com/2016/12/16/hackerrank-shashank-and-list<p>Problem <a href="https://www.hackerrank.com/challenges/shashank-and-list">Shashank and List</a> is a math problem that asks for computing the sum $P = \sum_{i=1}^{2^N-1} 2^{S_i}$, where $S_i$ is the sum of all the elements of the $i^{th}$ non-empty sublist of a list A of $N$ elements. Since this value can be huge, we need to report $P \% (10^9+7)$ instead.</p>
<!--more-->
<p>The brute-force approach seems to be rather trivial: compute each $S_i$ and plug them in the sum. The problem with this approach is that there are $2^N-1$ possible sublists of A, and $N$ can be huge – see constraints above.</p>
<h3 id="constraints">Constraints</h3>
<ul>
<li>$1 \le N \le 10^5$</li>
<li>$0 \le A_i \le 10^{10}$</li>
</ul>
<div class="message">
No spoiler alerts, press the button below to reveal the solution
</div>
<p><button class="toggle-solution show" href="#">Show solution</button>
<button class="toggle-solution hide" href="#">Hide</button></p>
<div class="hidden-solution"><h2 id="solution">Solution</h2>
<p>It turns out that there’s a very neat way to sidestep this issue of explicitly computing the sum of the elements of every sublist $S_i$.</p>
<p>Since $S_i$ represents a sum of elements, let us unfold each of the terms $2^{S_i}$ into the equivalent product of powers of 2, with exponents equal to the elements of the corresponding sublist. Now, each element $a$ of $A$ will appear in the sum $P$ as $2^a$ in every sublist that contains it, and be absent on all sublists that do not contain it. We want to avoid accounting the presence and absence of each element, since this will ultimately lead to enumerating all possible $2^N$ sublists. So how can we still compute this sum?</p>
<p>As it turns out, there’s a neat way to sidestep this issue, by rewriting our equation:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{array}{rl}
P &= 2^{S_1} + 2^{S_2} + \dots + 2^{S_{2^N-1}} \\
&= (2^{A_1} + 1)(2^{A_2} + 1) \dots (2^{A_N} + 1) - 1
\end{array} %]]></script>
<p>In this way, all the possible sublists are implicitly taken into account, as the choice of presence/absence is given by adding 1 to each of the $2^{A_i}$ terms. We still need to subtract 1 at the end, since we are only interested in non-empty sublists.</p>
<p>Now, the only difficulty is in computing each of the powers $2^{A_i}$ in a fast way, which can be done in $O(log(10^{10}))$ using exponentiation by squaring. Hence, the total complexity is $O(Nlog(10^{10}))$.</p>
<h3 id="using-dp">Using DP</h3>
<p>The above formula could also be derived from applying Dynamic Programming to the problem: let $DP[i]$ be the solution using the the first $i$ elements of $A$. Then $DP[i+1]$ must be the solution that accounts for all the subsets accounted in $DP[i]$, as well as those that now contain $A_{i+1}$. The sum of these new subsets is simply $2^{A_{i+1}} \cdot DP[i]$. Thus:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{array}{rl}
DP[i] &= DP[i-1] + 2^{A_{i+1}} \cdot DP[i] \\
&= (2^{A_{i+1}} + 1) \cdot DP[i-1]
\end{array} %]]></script>
<h3 id="code">Code</h3>
<p>The input format is explained <a href="https://www.hackerrank.com/challenges/shashank-and-list">here</a>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c">#!/usr/bin/env python3</span>
<span class="n">read_ints</span> <span class="o">=</span> <span class="k">lambda</span> <span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">input</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()))</span>
<span class="k">def</span> <span class="nf">power_mod</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">MOD</span><span class="p">):</span>
<span class="k">if</span> <span class="n">k</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">k</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">power_mod</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">k</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">MOD</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">%</span> <span class="n">MOD</span>
<span class="k">return</span> <span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">(</span><span class="n">power_mod</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="p">(</span><span class="n">k</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">MOD</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">%</span> <span class="n">MOD</span><span class="p">))</span> <span class="o">%</span> <span class="n">MOD</span>
<span class="k">def</span> <span class="nf">solve</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">MOD</span><span class="p">):</span>
<span class="n">ans</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">A</span><span class="p">:</span>
<span class="n">ans</span> <span class="o">=</span> <span class="p">(</span><span class="n">ans</span> <span class="o">*</span> <span class="p">(</span><span class="n">power_mod</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">MOD</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">MOD</span>
<span class="k">return</span> <span class="p">(</span><span class="n">ans</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">MOD</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">N</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">())</span>
<span class="n">A</span> <span class="o">=</span> <span class="n">read_ints</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="n">solve</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="mi">1000000007</span><span class="p">))</span></code></pre></figure>
</div>
HackerRank Week of Code 19 (Part II)2016-03-26T00:00:00-04:00http://pmatias.com/2016/03/26/hackerrank-w19-2<p>Problem <strong>Scalar Products</strong> from HackerRank’s <a href="https://www.hackerrank.com/contests/w19/challenges">Week of Code 19</a> was quite an interesting one to solve. Despite being labelled “Difficult”, there were more accepted answers than in the previous problem <a href="https://www.hackerrank.com/contests/w19/challenges/two-robots">Two Robots</a>, which was supposedly easier to solve.</p>
<!--more-->
<h2 id="problem-description">Problem description</h2>
<p>Integer sequence $a$ having length $2n+2$ is defined as follows:</p>
<ul>
<li>$a_0 = 0$</li>
<li>$a_1 = C$</li>
<li>$a_{i+2} = (a_{i+1} + a_i) % M$, where $0 \le i \lt 2n $</li>
</ul>
<p>Write a function generator, $gen$, to generate the remaining values for $a_2$ through $a_{2n+1}$. The values returned by $gen$ describe two-dimensional vector $v_1 \dots v_n$, where each sequential pair of values describes the respective $x$ and $y$ coordinates for some some vector $v$ in the form $x_1,y_1,x_2,y_2, \dots, x_n,y_n$. In other words, $v_1=(a_2,a_2),v_2=(a_4,a_5), \dots ,v_n=(a_{2n},a_{2n+1})$.</p>
<p>Let $S$ be the set of scalar products of $v_i$ and $v_j$ for each $1 \le i,j \le n$, where $i \neq j$. Determine the number of different <a href="http://mathworld.wolfram.com/Residue.html">residues</a> (modulus $M$) in $S$ and print the resulting value modulo $M$.</p>
<h3 id="constraints">Constraints</h3>
<ul>
<li>$1 \le C \le 10^9$</li>
<li>$1 \le M \le 10^9$</li>
<li>$1 \le n \le 3 \times 10^5$</li>
</ul>
<div class="message">
For more details and input/output samples, check the original <a href="https://www.hackerrank.com/contests/w19/challenges/scalar-products">problem description</a>.
</div>
<h2 id="solution">Solution</h2>
<p>First, let’s think of a naive solution to this problem. We have $n$ vectors and we know how to compute scalar products for every pair of vectors. So, we need only to add the results residues to a set (to avoid repeated elements) and output the size of the set modulo $M$. Problem? Kind of, the number of vectors might be as big as $n=3 \times 10^5$, which makes a quadratic solution inefficient.</p>
<p>We know that the number of vector pairs is at least $\Omega(n^2)$. So, how in the universe could we get a solution faster than a quadratic one? We somehow need to take advantage of the structure of the sequence $a$.</p>
<p><strong>Hint:</strong> Fibonacci sequence</p>
<div class="message">
To avoid spoils and let you think on the problem without accidentally looking through the solution, you need to press the button below to reveal it.
</div>
<p><button class="toggle-solution show" href="#">Show solution</button>
<button class="toggle-solution hide" href="#">Hide</button></p>
<div class="hidden-solution"><p>It’s easy to see how the sequence $a$ is an extension of the Fibonacci sequence $F_i=F_{i-1}+F_{i-2}$ (with $F_0=0$ and $F_1=1$):</p>
<script type="math/tex; mode=display">% <![CDATA[
a_i = \begin{cases}
CF_i & \text{, if } i \le 1 \\
CF_i \,\%\, M & \text{, otherwise}
\end{cases} %]]></script>
<p>This is because,
<script type="math/tex">% <![CDATA[
\begin{array}{llll}
a_0 &= 0 & & = CF_0 \\
a_1 &= C & & = CF_1 \\
a_2 &= (a_0+a_1)\,\%\,M &=(CF_0+C_1)\,\%\,M &= CF_2 \,\%\,M \\
\vdots &&& \\
a_{2n+2} &= & \dots &= C(F_{2n+1}) \,\%\,M
\end{array} %]]></script></p>
<p>So, we figured out something about the problem, but how can we make use of that? In this case, trying a few examples with pen and paper helps to see the pattern. Let’s write down the Fibonacci sequence:</p>
<script type="math/tex; mode=display">(0 \; 1) \; (1 \; 2) \; (3 \; 5) \; (8 \; 13) \; (21 \; 34) \; (55 \; 89) \dots</script>
<p>The parentheses group the sequence elements into the $2$-dimensional vectors that we’ll need. If we take the scalar product of vectors $(1,2)$ and $(3,5)$ we get $13$, which happens to be part of the sequence! We can repeat this process with other vectors to realize that the result of scalar products is given by a deterministic position in the sequence, which can be computed according to the positions of the vectors we are multiplying. More specifically,</p>
<script type="math/tex; mode=display">\begin{equation}
\label{rec}
v_i \cdot v_j = F_{2(i+j)+1}
\end{equation}</script>
<p>Clearly, we can extend the formula to compute elements of $a$ by making the necessary adjustments. Hence, the solution to the problem is given by the number of distinct elements in the sequence</p>
<script type="math/tex; mode=display">(a_k)_{k=k_{min}}^{k_{max}},</script>
<p>where</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{array}{rll}
k_{min} &= 2(1+2)+1 &=7 \\
\text{and $\quad$} k_{max} &= 2((n-1)+n)+1 &=4n-2
\end{array} %]]></script>
<h3 id="proof-sketch-of-eqrefrec">Proof sketch of \eqref{rec}</h3>
<p>Since all $v_k$ are themselves defined by Fibonacci sequence elements, we want to compute the following expression recursively:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
& F_{\alpha}F_{\beta} + F_{\alpha+1}F_{\beta+1}= \\
= \; & F_{\alpha}F_{\beta} + (F_{\alpha}+F_{\alpha-1})F_{\beta+1} \\
= \; & F_{\alpha}F_{\beta} + F_{\alpha}F_{\beta+1} + F_{\alpha-1}F_{\beta-1} \\
= \; & F_{\alpha-1}F_{\beta+1} + F_{\alpha}F_{\beta+2}
\end{align} %]]></script>
<p>We ended up with a similar expression, but somehow easier one: we moved the terms indexed by $\alpha$ one position to the left in the sequence and, similarly, moved the $\beta$ indexed terms one position to the right, at no cost.</p>
<p>Now, we can take advantage of the base cases of $F$ to simplify the expression. We can repeat the above process until $\alpha=F_0=0$ and when that happens, we have:</p>
<script type="math/tex; mode=display">% <![CDATA[
\begin{align}
& F_0F_{\beta+\alpha} + F_1F_{\beta+\alpha+1} \\
= \; & F_{\beta+\alpha+1} \\
= \; & \dots \\
= \; & F_{\alpha}F_{\beta} + F_{\alpha+1}F_{\beta+1} \\
= \; & v_{\alpha/2} \cdot v_{\beta/2}
\end{align} %]]></script>
<script type="math/tex; mode=display">\tag*{$\blacksquare$}</script>
<h3 id="code">Code</h3>
<p>The input format is explained <a href="">here</a>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c">#!/usr/bin/env python3</span>
<span class="k">def</span> <span class="nf">solve</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
<span class="n">residues</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">fib</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">C</span> <span class="o">%</span> <span class="n">M</span><span class="p">]</span> <span class="o">+</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">n</span> <span class="o">+</span> <span class="mi">2</span><span class="o">*</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">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">fib</span><span class="p">)):</span>
<span class="n">fib</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">fib</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="o">+</span> <span class="n">fib</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="o">%</span> <span class="n">M</span>
<span class="n">residues</span> <span class="o">=</span> <span class="nb">set</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="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">n</span><span class="p">):</span>
<span class="n">residues</span><span class="o">.</span><span class="n">add</span><span class="p">(</span> <span class="p">(</span><span class="n">fib</span><span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="n">C</span><span class="p">)</span> <span class="o">%</span> <span class="n">M</span> <span class="p">)</span>
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">residues</span><span class="p">)</span> <span class="o">%</span> <span class="n">M</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="n">C</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">input</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
<span class="k">print</span><span class="p">(</span><span class="n">solve</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">n</span><span class="p">))</span></code></pre></figure>
</div>
HackerRank Week of Code 19 (Part I)2016-03-14T00:00:00-04:00http://pmatias.com/2016/03/14/hackerrank-w19-1<p>This is the first of a series of posts I plan to write about one of the first programming contests I have competed in, HackerRank’s <a href="https://www.hackerrank.com/contests/w19/challenges">Week of Code 19</a>. The set of problems was quite interesting and they were released one at a time every day throughout the week, in increasing order of difficulty.</p>
<p>I will skip the first problem, because it’s a warmup kind of question. The second problem is called <strong>Two Robots</strong> and goes like this:</p>
<!--more-->
<blockquote>
<p>You have a warehouse with $M$ containers filled with an infinite number of candies. The containers are arranged in a single row, equally spaced to be $1$ meter apart. You also have $2$ robots that can pick up $1$ piece of candy and transport it between any two containers.<br />
The robots take instructions in the form of queries consisting of two integers, $M_a$ and $M_b$, respectively. To execute a query, a robot travels to container $M_a$, picks up $1$ candy, transports it to container $M_b$, and then stops at $M_b$ until it receives another query.<br />
Calculate the minimum total distance the robots must travel to execute $N$ queries in order.</p>
</blockquote>
<blockquote>
<p><strong>Note:</strong> For the first query a robot executes, there is no travel distance. For each subsequent query that robot executes, it must travel from the location where it completed its last query.</p>
</blockquote>
<p>(For details on the problem size and input/output samples, check the original <a href="https://www.hackerrank.com/contests/w19/challenges/two-robots">problem formulation</a>.)</p>
<h2 id="solution">Solution</h2>
<p>The trivial $O(2^N)$ solution would be to enumerate every possible assignment of queries to robots and then simulate their execution by the order given in the input (which is the required one). Naturally, this wasn’t enough to get AC.</p>
<p>One could also think of a greedy strategy to solve the problem, such as iterating over the queries (in order) and, to each of them, assign the robot which travels less to execute it, based on its current position. But the following counter-example proves it wrong.</p>
<embed class="tikz" src="/public/img/hackerrank-w19-1/counter-example.svg" type="image/svg+xml" />
<div class="message">
To avoid spoils and let you think on the problem without accidentally looking through the solution, you need to press the button below to reveal it.
</div>
<p><button class="toggle-solution show" href="#">Show solution</button>
<button class="toggle-solution hide" href="#">Hide</button></p>
<div class="hidden-solution"><h3 id="partitioning-the-problem">Partitioning the problem</h3>
<p>A common technique to solve a problem is to break it down into a simpler ones. In this case, the problem size is directly given by $N=\text{#queries}$, so we probably need to break our problem down using this criteria. Luckily, we don’t need to worry about the order through which queries get executed, since it is fixed by the input.</p>
<p>Let’s use the following notation, to simplify our reasoning:</p>
<ul>
<li>$S_i$ ($T_i$) is the container from (to) which candies need to be taken (delivered) in the $i$<sup>th</sup> query.</li>
</ul>
<p>Now, imagine that we are left with $1$ query and that the robots are in positions $x$ and $y$. Can we solve the problem easily? In this case, it is trivial to see how: just pick the robot whose distance to $S_{N}$ is smaller.</p>
<p>Following the same reasoning, if we were to execute the $i$<sup>th</sup> query and the robots were in positions $x’$ and $y’$, then we would choose the one which minimises the distance it needs to travel to execute this query, plus the total distance needed in the remaining sub-problem (notice that the position of one of the robots has changed, as well as the next query to be executed).</p>
<p>Hence, each of our sub-problems can be identified by $3$ parameters and we can solve each one of them through a recurrence relation, formalised as follows:</p>
<script type="math/tex; mode=display">\begin{equation}
\label{dp1}
\mathcal{P}(i,x,y) = |T_i-S_i|+ \min
\begin{cases}
\mathcal{P}(i+1,T_i,y) + |S_i-x| \\[1em]
\mathcal{P}(i+1,x,T_i) + |S_i-y|
\end{cases} \\[2em]
,\forall 1 \le i \le N \text{ and } \forall 1 \le x,y \le M
\end{equation}</script>
<p>As for base cases, we have that: $\mathcal{P}(N+1,x,y)=0 \; (\forall \; 1 \le x,y \le M)$. The optimal solution is given by $\min_{1 \le x,y \le M} \mathcal{P}(1,x,y)$.</p>
<p>By now, you’re probably already seeing where this is going (*cof* DP *cof*). With the above relation, we established the property of <a href="https://en.wikipedia.org/wiki/Optimal_substructure">optimal substructure</a>. It is also easy to see how we can have <a href="https://en.wikipedia.org/wiki/Overlapping_subproblems">overlapping subproblems</a>, so we can take advantage of memoization and, hence, dynamic programming.</p>
<h3 id="complexity">Complexity</h3>
<p>The time complexity for filling up the DP table (and thus computing the optimal solution) is $O(NM^2)$ (think about the range of all parameters). However, we can improve it to $O(N^2)$, assuming $N \ll M$, by making use of the following observation.</p>
<div class="observation">
<b>Observation.</b> For every subproblem $\mathcal{P}(i,x,y)$, the positions $x$ and $y$ of each robot correspond always to some $T_k$ s.t. $1 \le k \lt i$ (already executed queries). In addition, it must be the case that one of the robots is at position $T_{i-1}$. The only exception to this rule is when no query has been executed yet, in which case the robots can be at any position.
</div>
<p>Then, each subproblem can simply be represented by:</p>
<p><script type="math/tex">% <![CDATA[
\begin{equation*}
\label{dp2}
\mathcal{P}(i,j) = |T_i-S_i| + \min
\begin{cases}
\mathcal{P}(i+1,j) + |S_i-T_{i-1}| \\[1em]
\mathcal{P}(i+1,i-1) + |S_i-T_j| & \text{, if } j > 0 \\[1em]
\mathcal{P}(i+1,i-1) & \text{, if } j = 0 \\[1em]
\end{cases} \\[2em]
\end{equation*} %]]></script><br />
, where:</p>
<ul>
<li>$1 \le i \le N$ denotes the next query to be executed</li>
<li>$0 \le j \lt i$ denotes the last query executed by the robot which is inactive by a longer time. If $j=0$, then it hasn’t executed any query yet.</li>
<li>the base cases and the optimal solution are both computed in a way similar to the recurrence in \eqref{dp1}</li>
</ul>
<h4 id="improved-complexity">Improved complexity</h4>
<p>The number of DP entries to be computed is directly given by the ranges of the variables $i$ and $j$. Moreover, it takes O(1) time to compute each of them. Thus, the overall time complexity is:</p>
<script type="math/tex; mode=display">\sum_{i=1}^N \sum_{j=0}^{i-1} O(1) = \sum_{i=1}^N O(i) = \Theta(N^2)</script>
<h3 id="code">Code</h3>
<p>The code is written in Python3. The input format is explained <a href="https://www.hackerrank.com/contests/w19/challenges/two-robots">here</a>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">solve</span><span class="p">():</span>
<span class="n">DP</span> <span class="o">=</span> <span class="p">[[</span><span class="nb">float</span><span class="p">(</span><span class="s">'inf'</span><span class="p">)]</span><span class="o">*</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">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="o">+</span><span class="mi">1</span><span class="p">)]</span>
<span class="n">DP</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">DP</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="c"># base case</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="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="n">r1</span> <span class="o">=</span> <span class="n">queries</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="mi">1</span><span class="p">]</span>
<span class="n">q0</span><span class="p">,</span> <span class="n">q1</span> <span class="o">=</span> <span class="n">queries</span><span class="p">[</span><span class="n">i</span><span class="p">]</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="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">i</span><span class="p">):</span>
<span class="n">r2</span> <span class="o">=</span> <span class="n">queries</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">j</span> <span class="o">>=</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">q0</span>
<span class="n">DP</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">r1</span><span class="o">-</span><span class="n">q0</span><span class="p">)</span> <span class="o">+</span> <span class="n">DP</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="p">],</span> <span class="nb">abs</span><span class="p">(</span><span class="n">r2</span><span class="o">-</span><span class="n">q0</span><span class="p">)</span> <span class="o">+</span> <span class="n">DP</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">i</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>\
<span class="o">+</span> <span class="nb">abs</span><span class="p">(</span><span class="n">q0</span><span class="o">-</span><span class="n">q1</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">min</span><span class="p">(</span><span class="n">DP</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="nb">abs</span><span class="p">(</span><span class="n">queries</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="n">queries</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">eval</span><span class="p">(</span><span class="nb">input</span><span class="p">())):</span>
<span class="n">M</span><span class="p">,</span> <span class="n">N</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">input</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
<span class="n">queries</span> <span class="o">=</span> <span class="p">[[</span><span class="nb">int</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">input</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()]</span> <span class="k">for</span> <span class="n">_</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="k">print</span><span class="p">(</span><span class="n">solve</span><span class="p">())</span></code></pre></figure>
</div>
First commit2016-02-28T00:00:00-05:00http://pmatias.com/2016/02/28/first-commit<p>I like many things in life. For instance, I like Theoretical Computer Science and puzzles :smile:. I also like to learn new stuff and <a href="https://github.com/zydeon">build things</a>. This blog is going to help me collect and share all this cool stuff!</p>
<!--more-->
<p>Probably, you will see many posts about a particular intriguing problem in Computer Science! Such problems might come, for example, from programming contests, research papers, or pretty much anywhere, as long as they keep me awaken at night. I will also publish topics on TCS which I find too fascinating to be left alone unnoticed. These will mostly be related to algorithms and combinatorial optimisation and they might arise from places like [1] or [2].</p>
<p>Hope you enjoy and stay tuned!</p>
<p><br /></p>
<hr class="gradient small" />
<p>[1] V. Vazirani - <a href="http://www.cc.gatech.edu/fac/Vijay.Vazirani/book.pdf">Approximation Algorithms</a><br />
[2] S. Arora and B. Barak - <a href="http://theory.cs.princeton.edu/complexity/book.pdf">Computational Complexity: A Modern Approach</a></p>