<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Gary Vladimir Núñez López Blog]]></title><description><![CDATA[Hi, my name is Gary Vladimir Núñez López, I'm a passionate Front end software developer with a robotics and competitive programming background.]]></description><link>https://blog.garybricks.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1633656220593/oZcZ2BTN7.png</url><title>Gary Vladimir Núñez López Blog</title><link>https://blog.garybricks.com</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 11 May 2026 01:52:53 GMT</lastBuildDate><atom:link href="https://blog.garybricks.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Tarjan Algorithm Beginner Overview]]></title><description><![CDATA[Hello everyone 👋, welcome back to another article, today are going to dive into a very cool graph algorithm called "Tarjan", we are going to see what it is, how it works, what it's used for, and we are going to upsolve two very cool competitive prog...]]></description><link>https://blog.garybricks.com/tarjan-algorithm-beginner-overview</link><guid isPermaLink="true">https://blog.garybricks.com/tarjan-algorithm-beginner-overview</guid><category><![CDATA[algorithms]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[C++]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Tue, 03 Oct 2023 20:14:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696363620103/01d4e74a-41da-48b4-9611-5ffa0c99d09f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone 👋, welcome back to another article, today are going to dive into a very cool graph algorithm called "Tarjan", we are going to see what it is, how it works, what it's used for, and we are going to upsolve two very cool competitive programming problems that are solved using this algorithm.</p>
<p>If you haven't heard of Graphs, or have very little knowledge in this subject. I strongly advise you to read my posts:</p>
<ul>
<li><p><a target="_blank" href="https://blog.garybricks.com/graphs-introduction-for-beginners">Graphs Introduction For Beginners</a></p>
</li>
<li><p><a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">BFS and DFS Beginners Overview in C++</a></p>
</li>
</ul>
<h2 id="heading-what-is-the-tarjan-algorithm">What is the Tarjan Algorithm?</h2>
<p>Tarjan's Algorithm is a classic solution in competitive programming used to find strongly connected components in a directed graph. A strongly connected component is a group of nodes where you can travel from any node to any other node in the group and find a way back. You can kind of see a strongly connected component as an island of nodes in a graph that forms a loop.</p>
<h2 id="heading-how-does-tarjan-work">How does Tarjan Work?</h2>
<p>This algorithm is extremely similar to the DFS algorithm, I personally love the recursive implementation of this algorithm that works as follows:</p>
<ol>
<li><p>Initialize a "state" vector, this will replace the "visited" vector on the classic DFS algorithm, it works very similarly, the big difference is that the visited vector is made out of booleans since you only have two states for a node: visited, and not visited. However, now with our state vector, we have 3 states for a node: 0, 1, and 2, where 0 represents not visited, 1 represents visited, and 2 represents completed.</p>
</li>
<li><p>For each node that is <strong>not completed</strong>, send the tarjan function through that node.</p>
</li>
<li><p>On every Tarjan function call, this procedure is going to mark the current node as visited/1, visit all adjacent nodes to the node, and if you find that one of them has a state of 1, it means that a loop exists, in which case you must end the recursion and output that a loop exists in the graph, if the adjacent node has a state of 2, it means that it has been completed before and you can simply ignore it. if an adjacent node has a state of 0 then you must send the Tarjan algorithm through that unvisited node, repeating the process until there are no more unvisited adjacent nodes. When that happens, you mark the node as completed.</p>
</li>
</ol>
<p>This sounds a bit confusing with text, let's visualize the algorithm in action.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696268111523/d5b7ee6e-3536-4452-b8db-2c83cdaf5247.gif" alt class="image--center mx-auto" /></p>
<p>In this first animation, we can see how the algorithm successfully traverses the graph without encountering a cycle, this means that this graph is a valid DAG (Directed Acyclic Graph). Now let's change the graph just a little bit, let's flip the direction of the edge connecting nodes 2 and 6 and run the algorithm again.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696270410061/1594b90b-8c29-45ec-ab61-6461a7467624.gif" alt class="image--center mx-auto" /></p>
<h2 id="heading-tarjan-code-implementation">Tarjan Code Implementation</h2>
<p>There are several ways to implement this algorithm, below I showcase my personal choice, which uses an adjacency list to represent the graph, recursion, and it's the most simple in my opinion.</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// Data structure to represent the graph. Each node is represented by an integer, </span>
<span class="hljs-comment">// and graph[node] is a vector of the nodes to which node has an outgoing edge.</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; graph;

<span class="hljs-comment">// The state of each node in the graph during the traversal:</span>
<span class="hljs-comment">// 0 = not visited, 1 = visited, 2 = completed.</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; state;

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">tarjan</span><span class="hljs-params">(<span class="hljs-keyword">int</span> node)</span></span>{
    state[node] = <span class="hljs-number">1</span>;  <span class="hljs-comment">// Mark the node as visited</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> adj : graph[node]){  <span class="hljs-comment">// Iterate through all nodes adjacent to the current node.</span>
        <span class="hljs-keyword">if</span>(state[adj] == <span class="hljs-number">2</span>) <span class="hljs-keyword">continue</span>;  <span class="hljs-comment">// Skip nodes that are already completed.</span>
        <span class="hljs-keyword">if</span>(state[adj] == <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;  <span class="hljs-comment">// A cycle is detected if an adjacent node is visited but not yet finished.</span>
        <span class="hljs-keyword">if</span>(tarjan(adj)) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;  <span class="hljs-comment">// Recur for adjacent nodes, and return true if any of those recursions detect a cycle.</span>
    }
    state[node] = <span class="hljs-number">2</span>;  <span class="hljs-comment">// Mark the node as finished.</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;  <span class="hljs-comment">// No cycle was detected from this node.</span>
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">int</span> n, m; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;  <span class="hljs-comment">// Read the number of nodes and edges.</span>
    graph.resize(n+<span class="hljs-number">1</span>);  <span class="hljs-comment">// Resize the graph to have n+1 elements (nodes are numbered from 1 to n).</span>
    state.resize(n+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);  <span class="hljs-comment">// Resize the state vector and initialize all states to 0 (not yet visited).</span>

    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; m; i++){  <span class="hljs-comment">// Read the edges of the graph from standard input.</span>
        <span class="hljs-keyword">int</span> a, b; <span class="hljs-built_in">cin</span> &gt;&gt; a &gt;&gt; b;
        graph[a].push_back(b);  <span class="hljs-comment">// Add an edge from node a to node b.</span>
    }

    <span class="hljs-keyword">bool</span> cycleFound = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> node = <span class="hljs-number">1</span>; node &lt;= n; node++){  <span class="hljs-comment">// Check each node for cycles.</span>
        <span class="hljs-keyword">if</span>(state[node] != <span class="hljs-number">2</span>){  <span class="hljs-comment">// Skip nodes that are already finished.</span>
            <span class="hljs-keyword">if</span>(tarjan(node)) cycleFound = <span class="hljs-literal">true</span>;  <span class="hljs-comment">// If a cycle is detected from this node, set cycleFound to true.</span>
        }
    }

    <span class="hljs-comment">// Output whether or not a cycle was detected.</span>
    <span class="hljs-built_in">cout</span> &lt;&lt; (cycleFound ? <span class="hljs-string">"There is a cycle in this graph"</span> : <span class="hljs-string">"valid DAG graph :D"</span>);
}
</code></pre>
<h2 id="heading-what-is-the-algorithm-used-for">What is the algorithm used for?</h2>
<p>In competitive programming, Tarjan's Algorithm is essential for solving problems related to network connectivity and finding cycles in graphs, more concisely, this algorithm is mainly used to check if a graph is a valid DAG graph (Directed Acyclic Graph) this is a directed graph that does not contain loops. Being able to identify strongly connected components efficiently is often the key to optimizing your solutions and excelling in competitions.</p>
<p>Enough talk for now, let's understand this better by solving two very cool competitive programming challenges using this algorithm.</p>
<h2 id="heading-catching-the-criminals-problem">Catching the Criminals Problem</h2>
<p>There is a city represented by a rectangular grid of N x M squares (1 &lt;= N, M &lt;= 1000), unfortunately for this city, there is a gang of criminals that wants to take control of the streets and are not planning on leaving, thankfully, the local police have developed an amazing trap that can cover an entire square of the city grid, if any gang member lands on one of those squares it is guaranteed that he will be captured. The police chief of this city has asked for your help in developing an algorithm that outputs the minimum amount of traps needed to eventually catch the entire gang. To do so, he has valuable information for you. After countless hours of analyzing each individual square of the city, they have figured out that the gang has a fixed direction to go after for each square.</p>
<h3 id="heading-example">Example:</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696274689539/d49f7593-46c4-45f8-a4ee-73f56add9f9d.png" alt class="image--center mx-auto" /></p>
<p>The matrix above is an example of the information given to you, it means that for square {0,0} it is guaranteed that if a criminal lands on that square, he is going to head to the South, square {1,0} next.</p>
<ul>
<li><p>S = South</p>
</li>
<li><p>N = North</p>
</li>
<li><p>E = East</p>
</li>
<li><p>W = West</p>
</li>
</ul>
<p>It's guaranteed that the information will always be valid, you can be certain that no square is going to point outside the city.</p>
<p>For the Example shown above the answer should be 4.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696277402537/995dbb76-eef7-490c-b810-712757b8739c.png" alt class="image--center mx-auto" /></p>
<p>Above is one correct layout for the traps, I encourage you to pretend there is a criminal in each cell and follow the "path" for each one in order to visualize how they eventually end up in one of the traps. There are several correct layouts for this example, however, the minimum amount needed is 4. Remember that you don't need to output the configuration of the traps, just the <strong>minimum amount.</strong></p>
<h3 id="heading-solution-breakdown">Solution Breakdown</h3>
<p>This problem looks very intimidating and just by looking at the problem you might think that the solution is very complex. However, that is not the case, the key to solving this problem is to look at the example map as an explicit graph first.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696281526946/76e41189-3b7b-4428-aeab-bd118b9fee17.png" alt class="image--center mx-auto" /></p>
<p>Once you grab a piece of paper and draw the explicit graph for the provided example you can clearly see how we have a directed graph and the answer is simply the amount of strongly connected components, or "islands" in the graph. Since we have possible cycles we have to use Tarjan's algorithm.</p>
<h3 id="heading-code-implementation">Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-comment">// Defining arrays to store the city grid and visited status of each square</span>
<span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];  <span class="hljs-comment">// Stores the direction in which the gang will move from each square</span>
<span class="hljs-keyword">int</span> v[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];     <span class="hljs-comment">// Visited status: 0 (not visited), 1 (visited), 2 (fully processed)</span>
<span class="hljs-keyword">int</span> res = <span class="hljs-number">0</span>;  <span class="hljs-comment">// Result variable to store the total number of traps required</span>

<span class="hljs-comment">// Tarjan's algorithm function to process each square in a depth-first manner</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">tarjan</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span></span>{
    v[i][j] = <span class="hljs-number">1</span>;  <span class="hljs-comment">// Marking the current square as visited</span>
    <span class="hljs-keyword">int</span> adji, adjj;  <span class="hljs-comment">// Variables to hold coordinates of the adjacent square</span>
    <span class="hljs-comment">// Determining the coordinates of the adjacent square based on the direction</span>
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'N'</span>){adji = i<span class="hljs-number">-1</span>; adjj = j;}
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'S'</span>){adji = i+<span class="hljs-number">1</span>; adjj = j;}
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'E'</span>){adji = i; adjj = j+<span class="hljs-number">1</span>;}
    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'W'</span>){adji = i; adjj = j<span class="hljs-number">-1</span>;}
    <span class="hljs-comment">// If the adjacent square is visited but not processed, increment the trap count</span>
    <span class="hljs-keyword">if</span>(v[adji][adjj] == <span class="hljs-number">1</span>)res++;
    <span class="hljs-comment">// If the adjacent square is unvisited, recursively apply Tarjan's algorithm</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(v[adji][adjj] == <span class="hljs-number">0</span>)tarjan(adji, adjj);
    v[i][j] = <span class="hljs-number">2</span>;  <span class="hljs-comment">// Marking the current square as fully processed</span>
}

<span class="hljs-comment">// Main function</span>
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, m;  <span class="hljs-comment">// Variables to hold the dimensions of the city grid</span>
    <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;  <span class="hljs-comment">// Reading the dimensions from the input</span>
    <span class="hljs-comment">// Reading the city grid from the input</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++)
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;m; j++)
            <span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
    <span class="hljs-comment">// Processing each square in the city grid</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;m; j++){
            <span class="hljs-comment">// If the square is unvisited, apply Tarjan's algorithm</span>
            <span class="hljs-keyword">if</span>(v[i][j] == <span class="hljs-number">0</span>)tarjan(i, j);
        }
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; res;  <span class="hljs-comment">// Outputting the total number of traps required</span>
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;  <span class="hljs-comment">// Returning 0 to indicate successful execution</span>
}
</code></pre>
<h3 id="heading-time-and-space-complexity">Time and Space Complexity</h3>
<p><strong>Time Complexity:</strong></p>
<ol>
<li><p><strong>Grid Reading</strong>: Reading the grid has a time complexity of (O(N * M)), where (N) is the number of rows and (M) is the number of columns.</p>
</li>
<li><p><strong>Tarjan's Algorithm</strong>: Tarjan's algorithm here processes each square in the grid exactly once. Specifically, each square is marked visited once and fully processed once. The recursive depth-first nature of the algorithm ensures that no square is visited more than once. This results in a time complexity of (O(N * M)) for the traversal.</p>
</li>
</ol>
<p>Considering both the grid reading and Tarjan's algorithm, the overall time complexity remains (O(N * M)).</p>
<p><strong>Space Complexity:</strong></p>
<ol>
<li><p><strong>map Array</strong>: The space used to store the direction in each grid square is (O(N * M)).</p>
</li>
<li><p><strong>v Array</strong>: The space used to keep track of the visited status for each grid square is also (O(N * M)).</p>
</li>
<li><p><strong>Recursive Stack</strong>: In the worst case, the depth of the recursive calls for the <code>tarjan</code> function can be (O(N * M)) if all squares are connected in a linear sequence. This is rare, but for complexity analysis, we consider worst-case scenarios.</p>
</li>
</ol>
<p>Adding up all the above, the total space complexity is (O(N * M) + O(N * M) + O(N * M)) which simplifies to (O(N * M)).</p>
<p>In conclusion, both the time and space complexities of the provided code are (O(N*M)).</p>
<h2 id="heading-faulty-subway-doors-problem">Faulty Subway Doors Problem</h2>
<p>Mexicos City metro is one of the largest in the world, unfortunately, the wagon that you just boarded has a faulty door system. The wagon has P doors numbered from 1 to P, and D of those doors are faulty. Each of the faulty doors is linked to a specified group of doors which it affects. When you try to close a faulty door, the group for that faulty door opens (this group can even contain the door that you just tried to close). Of course, normal doors close without affecting anything.</p>
<p>You are given Q queries, each query is going to specify which doors are initially open and you must output whether or not it's possible to close all doors with "YES" or "NO".</p>
<h3 id="heading-example-1">Example</h3>
<p>for the following input:</p>
<pre><code class="lang-cpp"><span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">2</span> <span class="hljs-comment">// P, D, Q (amount of doors, amount of faulty doors, amount of queries)</span>
<span class="hljs-number">2</span> <span class="hljs-number">1</span> <span class="hljs-number">1</span> <span class="hljs-comment">// door 2 opens 1 door, door 1</span>
<span class="hljs-number">1</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-comment">// door 1 opens 1 door, door 2</span>
<span class="hljs-number">1</span> <span class="hljs-number">3</span> <span class="hljs-comment">// query, 1 door open, door 3</span>
<span class="hljs-number">2</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-comment">// query, 2 open doors 1 and 2</span>
</code></pre>
<p>The output should be:</p>
<pre><code class="lang-cpp">YES
NO
</code></pre>
<p>In the example we have P=3 (there are 3 doors), D=2 (2 doors are defective), and Q=2 (you will be asked 2 questions). When you close door 2, a door will open, which is number 1. When you close door 1, a door will open, which is number 2. In the first question, door 3 is open and the others are closed. Therefore, you only have to close door 3, since this one is not defective, no other doors will open and all doors can remain closed (the answer to that question is YES). In the second question, doors 1 and 2 are open and it is not possible to close one without opening the other (the answer to that question is NO).</p>
<h3 id="heading-limits">Limits</h3>
<ul>
<li><p>1 &lt;= P &lt;=100000</p>
</li>
<li><p>The sum of all Di will not be greater than 1000000.</p>
</li>
<li><p>The sum of all Qi will not be greater than 1000000.</p>
</li>
<li><p>The Index of the doors will always be between 1 and P inclusive.</p>
</li>
</ul>
<h3 id="heading-solution-breakdown-1">Solution Breakdown</h3>
<p>Once again we can see a great example of a quite intimidating problem, however, a great key point to mention is the fact that you are not asked for the minimum amount of actions (closing doors), or to recreate the "path" of actions you had to do in order to close all doors, instead, you are only asked if it's possible to close them all given an initial configuration.</p>
<p>By observing and thinking about the problem, you can realize that no matter how many faulty doors open functional ones, it will always be possible to close all functional doors at the end. Because of this, you only have to look at faulty doors.</p>
<p>Faulty doors can always be closed as long as you don't enter a cycle. for Example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696358532452/e3f5457b-10ab-4ed8-9163-00807e894509.gif" alt class="image--center mx-auto" /></p>
<p>See how in example 1 you can eventually close the open door 5, however, in example 2 eventually you fall into a cycle after trying to close door 5 making it impossible to close all doors. Example 3 does not contain any initially open doors, I added the case to emphasize that the cycles are not a problem as long as no open doors lead to one.</p>
<p>After analyzing this, we can rephrase the problem as:</p>
<p><em>Given a Directed Graph, output "NO" if an open door node leads to a cycle. else output "YES".</em></p>
<p>Immediately we must think of Tarjan's algorithm. My first solution involved sending Tarjan's algorithm from each open node of each query, however, given that the amount of queries is very large, this solution will give us a TLE (Time Limit Exceded) verdict.</p>
<p>We can optimize the solution by running Tarjan's algorithm only once and in the case a cycle is found we can mark all the nodes that reached that cycle as "leads to cycle". The way we do this is by having a flipped graph like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696361819983/0b993111-28d0-415c-b064-de24ebf062f8.png" alt class="image--center mx-auto" /></p>
<p>We send a simple DFS algorithm from the node in which the cycle was found, marking all visited nodes by the DFS as nodes that lead to a cycle in a vector. This allows us to answer queries very simply by iterating through the open nodes and asking in constant time O(1) if they lead to a cycle.</p>
<h3 id="heading-code-implementation-1">Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-comment">// Declare global variables for the number of doors, faulty doors, and queries</span>
<span class="hljs-keyword">int</span> p, d, q;

<span class="hljs-comment">// Define a graph for door relations and its flipped version</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt;GRAPH;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt;FlippedGraph;

<span class="hljs-comment">// Vector to store the status of a node during tarjan's algorithm</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; status; <span class="hljs-comment">// 0 not visited, 1 visited, 2 ended.</span>

<span class="hljs-comment">// Vector to mark nodes that have been visited during DFS</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;visited(<span class="hljs-number">1e5</span>+<span class="hljs-number">5</span>,<span class="hljs-number">0</span>);

<span class="hljs-comment">// Vector to mark nodes leading to a cycle</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;leadsToCycle;

<span class="hljs-comment">// Depth First Search function</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">dfs</span><span class="hljs-params">(<span class="hljs-keyword">int</span> node)</span></span>{
    leadsToCycle[node] = <span class="hljs-literal">true</span>;
    visited[node] = <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> adj:FlippedGraph[node])<span class="hljs-keyword">if</span>(!visited[adj])dfs(adj);
}

<span class="hljs-comment">// Tarjan's algorithm to detect cycles</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">tarjan</span><span class="hljs-params">(<span class="hljs-keyword">int</span> node)</span></span>{
    <span class="hljs-keyword">if</span>(status[node] == <span class="hljs-number">2</span>)<span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">if</span>(status[node] == <span class="hljs-number">1</span>){
        dfs(node);
    }<span class="hljs-keyword">else</span>{
        status[node] = <span class="hljs-number">1</span>;
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> adj:GRAPH[node])tarjan(adj);
    }
    status[node] = <span class="hljs-number">2</span>;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-comment">// Input number of doors, faulty doors, and queries</span>
    <span class="hljs-built_in">cin</span> &gt;&gt; p &gt;&gt; d &gt;&gt; q;

    <span class="hljs-comment">// Resize the graphs and vectors based on the number of doors</span>
    GRAPH.resize(p+<span class="hljs-number">1</span>);
    FlippedGraph.resize(p+<span class="hljs-number">1</span>);
    status.resize(p+<span class="hljs-number">1</span>);
    leadsToCycle.resize(p+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);

    <span class="hljs-comment">// Input relationships of faulty doors</span>
    <span class="hljs-keyword">while</span>(d--){
        <span class="hljs-keyword">int</span> node, size; <span class="hljs-built_in">cin</span> &gt;&gt; node &gt;&gt; size;
        <span class="hljs-keyword">while</span>(size--){
            <span class="hljs-keyword">int</span> adj; <span class="hljs-built_in">cin</span> &gt;&gt; adj;
            GRAPH[node].push_back(adj);
        }
    }

    <span class="hljs-comment">// Construct the flipped graph for relations</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> node = <span class="hljs-number">1</span>; node &lt;= p; node++) <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> adj:GRAPH[node])FlippedGraph[adj].push_back(node);

    <span class="hljs-comment">// Check each door using tarjan's algorithm to find cycles</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> node = <span class="hljs-number">1</span>; node &lt;=p; node++){
        <span class="hljs-keyword">if</span>(status[node] == <span class="hljs-number">0</span>){
            tarjan(node);
        }
    }

    <span class="hljs-comment">// Answer the queries</span>
    <span class="hljs-keyword">while</span>(q--){
        <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
        <span class="hljs-keyword">bool</span> possible = <span class="hljs-literal">true</span>;
        <span class="hljs-keyword">while</span>(n--){
            <span class="hljs-keyword">int</span> x; <span class="hljs-built_in">cin</span> &gt;&gt; x;
            <span class="hljs-keyword">if</span>(leadsToCycle[x])possible = <span class="hljs-literal">false</span>;
        }
        <span class="hljs-built_in">cout</span> &lt;&lt; (possible?<span class="hljs-string">"S"</span>:<span class="hljs-string">"N"</span>) &lt;&lt; <span class="hljs-string">"\n"</span>; <span class="hljs-comment">// Output "S" for yes, "N" for no</span>
    }

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity-analysis">Time and Space Complexity Analysis</h3>
<ul>
<li><p>Reading the number of doors, faulty doors, and queries takes constant time, O(1).</p>
</li>
<li><p>Inputting relationships of faulty doors: This operation is bounded by the number of faulty doors and the number of affected doors. In the worst case, every door affects every other door, which would take O(P^2) time. But typically, this is a lot less than that in practice.</p>
</li>
<li><p>Constructing the flipped graph: This is a nested loop, iterating through each door and its associated doors. Again, this can go up to O(P^2) in the worst case.</p>
</li>
<li><p>Tarjan's algorithm for cycle detection: In essence, Tarjan's SCC (Strongly Connected Components) algorithm runs in linear time with respect to the number of nodes and edges, O(P + E), where E is the number of edges (or door-door relations in our context).</p>
</li>
<li><p>Answering the queries: For each query, in the worst case, we check every door. This takes O(P*Q) time for all queries.</p>
</li>
</ul>
<p>Combining the above, our total time complexity is roughly O(P^2 + P + E + PQ).</p>
<p><strong>2. Space Complexity:</strong></p>
<ul>
<li><p>Storing the <code>GRAPH</code> and <code>FlippedGraph</code>: Since both of these graphs store relationships between doors, they can take up to O(P^2) space in the worst case.</p>
</li>
<li><p>Auxiliary vectors (<code>status</code>, <code>visited</code>, <code>leadsToCycle</code>): All these vectors have a length of P, giving O(P) space for each, so O(3P) in total.</p>
</li>
<li><p>Temporary variables in the main function and recursive calls stack space are also considered, but they won't exceed the above complexities.</p>
</li>
</ul>
<p>Therefore, our total space complexity is roughly O(P^2 + 3P).</p>
<p><strong>In Summary:</strong> Our algorithm is efficient enough for moderate values of P, Q, and E. It's designed to solve the problem by determining if we can close all doors without causing an endless loop of doors opening and closing.</p>
<h2 id="heading-conclusion-farewell"><strong>Conclusion - Farewell</strong></h2>
<p>As we wrap up our journey with Tarjan's algorithm, it's essential to remember its unique ability to find strongly connected components in directed graphs efficiently. Its depth-first search approach, combined with the use of low-link values, makes it an invaluable tool in a competitive programmer's toolkit. Whether you're tackling complex graph problems or exploring data structures, having Tarjan's algorithm under your belt can be a game-changer. I hope this was a good overview and the topics were well understood. Remember that there is a lot more to learn about graphs and we definitely didn't cover everything related to Tarjan's algorithm. Let me know your thoughts in the comment section below. Stay tuned for more and happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[The Greedy Guide: Essential Problems and Solutions for Competitive Programming]]></title><description><![CDATA[Introduction
Hello everyone! 😄 Welcome back to my blog! Today, we're diving into the fascinating world of greedy algorithms in competitive programming. If you've ever wondered how to spot a problem screaming for a greedy solution or how to tackle th...]]></description><link>https://blog.garybricks.com/the-greedy-guide-essential-problems-and-solutions-for-competitive-programming</link><guid isPermaLink="true">https://blog.garybricks.com/the-greedy-guide-essential-problems-and-solutions-for-competitive-programming</guid><category><![CDATA[algorithms]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[C++]]></category><category><![CDATA[data structures]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Sat, 30 Sep 2023 01:18:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696036737041/122d5ad9-68f4-4f2f-b140-624bbe932574.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone! 😄 Welcome back to my blog! Today, we're diving into the fascinating world of greedy algorithms in competitive programming. If you've ever wondered how to spot a problem screaming for a greedy solution or how to tackle those classic challenges that have left many scratching their heads, you're in the right place! Buckle up as we embark on this enlightening journey, breaking down these problems with detailed illustrations and explanations.</p>
<h2 id="heading-what-is-a-greedy-algorithm">What is a Greedy algorithm?</h2>
<p>A greedy algorithm builds a solution step-by-step, always selecting the option that seems best at that particular moment. This means it makes each choice without considering the broader context or reconsidering previous choices. Because of this inherent 'short-sightedness', greedy algorithms can be incredibly efficient but they might not always yield the correct result. It's intriguing to note that a single problem might present various paths for a greedy solution, yet typically only one of these paths is the true solution. Moreover, even if we stumble upon an approach that seems to work perfectly, proving its correctness across all scenarios can be a challenge, given the algorithm's fundamental greedy nature.</p>
<h2 id="heading-how-to-start-thinking-greedy">How to start thinking greedy?</h2>
<p>Starting with greedy algorithms can make you wonder:</p>
<p><em>How do I know when to use a greedy approach?</em> And <em>How can I be sure my solution is right?</em></p>
<p>It might feel tricky at first. But here's some good news: There are many classic problems with clear greedy solutions. By studying these problems and understanding how they're solved, you'll slowly get better at spotting when to use a greedy method and how to apply it to new challenges.</p>
<h2 id="heading-coin-problem">Coin Problem</h2>
<p>Imagine that you have an infinite supply of coins with values = {1, 2, 5, 10, 50, 100, 200} Now, someone gives you a number, let's call it N. The challenge? Figure out the fewest coins you'd need to make the exact amount of N.</p>
<p>Sounds fun, right? This problem is a classic one, and many find it a good starting point. The trick? Always choose the biggest coin that's not more than N. Once you've picked it, take it away from N, and keep going until you reach 0. Now, you might wonder, does this method always work? Well, for the coins that match our everyday money, the answer is yes!</p>
<p>Here's why our greedy coin-picking method works:</p>
<ol>
<li><p><strong>Using Bigger Coins</strong>: With coins like 1, 5, 10, 50, and 100, you'll never need more than one of each to get the best solution. Why? Well, if you tried to use two of the same coin (like two 5s), you could simply swap them out for a bigger coin (a 10) and end up with fewer coins.</p>
</li>
<li><p><strong>A Limit on Some Coins</strong>: For coins like 2 and 20, you won't need more than two of them. Three 2s can be swapped out for a 5 and a 1. Similarly, three 20s can be changed for a 50 and a 10. So, you see, there's a better way!</p>
</li>
<li><p><strong>Avoiding Inefficient Mixes</strong>: You also won't need combinations like 2 + 2 + 1 or 20 + 20 + 10 because you can just use a 5 or a 50 coin instead.</p>
</li>
<li><p><strong>Best Way with Bigger Coins</strong>: For any bigger coin, you can't make its value using only smaller coins without needing more of them. For instance, the closest you can get to 100 using smaller coins is 99 (with coins 50, 20, 20, 5, 2, and 2). So, the greedy method of always picking the biggest coin really is the best way.</p>
</li>
</ol>
<p>This example shows that it can be difficult to argue that a greedy algorithm works, even if the algorithm itself is simple.</p>
<h3 id="heading-wrong-answer-scenario">Wrong Answer Scenario</h3>
<p>I want to reiterate the fact that this solution always works for coins 1,2,5,10,50, and 100 that follow our monetary system. HOWEVER, in a general case where the set of coins can contain random values like coins = {1,3,4} and N = 6, this algorithm is going to produce the solution 4 + 1 + 1 which is incorrect, since the most optimal solution is 3 + 3. For such a problem with random coin values, we would have to implement a totally different solution using DP (Dynamic Programming)</p>
<h3 id="heading-greedy-solution-code-implementation">Greedy Solution Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-keyword">int</span> coins[<span class="hljs-number">7</span>] = {<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">5</span>,<span class="hljs-number">10</span>,<span class="hljs-number">50</span>,<span class="hljs-number">100</span>,<span class="hljs-number">200</span>};
    <span class="hljs-keyword">int</span> current = <span class="hljs-number">6</span>, coinsUsed = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">while</span>(n){
        <span class="hljs-keyword">if</span>(coins[current] &gt; n){current--; <span class="hljs-keyword">continue</span>;}
        n -= coins[current];
        coinsUsed++;
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; coinsUsed;
}
</code></pre>
<h3 id="heading-time-complexity">Time Complexity</h3>
<p>The inner operations of the loop are O(1). The loop itself is O(n) in the worst case (but keep in mind that for many values of <code>n</code>, it will run far fewer iterations than <code>n</code>). Still, the overall time complexity is O(n).</p>
<h2 id="heading-studying-algorithms-problem">Studying Algorithms Problem</h2>
<p>Here is another very easy problem to warm up.</p>
<p>Steph wants to improve her knowledge of algorithms over winter break. She has a total of X (1 ≤ X ≤ 10^4 ) minutes to dedicate to learning algorithms. There are N (1 ≤ N ≤ 100) algorithms, and each one of them requires ai (1 ≤ ai ≤ 100) minutes to learn. Find the maximum number of algorithms she can learn.</p>
<h3 id="heading-example">Example:</h3>
<p>N = 6, X = 15</p>
<p>a = {4, 3, 8, 4, 7, 3}</p>
<p>Result = 4</p>
<p>This problem is very nice since you can trust your intuition and decide to always try to do the tasks that require less time because logically it leaves more time available for the next tasks therefore maximizing the number of tasks done.</p>
<h3 id="heading-code-implementation">Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">int</span> n, x; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; x;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;arr(n); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e;
    sort(arr.begin(), arr.end());
    <span class="hljs-keyword">int</span> sum = <span class="hljs-number">0</span>, res = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:arr){
        <span class="hljs-keyword">if</span>(sum + e &gt; x)<span class="hljs-keyword">break</span>;
        sum += e;
        res++;
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; res;
}
</code></pre>
<h3 id="heading-time-complexity-1">Time Complexity</h3>
<p>The most time-consuming operation is sorting, which has a time complexity of O(n log n). The other operations are linear (O(n)) or constant (O(1)).</p>
<p>So, in simple terms, the time complexity of the code is <strong>O(n log n)</strong>.</p>
<h2 id="heading-live-saving-boats-problem">Live Saving Boats Problem</h2>
<p>Picture this: A cruise trip has gone horribly wrong, and passengers are in dire need of rescue. As part of the rescue team, your challenge is to determine the fewest number of life-saving boats needed to save everyone. However, there's a catch. Each boat can hold a maximum of two people and has a weight capacity of X (where 1 ≤ X ≤ 30,000).</p>
<p>Here's how the input is structured:</p>
<ol>
<li><p>The first line provides an integer, X, indicating the boat's maximum weight capacity.</p>
</li>
<li><p>The next line offers an integer, N (where 1 ≤ N ≤ 50,000), representing the number of passengers awaiting rescue.</p>
</li>
<li><p>This is followed by N integers specifying the weight of each individual passenger. Note that each weight, Wi, will satisfy 1 ≤ Wi ≤ X.</p>
</li>
</ol>
<h3 id="heading-example-1">Example</h3>
<p>For X=100 and N=4 with weights:</p>
<p>W = {100, 60, 60, 40}</p>
<p>The solution is 3 boats. The most efficient arrangement is:</p>
<p>{100} - Only this boat can carry a person weighing 100. {60, 40} - Together, these two don't exceed the boat's limit. {60} - The remaining passenger.</p>
<p>Remember, in real-life scenarios, efficient problem-solving can make a world of difference!</p>
<p>To solve this problem we need to be very observant, I initially thought of iterating the weights, and for each Wi try to find the pair that would take you closest to the limit X as possible without exceeding. With this idea in mind, I made a key observation to solve this problem by looking at the persons with the greatest weight. I noticed how they were often too heavy to make any pair at all, taking a whole boat to themselves and if they could form a pair it would always be the most convenient to pair them with the lightest person. This is of course very greedy and I wasn't sure if it would work but the concept appeared to give the correct result for the example test cases.</p>
<h3 id="heading-code-implementation-1">Code Implementation</h3>
<p>The solution approach that I decided to take was to sort the weights and use two pointers, one at the beginning pointing to the lightest person and one at the end pointing at the person with the most weight. While the pointers are separated, we try to pair the lightest with the heaviest, if it's not possible we simply send the heaviest person alone. Here is my code implementation for better understanding:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">int</span> x, n; <span class="hljs-built_in">cin</span> &gt;&gt; x &gt;&gt; n;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;weights(n);
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:weights)<span class="hljs-built_in">cin</span> &gt;&gt; e;
sort(weights.begin(), weights.end()); <span class="hljs-comment">// IMPORTANT</span>
<span class="hljs-keyword">int</span> boatsUsed = <span class="hljs-number">0</span>, lightest = <span class="hljs-number">0</span>, heaviest = n<span class="hljs-number">-1</span>;
<span class="hljs-keyword">while</span>(lightest &lt;= heaviest){
    <span class="hljs-keyword">if</span>(lightest == heaviest){ <span class="hljs-comment">// necesary to avoid summing twice for the following if</span>
        boatsUsed++;
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-keyword">if</span>(weights[heaviest] + weights[lightest] &gt; x){ <span class="hljs-comment">// case for when it's imposible to form a pair</span>
        boatsUsed++;
        heaviest--;
    }<span class="hljs-keyword">else</span>{ <span class="hljs-comment">// ideal case for when it's possible to form a pair.</span>
        boatsUsed++;
        lightest++;
        heaviest--;
    }
}
<span class="hljs-built_in">cout</span> &lt;&lt; boatsUsed;
</code></pre>
<p>Notice how we don't have to actually save the pairs or modify the array for the algorithm to work.</p>
<h3 id="heading-time-complexity-2">Time Complexity</h3>
<p>The code consists of:</p>
<ol>
<li><p>Reading input: <em>O</em>(<em>n</em>)</p>
</li>
<li><p>Sorting weights: <em>O</em>(<em>n</em>log<em>n</em>)</p>
</li>
<li><p>A while loop processing each passenger: <em>O</em>(<em>n</em>) worst case scenario for when all elements are too heavy and need a boat for each passenger.</p>
</li>
</ol>
<p>The dominant factor is the sorting step. Hence, the overall time complexity is <em>O</em>(<em>n</em>log<em>n</em>).</p>
<p>Now let's convince ourselves that our greedy solution works by asking ourselves the following questions:</p>
<ol>
<li><p><strong>Why start with the heaviest?</strong> If the heaviest person doesn't fit with the lightest, they won't fit with anyone else, because all other people are heavier than the lightest. So in this case, the heaviest person takes a boat alone.</p>
</li>
<li><p><strong>Why pair the heaviest with the lightest?</strong> By trying to pair the heaviest and the lightest, we aim to use the remaining space on the boat after the heaviest person efficiently. If they fit together, that's the most people we can fit on that boat (because it's only allowed two). If they don't, we already know the heaviest person should go alone.</p>
</li>
</ol>
<p>As you can tell once again, it's hard to prove that the solution is correct before submitting it but for this particular problem this solution actually outputs the most optimal and correct answer for all cases.</p>
<h2 id="heading-the-scheduling-problem">The Scheduling Problem</h2>
<p>Many problems that involve efficient usage of time can often be solved with a greedy approach, a great example of the very classic "Scheduling" problem.</p>
<p>There are N events (1 &lt;= N &lt;= 1e6). Each event is described by its starting and ending times (0 &lt;= S &lt; E &lt;= 1e9). You want to attend the maximum amount of events possible, you can only attend one at a time, and if you choose to attend an event you have to attend the entire event from beginning to end. Traveling between events is instantaneous.</p>
<p>What is the maximum number of events you can assist?</p>
<h3 id="heading-examples">Examples</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694468948801/427627db-5b65-473b-8cea-be6bd363a800.png" alt class="image--center mx-auto" /></p>
<p>In the case above you can assist events {2-4} {5-6} {7-10} which it's the maximum amount possible, if you try to assist event {1-9} you are unable to attend any other.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694469923831/ccdad958-7a42-4062-97ee-e5d8c96c7894.png" alt class="image--center mx-auto" /></p>
<p>In example 2 there are 3 combinations that give the maximum result of 2, you can assist events {1-3} {6-8}, {1-3}{3-10}, or {2-5}{6-8}.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694542181843/3f68fae2-3979-47f7-af3f-b1d49933ea53.png" alt class="image--center mx-auto" /></p>
<p>In this last example, we have more events and several solutions that have a maximum result of 4. An example of an optimal solution is: {1-4}{4-5}{5-8}{8-9}.</p>
<h3 id="heading-solution-breakdown">Solution Breakdown</h3>
<p>When I was first tasked with this problem, I immediately thought of analyzing the example cases by drawing the timeline in order to understand the relationship between the input and the correct result. By drawing the events on paper the result became easily apparent on sight. Physically drawing the events is an excellent idea for this problem in particular because when trying to draw them you are going to question if it's convenient to have them in a special order. Having the events ordered means that you can iterate the events and worry about comparing only two at a time.</p>
<h3 id="heading-algorithm-1-earliest-starting-event">Algorithm 1 - "Earliest Starting Event"</h3>
<p>In this first approach, we want to sort all the events by starting point. This means always selecting the next possible event that begins as early as possible. Let's visualize all of the examples after applying this sort.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694546710783/2002e77c-ae6e-47bd-8fa7-73c956585125.gif" alt class="image--center mx-auto" /></p>
<p>In the animation above you can see the algorithm in action for example 2. Observe how the first event is always chosen and from there, for each event you ask if it's overlapping with the last chosen event, if it is overlapping, you ignore it and continue. else you mark it as chosen. For example 2, this algorithm prints the correct result of 2, However, before concluding that this algorithm works you should first test it again with the other test examples.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694549430325/82b82e0a-c0aa-44ac-ae43-62fd676fb0d5.gif" alt class="image--center mx-auto" /></p>
<p>Amazingly this algorithm outputs 4 which is the correct result for this case as well.</p>
<p>Let's try to simulate the algorithm one last time for example 1.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694550604599/30172844-f9f1-4324-80eb-984f1b2b0d7e.gif" alt class="image--center mx-auto" /></p>
<p>This example is a very simple base case and it's clear how this algorithm breaks and no longer outputs the correct result. Looking at this example is enough to discard this sorting idea.</p>
<h3 id="heading-algorithm-2-duration">Algorithm 2 - "Duration"</h3>
<p>Once algorithm 1 was proven to be incorrect I cleared my mind and decided to think about all the previous greedy problems, remembering the problem "Studying Algorithms", As we saw previously, the solution to that problem was to always pick the tasks that required the less time because it logically allowed more time to complete other tasks.</p>
<p>With that idea in mind, I decided to try the previous algorithm for all example test cases but with the events sorted by duration.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694634316800/6f44a656-bd4c-4526-a8f4-8b58dbfb2efb.gif" alt class="image--center mx-auto" /></p>
<p>As seen in the animation above this approach gives the correct result for example 1</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694636218598/3378157d-2fe5-4b61-92a4-0071312afdab.gif" alt class="image--center mx-auto" /></p>
<p>In Example 2 however, the result is clearly incorrect, outputing 3 instead of 2. By visualizing this case in action it's very clear that this idea is not going to work, since, unlike the "learning algorithms" problem there are starting and ending points that must be taken into account. Another thing that you can look at is the fact that if you have a "group" of events and then you have a second separated group, you must make sure they don't mix during the processing. Example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694638183338/e857a286-5dee-424c-81bf-d7a0a77b741f.png" alt class="image--center mx-auto" /></p>
<p>With the illustration above you can see that the logically correct thing do to is process the events in the blue group and in a separate manner process the events that are in the red group, however, this algorithm mixes them all up.</p>
<h3 id="heading-algorithm-3-earliest-ending-event">Algorithm 3 - "Earliest Ending Event"</h3>
<p>The correct greedy approach for solving this problem is to sort the events by ending times, the logic behind this idea is that the sooner an event ends the more opportunity you have to test with more events that come after.</p>
<p>Let's visualize this approach in action for all the test cases.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694641125209/016c8dfe-844c-471e-bdd5-44f3470cdc28.gif" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694641829580/67fa83a7-2aad-47fd-982a-0ffec45209ca.gif" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694706996523/ac7a57a3-bff9-4b0f-a138-d33abcdf157a.gif" alt class="image--center mx-auto" /></p>
<p>As you can see from all of the animations above, this code outputs the correct result for all test cases.</p>
<h3 id="heading-code-implementation-2">Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">ev</span>{</span>
    <span class="hljs-keyword">int</span> start, end;
    <span class="hljs-keyword">bool</span> <span class="hljs-keyword">operator</span> &lt; (<span class="hljs-keyword">const</span> ev &amp;b)<span class="hljs-keyword">const</span>{<span class="hljs-keyword">return</span> end &lt; b.end;} <span class="hljs-comment">// sort by end</span>
};

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">notOverlap</span><span class="hljs-params">(ev a, ev b)</span></span>{
    <span class="hljs-keyword">return</span> (b.start &gt;= a.end &amp;&amp; b.end &gt; a.end) || (b.end &lt;= a.start &amp;&amp; b.start &lt; a.start);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;ev&gt; <span class="hljs-title">events</span><span class="hljs-params">(n)</span></span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:events)<span class="hljs-built_in">cin</span> &gt;&gt; e.start &gt;&gt; e.end;
    sort(events.begin(), events.end());
    <span class="hljs-keyword">if</span>(events.size() == <span class="hljs-number">1</span>){<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-number">1</span>; <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;}
    ev lastValid = events[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">int</span> res = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>;i&lt;n; i++){
        <span class="hljs-keyword">if</span>(notOverlap(lastValid, events[i])){
            lastValid = events[i];
            res++;
        }
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; res;
}
</code></pre>
<p>Notice how the events are nicely represented by a custom-made struct called "ev" that has the starting and ending times represented by integers. Notice how in that same struct we define an operator that is needed to easily sort the events by end time using the sort() procedure. The rest is really straightforward, we iterate the events array and if the last valid event and the current event do not overlap, then we set the new last valid event and increment the answer.</p>
<h3 id="heading-time-complexity-3">Time Complexity</h3>
<p>The code consists of:</p>
<ol>
<li><p>Reading input: <em>O</em>(<em>n</em>)</p>
</li>
<li><p>Sorting the events: <em>O</em>(<em>n</em>log<em>n</em>)</p>
</li>
<li><p>A for loop that processes each event: <em>O(n)</em></p>
</li>
</ol>
<p>The dominant factor is the sorting step. Hence, the overall time complexity is <em>O</em>(<em>n</em>log<em>n</em>).</p>
<h2 id="heading-flipping-consecutive-coins-problem">Flipping Consecutive Coins Problem</h2>
<p>You have <em>N (1 &lt;= N &lt;= 1000)</em> coins in a row, each showing either "1" or "0". In a single move, you can choose any <em>K (1 &lt;= K &lt;= 1000)</em> consecutive coins and flip them to their opposite side (e.g., "0" becomes "1" and vice versa).</p>
<p>Your task: Determine the minimum number of moves required to make all coins display "1". If it's impossible to achieve this, output "-1".</p>
<h3 id="heading-example-2">Example</h3>
<p>Input:</p>
<pre><code class="lang-cpp"><span class="hljs-number">5</span> <span class="hljs-number">2</span>
<span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span>
</code></pre>
<p>Output:</p>
<pre><code class="lang-cpp"><span class="hljs-number">2</span>
</code></pre>
<p>In this example there are 5 coins and K = 2, this means that you can pick any 2 consecutive coins and perform a flip, Note that you have to pick exactly 2 elements not less. for this specific initial coin layout, you can perform a flip in the range [1, 2] (zero-indexed) leaving the coins as: <code>1 1 0 0 1</code> and then do a flip in the range [2, 3] resulting in <code>1 1 1 1 1</code>, in only 2 moves, which is the minimum amount possible.</p>
<h3 id="heading-bfs-approach">BFS Approach</h3>
<p>When I first came across this problem I looked at three important points.</p>
<ol>
<li><p>The fact that N and K could have a worst case of 1000 which is a relatively small limit.</p>
</li>
<li><p>The fact that you were asked to figure out a minimum distance to state "11111..."</p>
</li>
<li><p>The statement specifies to print -1 if there is no solution.</p>
</li>
</ol>
<p>All of the points above are very classic observations for problems that can be solved using a BFS/DFS approach which I immediately tried to implement without thinking of another more simple approach.</p>
<p>If you have never heard of BFS or DFS I strongly advise you to read my <a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">BFS and DFS Beginners Overview</a> in order to understand the solution approach for this problem. However, as we'll see later on, this solution gives an MLE (Memory Limit Exeded) verdict so feel free to skip this section.</p>
<p>The way I managed to implement this solution was to visualize the way to represent a node, in this case, I figured that I could represent a coin configuration 1 0 1 0 1 as a string with no spaces "10101". With this, you can create an Adjacency list but with an unordered_map&lt;string, int&gt;. You can also represent the desired "final" node as string "11111". Lastly, the BFS algorithm logic remains the same, in which for a node, you visit the adjacent nodes and mark them as visited to avoid repeating, and by doing this you can test all possible Paths (simulate the flips) in an efficient manner, for example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694976761262/a6287ab1-847d-46a7-a2ad-f31ad0ae5032.png" alt class="image--center mx-auto" /></p>
<p>In the image above you can see that for the initial node 10101, you have 3 adjacent nodes which are the resulting states after performing the flips in ranges: [0,2], [1,3], [2,4]. the initial node always has a distance of 0 flips but for this particular problem, I decided to set it to 1 and then subtract 1 to the answer at the end, the reason being that we need 0 to represent not visited, traditionaly we used -1, but since we are working with a sting map we can't use that. The adjacent nodes are going to have a distance of the parent + 1, this way, if we get state 01001 later on we can trim that search since we know it was visited in a more optimal manner before.</p>
<pre><code class="lang-cpp"><span class="hljs-built_in">unordered_map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-keyword">int</span>&gt; dist; <span class="hljs-comment">// Adjacency List</span>

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cin</span>.tie(<span class="hljs-literal">nullptr</span>);
  <span class="hljs-built_in">std</span>::ios_base::sync_with_stdio(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">int</span> n, m; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;
  <span class="hljs-built_in">string</span> initial = <span class="hljs-string">""</span>; <span class="hljs-comment">// representing the coins as a string with no spaces</span>
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
    <span class="hljs-keyword">char</span> x; <span class="hljs-built_in">cin</span> &gt;&gt; x;
    initial += x;
  }
  <span class="hljs-built_in">queue</span>&lt;<span class="hljs-built_in">string</span>&gt; BFS;
  BFS.push(initial); <span class="hljs-comment">// starting BFS</span>
  dist[initial] = <span class="hljs-number">1</span>; <span class="hljs-comment">// starting from 1 because we need 0 to represent not visited</span>
  <span class="hljs-keyword">while</span>(BFS.size()){
    <span class="hljs-built_in">string</span> c = BFS.front(); <span class="hljs-comment">// getting current node</span>
    BFS.pop();
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;=n-m; i++){ <span class="hljs-comment">// create all possible adjacent nodes</span>
      <span class="hljs-built_in">string</span> adj = <span class="hljs-string">""</span>;
      <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;i; j++)adj += c[j];
      <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=i; j&lt;i+m; j++)adj += c[j] == <span class="hljs-string">'1'</span>?<span class="hljs-string">'0'</span>:<span class="hljs-string">'1'</span>;
      <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=i+m; j&lt;n; j++)adj += c[j];
      <span class="hljs-comment">// add node to BFS if not visited.</span>
      <span class="hljs-keyword">if</span>(dist[adj] == <span class="hljs-number">0</span>){BFS.push(adj); dist[adj] = dist[c] + <span class="hljs-number">1</span>;} 
    }
  }
  <span class="hljs-function"><span class="hljs-built_in">string</span> <span class="hljs-title">endNode</span><span class="hljs-params">(n, <span class="hljs-string">'1'</span>)</span></span>; <span class="hljs-comment">// create ending node</span>
  <span class="hljs-keyword">if</span>(dist[endNode] == <span class="hljs-number">0</span>)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-number">-1</span>; <span class="hljs-comment">// no answer case</span>
  <span class="hljs-keyword">else</span> <span class="hljs-built_in">cout</span> &lt;&lt; dist[endNode]<span class="hljs-number">-1</span>; <span class="hljs-comment">// print the minimum distance to the ending node</span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity-analisis">Time and Space Complexity Analisis</h3>
<p>Unfortunately, this solution is not the most optimal possible and gives a MLE verdict. Let's see why:</p>
<p>You're flipping <code>K</code> consecutive coins in a sequence of <code>N</code> coins, where (N = 1000). Let's consider the worst-case scenario for the number of combinations, i.e., the number of unique sequences you could generate by flipping any <code>K</code> consecutive coins.</p>
<ol>
<li><p>For a given starting position <code>i</code>, there's only one unique sequence after flipping <code>K</code> consecutive coins.</p>
</li>
<li><p>You can start flipping from position <code>i = 0</code> to <code>i = N-K</code>. This means there are (N-K+1) possible starting positions for flipping.</p>
</li>
<li><p>So, for each starting position, you get a new sequence. In the worst case, every single one of these could be unique, leading to (N-K+1) unique sequences.</p>
</li>
</ol>
<p>However, note that this is just the number of unique sequences obtained from a single flip. When you consider multiple flips, the number of unique sequences can increase dramatically as you can flip any possible segment of <code>K</code> coins in any of these sequences.</p>
<p>So, you can think of it like this:</p>
<p>From the initial state, you have (N-K+1) sequences. From each of those, you can have up to (N-K+1) more sequences and this can keep going.</p>
<p>Now, not every sequence will be unique. Some flips will revert a previous flip, and others might lead to a sequence you've already seen. But even considering that, it's clear that the potential number of combinations can explode quickly, especially as the number of flips (and hence the depth of the BFS) increases.</p>
<p>This doesn't even get us to an exact number, but you can already see how the combinations can quickly grow into the thousands or even millions, which can easily exceed memory limits. Thankfully, this solution is enough to get a partial result, but we'll see in the next section how to get a 100% score.</p>
<h3 id="heading-greedy-approach">Greedy Approach</h3>
<p>In order to spot this solution you need to think about the fact that you want all zeros to become 1, and once a value becomes 1 you don't want to modify it under any condition.</p>
<p>With this idea in mind, you can simply iterate the coin array, and if you find a 0 you HAVE to flip the range starting inclusively from that position to that position + k, repeating the process until you finish iterating the array or until you are forced to perform an impossible flip, this means that there are not enough coins for a flip to happen, for example, 1110. Notice how you would get a segmentation fault error.</p>
<p>Basically, this approach works because once we perform a flip we never look back and we will never under any condition flip a previously flipped 0 coin again meaning that it's guaranteed to be the most optimal answer possible.</p>
<p>Here is my code implementation:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n, m, res = <span class="hljs-number">0</span>; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;
  <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;arr(n); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;=n-m; i++){
    <span class="hljs-keyword">if</span>(arr[i] == <span class="hljs-number">0</span>){
      res++;
      <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=i; j &lt; i+m; j++)arr[j] = arr[j] == <span class="hljs-number">0</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>;
    }
  }
  <span class="hljs-keyword">bool</span> valid = <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:arr)<span class="hljs-keyword">if</span>(e == <span class="hljs-number">0</span>)valid = <span class="hljs-literal">false</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; (valid?res:<span class="hljs-number">-1</span>);
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; 
}
</code></pre>
<p>Notice how the handling for the impossible case is very easy to check, we just iterate the array after performing the algorithm, and if there is any 0 left, it's imposible and we should output -1, else we just print the res variable that counted the amount of flips.</p>
<h3 id="heading-time-and-space-complexity">Time and Space Complexity</h3>
<p>Reading the input: O(n) - Because you're reading 'n' numbers into the arr vector.</p>
<p>Main Loop: O(n×m) - The outer loop runs 'n' times, and for each of those, the inner loop runs 'm' times (in the worst case). So, together, it's like multiplying 'n' and 'm'.</p>
<p>Checking the result: O(n) - You're going through the arr vector again to see if all coins show "1".</p>
<p>Combine all these, and the time complexity is O(n+n×m+n), which simplifies to O(n×m).</p>
<p>For the Space complexity, we have the <strong>Vector</strong>: <em>O</em>(<em>n</em>) - The <code>arr</code> vector stores 'n' numbers and <strong>Other Variables</strong>: These just take up constant space. No matter how big 'n' or 'm' get, the space used by variables like <code>n</code>, <code>m</code>, <code>res</code>, and <code>valid</code> doesn't grow.</p>
<p>So, the space complexity is <em>O</em>(<em>n</em>). Giving us an AC verdict with a much simpler solution. 🥳</p>
<h2 id="heading-interval-flipped-coin-problem">Interval Flipped Coin Problem</h2>
<p>You have an endless row of coins, all initially showing heads. And you are given <strong><em>N</em></strong> inclusive range intervals. Write a program that outputs the fewest number of coins you need to flip to ensure there's at least one tails in each of the M intervals provided to you. (heads is represented by '0' and tails by '1')</p>
<h3 id="heading-example-3">Example</h3>
<p>input:</p>
<pre><code class="lang-plaintext">3
1 6
2 9
1 4
</code></pre>
<p>output:</p>
<pre><code class="lang-plaintext">1
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696022957531/48122ff9-3ca2-42fa-a16b-889ada0b7b7e.png" alt class="image--center mx-auto" /></p>
<p>In this example you are given 3 inclusive intervals, by drawing them, the solution becomes clear, you only need to flip 1 coin, which is the minimum amount of flips for a valid solution, in the image I flipped coin 4, however, flipping the coin 3 or 2 are also valid answers. For this problem, you don't need to print the positions of the flipped coins, only the amount.</p>
<h3 id="heading-limits">Limits</h3>
<ul>
<li><p>1 &lt;= N &lt;= 100,000</p>
</li>
<li><p>1 &lt;= i &lt;= j &lt;= 1,000,000 in which i represents the starting index and j represents the ending index to the inclusive interval.</p>
</li>
</ul>
<h3 id="heading-solution-breakdown-1">Solution Breakdown</h3>
<p>Amazingly this problem has an almost exact solution to The Scheduling Problem in which we sort all intervals by end-time.</p>
<p>The algorithm would work as follows:</p>
<ol>
<li><p>Sort the intervals by end time</p>
</li>
<li><p>Keep track of the position of the last 1/flip (initially there is none so it can be initialized with -1)</p>
</li>
<li><p>Iterate the Intervals and for each one ask if the starting point is less than the position of the last 1/flip, if true it means that the last one/flip is still within the current interval and there is no need to make any flip. If false, it means that are forced to make a flip, we choose to follow a greedy strategy by doing the flip at the end position of that interval because it is the most efficient place to target the following intervals.</p>
</li>
</ol>
<h3 id="heading-code-implementation-3">Code Implementation</h3>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">range</span>{</span>
  <span class="hljs-keyword">int</span> i, j;
  <span class="hljs-keyword">bool</span> <span class="hljs-keyword">operator</span> &lt; (<span class="hljs-keyword">const</span> range &amp;b)<span class="hljs-keyword">const</span>{
    <span class="hljs-keyword">return</span> j &lt; b.j;
  }
};

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;range&gt; <span class="hljs-title">arr</span><span class="hljs-params">(n)</span></span>;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e.i &gt;&gt; e.j;
  sort(arr.begin(), arr.end());
  <span class="hljs-keyword">int</span> lastFlip = <span class="hljs-number">-1</span>, res = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:arr){
    <span class="hljs-keyword">if</span>(e.i &gt; lastFlip){
      res++;
      lastFlip = e.j;
    }
  }
  <span class="hljs-built_in">cout</span> &lt;&lt; res;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>As you can see the solution is incredibly simple, yet it gives us the correct output every time in the most efficient way possible.</p>
<h3 id="heading-time-and-space-complexity-1">Time and Space Complexity</h3>
<p>The code consists of:</p>
<ol>
<li><p>Reading input: <em>O</em>(<em>n</em>)</p>
</li>
<li><p>Sorting the intervals: <em>O</em>(<em>n</em>log<em>n</em>)</p>
</li>
<li><p>A for loop that processes each interval: <em>O(n)</em></p>
</li>
</ol>
<p>The dominant factor is the sorting step. Hence, the overall time complexity is <em>O</em>(<em>n</em>log<em>n</em>).</p>
<p>For the space complexity, we only have to store the M intervals in an array, resulting in a space complexity of O(n).</p>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>We've journeyed through the exciting world of greedy algorithms together, learning how to spot problems that call for a greedy solution, and breaking down some classic examples. Our adventure into the code, along with its time and space analysis, hopefully gave you a clearer understanding and maybe sparked your curiosity a bit.</p>
<p>With each problem, we saw how a simple idea can lead to solutions that are both smart and efficient. We also noticed how the right approach can help find the best solutions, and how different coding choices can affect how fast our code runs and how much memory it uses.</p>
<p>Feel free to share this post with others who might be interested in diving into greedy algorithms, and don’t hesitate to drop your thoughts or questions in the comments below. Your interactions make this community a fun and enriching place to learn. Until next time, happy coding! 💻</p>
]]></content:encoded></item><item><title><![CDATA[Optimal Play: A Dynamic Programming Approach to an Array-based Turn Game"]]></title><description><![CDATA[Introduction
Hey there, fellow coders! Today, we're going to navigate through the exciting world of dynamic programming, tackling a captivating competitive programming problem along the way. We'll be stepping into the shoes of game strategists, playi...]]></description><link>https://blog.garybricks.com/optimal-play-a-dynamic-programming-approach-to-an-array-based-turn-game</link><guid isPermaLink="true">https://blog.garybricks.com/optimal-play-a-dynamic-programming-approach-to-an-array-based-turn-game</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[problem solving skills]]></category><category><![CDATA[Dynamic Programming]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Wed, 19 Jul 2023 20:32:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1689798334488/5009f424-ecfe-442e-af55-d7b740668680.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hey there, fellow coders! Today, we're going to navigate through the exciting world of dynamic programming, tackling a captivating competitive programming problem along the way. We'll be stepping into the shoes of game strategists, playing a turn-based game over an array where every decision counts.</p>
<p>Imagine this: you're playing a game where you and your opponent take turns removing elements from either end of an array. The challenge? Both of you are top-notch strategists aiming to maximize your own sums. Sounds intriguing, right?</p>
<p>So, let's roll up our sleeves, dive deep into the strategy of optimal play, and discover how we can wield the power of dynamic programming to solve this challenge. Ready to unlock a new level of your programming skills? Let's get started!</p>
<h2 id="heading-optimal-play-problem">"Optimal Play" Problem</h2>
<p>There is a very popular game that's creating quite a buzz. This two-player game revolves around a linearly arranged set of N coins, each represented by a number indicating its value. The crux of the game? To amass the maximum possible wealth. On each turn, a player can choose to take either the coin at the beginning or the end of the line. This back-and-forth continues until the last coin has been claimed.</p>
<p>In a bold move, you've invited your math teacher - a formidable opponent known for his strategic prowess - to a round of this game. Confident in his abilities, he's even let you take the first turn. Your mission, should you choose to accept, is to devise a program that, given an array of coins, predicts the maximum wealth you can amass. The catch? Both you and your teacher are playing optimally.</p>
<h3 id="heading-inputs"><strong>Inputs:</strong></h3>
<p>Your program will be receiving two lines of input:</p>
<ol>
<li><p>The first line will contain a single integer N, where 1 &lt;= N &lt;= 1000. This number represents the size of the line of coins.</p>
</li>
<li><p>The second line will contain N space-separated integers. Each of these integers represents the value of a coin in the line and will be between 1 and 1,000,000,000 (1E9), inclusive.</p>
</li>
</ol>
<h3 id="heading-outputs"><strong>Outputs:</strong></h3>
<p>Your program should output a single line containing one integer, representing the maximum amount of money you can win by playing this game optimally. Remember, you're making the first move and both you and your opponent are expected to play in the most strategic manner.</p>
<h3 id="heading-example">Example:</h3>
<p>Now that we have understood the problem, let's see an example to bring our understanding to life.</p>
<p><strong>Input:</strong></p>
<pre><code class="lang-cpp"><span class="hljs-number">5</span>
<span class="hljs-number">1</span> <span class="hljs-number">3</span> <span class="hljs-number">5</span> <span class="hljs-number">2</span> <span class="hljs-number">9</span>
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-cpp"><span class="hljs-number">15</span>
</code></pre>
<p><strong>Explanation:</strong></p>
<p>In this game, we start with a line of 5 coins with the values 1, 3, 5, 2, and 9, in that order. We take the first turn, and both we and our opponent play optimally.</p>
<ul>
<li><p>First, we take the coin with the value 9 (since it's the highest value), leaving the line as 1, 3, 5, 2.</p>
</li>
<li><p>Our opponent, playing optimally, would take 2 (leaving 1, 3, 5 as our options).</p>
</li>
<li><p>On our turn, we take the coin with value 5, leaving the line as 1, 3.</p>
</li>
<li><p>Our opponent now takes the coin with value 3, leaving only 1 in the line.</p>
</li>
<li><p>Finally, we take the last coin, which is 1.</p>
</li>
</ul>
<p>So, in total, we have taken coins of values 9, 5, and 1, summing up to 15, which is the maximum amount of money we can win in this scenario. Hence, the output is 15.</p>
<h2 id="heading-greedy-approach">Greedy Approach</h2>
<p>Upon the first encounter, this problem might seem like a cakewalk. The seemingly straightforward approach would be to opt for the largest available value at each turn and repeat the same strategy for our opponent. Essentially, we're simulating the entire game by iterating through the array in a specific order. With the time and space complexity of O(N), this approach is undoubtedly efficient.</p>
<p>The viability of this strategy shines through in our initial example and even holds up when tested on an example such as:</p>
<pre><code class="lang-cpp"><span class="hljs-number">4</span>
<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>
</code></pre>
<p>However, as the good competitive programmers that we are, we should question more if this solution is correct by trying to create an example in which this solution does not work.</p>
<pre><code class="lang-cpp"><span class="hljs-number">4</span>
<span class="hljs-number">20</span> <span class="hljs-number">30</span> <span class="hljs-number">2</span> <span class="hljs-number">2</span>
</code></pre>
<p>If we follow the greedy approach:</p>
<ul>
<li><p>We first pick 20, leaving the line as 30, 2, 2.</p>
</li>
<li><p>Then our opponent picks 30, leaving the line as 2, 2.</p>
</li>
<li><p>We pick 2, leaving the line as 2.</p>
</li>
<li><p>Lastly, our opponent picks the final 2.</p>
</li>
</ul>
<p>Here, we've ended up with coins worth 20 + 2 = 22.</p>
<p>However, if we played optimally, considering our opponent also plays optimally:</p>
<ul>
<li><p>We first pick 2 from the end, leaving the line as 20, 30, 2.</p>
</li>
<li><p>Our opponent, playing optimally, picks 20, leaving the line as 30, 2.</p>
</li>
<li><p>We pick 30, leaving the line as 2.</p>
</li>
<li><p>Lastly, our opponent picks the final 2.</p>
</li>
</ul>
<p>So, playing optimally, we would end up with coins worth 2 + 30 = 32, which is the correct and maximum achievable sum considering both players are playing optimally.</p>
<p>This example clearly demonstrates that the greedy approach doesn't always result in the best outcome, emphasizing the importance of a strategy that considers future moves and the optimal plays of the opponent.</p>
<h2 id="heading-brute-force-approach">Brute Force Approach</h2>
<p>It might be tempting to dissect the shortcomings of our initial greedy strategy until we're utterly convinced of its flaws. But really, that single example where it fell short is quite enough to nudge us away from it, encouraging us to think creatively and explore other strategies.</p>
<p>One such strategy that often comes to mind during these times is the Brute Force approach. If you're new to this concept, it's actually quite simple. All it means is that we try out every possible game scenario. Although this usually gives us the right answer, it can be a bit slow. But no worries - for now, our main aim is to find a solution that works, no matter how slow. We can always speed things up later to avoid hitting any time limits.</p>
<p>Remember, problem-solving isn't always about finding the quickest solution, but about finding a solution that works. Then, we can always improve and refine it!</p>
<h3 id="heading-implementation">Implementation</h3>
<p>Picture a maze where you're standing at the entrance, looking to navigate through different routes to find the exit. That's kind of like what we're trying to do here - explore all possible 'paths' of the game, using what's called a recursive approach.</p>
<p>Imagine each decision we make as branching off into a tree-like structure of different outcomes (See the image).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689711959867/c0afa616-1c26-4761-8f12-cf5656c42476.png" alt class="image--center mx-auto" /></p>
<p>Notice how quickly our 'decision tree' expands. But no worries, we'll tackle this size issue later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689712080529/81fe6b4d-a96d-4635-bfc4-b7a996e979fa.png" alt class="image--center mx-auto" /></p>
<p>Let's break down this decision tree, starting from the first node. Each node represents a snapshot of our game, defined as: {LeftIndex, RightIndex, Sum1, Sum2}. Here, 'Sum1' and 'Sum2' are the total values of coins you and your opponent have respectively, starting at 0. The 'LeftIndex' and 'RightIndex' mark the inclusive range of coins left to play with. At the start of the game, this range covers the whole array, hence why it starts at 0 and ends at 3.</p>
<p>Each node offers two decisions:</p>
<ul>
<li><p>Grab the coin from the left of the array, which means adding the value of the coin at 'LeftIndex' to your total (or your opponent's, depending on whose turn it is), and then moving the 'LeftIndex' one step to the right (essentially 'removing' that coin from the game).</p>
</li>
<li><p>Grab the coin from the right, which means adding the coin at 'RightIndex' to the current player's total, and then moving the 'RightIndex' one step to the left.</p>
</li>
</ul>
<p>Notice that when both indices are equal there is no need to create a new node, and we can directly add the value at the index to however the player was supposed to play on the next move.</p>
<p>Hopefully, by knowing this you can better see how the Tree represents all possible ways a game can unfold.</p>
<p>Initially, I thought of simply finding the path that maximized your sum, however, by looking at the tree, I realized that if I do that, the code is going to output 50, which is an incorrect output because of the fact that we are not considering that the opponent is guaranteed to play in the most optimal way possible.</p>
<p>This adds another layer of complexity, but no worries, it's manageable.</p>
<p>A key question here is: <em>"Can we predict the opponent's best move from any given node?"</em> If we could, we'd simply choose the opposite option, aiming to minimize the opponent's total. Let's visualize it to get a better understanding:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689712624467/dec06265-c19a-4ec4-97af-738b55e088ed.png" alt class="image--center mx-auto" /></p>
<p>Imagine you're at the purple node, deciding whether to go left or right. If we knew that the best move for the opponent would lead us to the pink node, we'd instead move to the blue node - after all, when your opponent isn't doing well, you are.</p>
<p>Unfortunately for us, there is no way for us to know the optimal play for the opponent until we have explored the full path. realizing that the only way for us to know the optimal value is by going down the tree is key because it allows us to change our perspective. Instead of trying to solve the problem from the root, we are going to start from the leaves.</p>
<p>Starting from the leaves makes a ton of sense because it's the only point in time when we know the best decision with certainty.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689716185250/f8ad850b-b787-4c78-abff-aafe3f6fddf4.gif" alt class="image--center mx-auto" /></p>
<p>In the animation above, notice how the pink nodes represent states in which is your turn, and the purple nodes represent states for the opponent. At the beginning, we start at the root node and explore to the right and then to the left for each node, we continue exploring until we reach a base case that marks when a leaf is met. The base case is very simple, it's just when the indexes are equal.</p>
<p>Observe how in the animation, it can be shown up until the point in which you have the information to fill the first two leaves 1,1 and 0,0, and now the parent 0,1 state must be filled.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689627620038/10990477-56ff-45e8-98fc-6465cf02327a.png" alt class="image--center mx-auto" /></p>
<p>We're trying to figure out what value the pink node should have. At first, we might want to generalize and think that the value for all nodes should represent the highest possible score we can get from that range of coins.</p>
<p>But when we look at the values of the two nodes beneath the pink node (its children), we only really know which option is better for us. In this situation, if we take a step to the left, the other player (the opponent) will have a chance to earn more than if we take a step to the right. So, we want to choose the option that is worse for the opponent. However, knowing this doesn't tell us what our total score will be for that range of coins. We need to think a bit harder about this problem and consider it from different angles.</p>
<p>What we can do for the value of each node is, instead of saving the maximum earning possible from a range, we save the maximum advantage possible. Let's look more into this idea.</p>
<p>Notice how the leaves stay the same since it's still the correct value with this new logic. But now let's try to fill the value for the pink node.</p>
<pre><code class="lang-cpp">val = max(-leftChild + arr[l], -rightChild + arr[r])
</code></pre>
<p>Let's break down the line above with the help of the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689704773677/bf9c62a5-574c-4f0c-aaba-ba7e5a6e12b4.png" alt class="image--center mx-auto" /></p>
<p>The left child contains the maximum advantage it can be obtained from the range [1,1], which in this case, it's 30, trivial because it's the case in which the indexes are the same. For the right child, it's the same leaf case, now with a value of 20. Now, for the pink node, we know for sure that both of the children are going to represent the maximum advantage but for the opponent, this is important, because it means that it's not going to be your advantage. This is the reason we make both children nodes negative when calculating the pink value, and of course, we must not forget to sum the value that made the left and right states happen in the first place. In this example, if we choose to go to the left child state, we would end up with a maximum advantage of -30 + 20 = -10. which is totally correct. and if we choose to go to the right, we would end up with a maximum advantage of -20 + 30 = 10. Of course, we want to maximize this value always. which means that the final value for the pink node is going to be 10.</p>
<pre><code class="lang-cpp">val = max(-leftChild + arr[l], -rightChild + arr[r])
</code></pre>
<p>Using this logic, let's fill the entire tree to see how it would end up looking.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689708503733/60bdfcbf-04ea-4459-90cc-50fba3cec376.png" alt class="image--center mx-auto" /></p>
<p>Feel free to take any node and "manually" check if the value is the maximum advantage you are going to have if you start from that node. If we take the root node [0, 3] for example, we can see we end up with an advantage of 10. Let's see why:</p>
<ul>
<li><p>We first pick 2 from the end, leaving the line as 20, 30, 2.</p>
</li>
<li><p>Our opponent, playing optimally, picks 20, leaving the line as 30, 2.</p>
</li>
<li><p>We pick 30, leaving the line as 2.</p>
</li>
<li><p>Lastly, our opponent picks the final 2.</p>
</li>
</ul>
<p>So, playing optimally, we would end up with coins worth 2 + 30 = 32, and the opponent ends up with 20 + 2 = 22.</p>
<p>If we subtract 32 - 22 = 10 we see that the value is indeed correct.</p>
<p>Excellent!, we got the difficult part out of the way, now, knowing the amount by which we beat the opponent (or lose if it's negative) we can calculate our sum using some math.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689782452261/d084f3de-aef9-4f90-a77e-9a26e7738459.png" alt class="image--center mx-auto" /></p>
<p>Let's break down the image above.</p>
<ol>
<li><p>We start by saying the total amount of coins (T) is made up of your coins (x) and the opponent's coins (y).</p>
</li>
<li><p>Next, we say your total coins (x) is made up of your opponent's coins (y) plus the extra coins you managed to snag (d). (d) = the maximum advantage by which you beat the opponent. (or lose if it's negative)</p>
</li>
<li><p>Now, we substitute the second equation (x = y + d) into the first (T = x + y). This is like saying the total coins are the same as your opponent's coins, the extra coins you gathered, plus your opponent's coins again. Sounds a bit repetitive, right? But it's crucial for our math to work!</p>
</li>
<li><p>Simplifying the above, we find that the total (T) is equal to twice your opponent's coins (2y) plus the coins you snagged extra (d). This is like saying the total coins are the same as two times your opponent's coins plus your extra coins.</p>
</li>
<li><p>Rearranging a bit, we subtract your extra coins (d) from the total (T), getting T - d = 2y. This tells us that if we take away your extra coins from the total, we're left with twice the amount of your opponent's coins.</p>
</li>
<li><p>Finally, to find your opponent's coins (y), we divide both sides of the equation by 2, which gives us y = (T - d) / 2. This is like saying your opponent's coins are half of the total coins minus your extra coins.</p>
</li>
<li><p>We now know the opponent sum, because of this finding yours is simple, it's just x = y + d</p>
</li>
</ol>
<p>And that's it! We've used algebra to solve our problem. It's like a smart way of splitting coins between you and your opponent!</p>
<h3 id="heading-coded-implementation">Coded Implementation</h3>
<p>As a recap, what we're doing in our solution is exploring every possible move in the game. We do this using a recursive approach, which allows us to create a tree-like map of all potential outcomes. Each node (or possible outcome) tells us the maximum advantage, or benefit, a player can get from a certain range of coins. We define this as:</p>
<p>{LeftIndex, RightIndex, MaximumAdvantage}.</p>
<p>Once we know the maximum advantage possible for the entire range of coins (let's call it 'd'), we can use this in our formula to calculate the final result:</p>
<p><code>((T-d)/2) + d</code></p>
<p>Below you can find my fully coded solution in C++</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> n, arr[<span class="hljs-number">1005</span>]; 

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">node</span><span class="hljs-params">(<span class="hljs-keyword">int</span> l, <span class="hljs-keyword">int</span> r)</span></span>{
    <span class="hljs-keyword">if</span>(l == r)<span class="hljs-keyword">return</span> arr[l];
    <span class="hljs-keyword">int</span> left = node(l+<span class="hljs-number">1</span>, r);
    <span class="hljs-keyword">int</span> right = node(l, r<span class="hljs-number">-1</span>);
    <span class="hljs-keyword">int</span> MaximumAdvantage = max(-left+arr[l], -right+arr[r]);
    <span class="hljs-keyword">return</span> MaximumAdvantage;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-keyword">int</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){<span class="hljs-built_in">cin</span> &gt;&gt; arr[i]; total += arr[i];}
    <span class="hljs-keyword">int</span> advantage = node(<span class="hljs-number">0</span>,n<span class="hljs-number">-1</span>); <span class="hljs-comment">// [inclusive range]</span>
    <span class="hljs-keyword">int</span> result = ((total - advantage) / <span class="hljs-number">2</span>) + advantage;
    <span class="hljs-built_in">cout</span> &lt;&lt; result;
}
</code></pre>
<p>As you can see, the code is amazingly simple and short for such a complex appearing problem, there is no need for an actual tree structure implementation with actual nodes and pointers. This is a beautiful example of recursion simplicity.</p>
<h4 id="heading-time-and-space-complexity">Time and space complexity</h4>
<p>As we saw previously, this solution explores all possible ways the game can unfold:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689789824675/ceed23dd-6c36-48e2-b931-c6e55d7764e0.png" alt class="image--center mx-auto" /></p>
<p>Notice how for each coin, we have two options - to pick the coin on the left or the right. And for each of these options, we again have two options for the next coin, and so on. Because of this, the number of possibilities we have to check grows exponentially, doubling with each decision, making the time complexity O(2^n).</p>
<p>Given that N = 1000, this code can perform up to 1.07150860718626732094842504906e+301 operations, which of course, it's waaaaaay above our usual 400,000,000 operations limit for most online judges.</p>
<p>This is, in fact, one of the most inefficient time complexities there are. With this solution, the maximum N our solution can process within the limits is approximately N = 30. any value greater than 30 will result in a TLE verdict. 😥</p>
<h2 id="heading-dp-implementation">DP Implementation</h2>
<p>What if I told you that we can drastically reduce the time it takes to solve this problem? Sounds exciting, right? The solution lies in a clever technique called Dynamic Programming (or DP, for short).</p>
<p>Think about this: while we're exploring all those different ways the game can unfold, we end up checking the same scenarios multiple times. (see image)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689792259118/ade23ee5-163b-41f0-a969-5ebdd18c04ef.png" alt class="image--center mx-auto" /></p>
<p>That's a lot of wasted effort! Dynamic Programming helps us avoid this by remembering the results of these already-solved scenarios. We call this "memoization".</p>
<p>So, let's use DP to make our program much, much faster. Instead of recalculating results we already have, we can just look them up in our "DP". This way, we save loads of time and avoid repeating work we've already done. We're about to supercharge our program, enabling it to handle more coins and perform its calculations way faster!</p>
<p>Let's see how to implement DP to our coded solution:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> n, arr[<span class="hljs-number">1005</span>];
<span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; <span class="hljs-title">DP</span><span class="hljs-params">(<span class="hljs-number">1005</span>, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;(<span class="hljs-number">1005</span>, <span class="hljs-number">-1</span>))</span></span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">node</span><span class="hljs-params">(<span class="hljs-keyword">int</span> l, <span class="hljs-keyword">int</span> r)</span></span>{
    <span class="hljs-keyword">if</span>(l == r)<span class="hljs-keyword">return</span> arr[l];
    <span class="hljs-keyword">if</span>(DP[l][r] != <span class="hljs-number">-1</span>)<span class="hljs-keyword">return</span> DP[l][r];
    <span class="hljs-keyword">int</span> left = node(l+<span class="hljs-number">1</span>, r);
    <span class="hljs-keyword">int</span> right = node(l, r<span class="hljs-number">-1</span>);
    <span class="hljs-keyword">return</span> DP[l][r] = max(-left+arr[l], -right+arr[r]);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-keyword">int</span> total = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){<span class="hljs-built_in">cin</span> &gt;&gt; arr[i]; total += arr[i];}
    <span class="hljs-keyword">int</span> advantage = node(<span class="hljs-number">0</span>,n<span class="hljs-number">-1</span>); <span class="hljs-comment">// [inclusive range]</span>
    <span class="hljs-keyword">int</span> result = ((total - advantage) / <span class="hljs-number">2</span>) + advantage;
    <span class="hljs-built_in">cout</span> &lt;&lt; result;
}
</code></pre>
<p>Did you spot the new parts? Let's break them down:</p>
<ol>
<li><p>We've got a DP 'notebook' now. It's like a big grid (or a 2D matrix) where we'll note down results so we can refer to them later. It's sized N * N because that covers all possible combinations of our coin pile indices. And see how it's filled with -1s to start with? That's because 0 could be a valid result, so we need something different to show that we haven't calculated a result yet.</p>
</li>
<li><p>We now check our 'notebook' before doing any calculations. If we've already got a result for a particular set of indices, we can just use that instead of doing all the work again. It's like saying, "Hey, we've seen this before! No need to do the same work again."</p>
</li>
<li><p>Last but not least, once we've done the calculation for a particular set of indices, we jot it down in our 'notebook' for later. It's like saying, "This could come in handy later. Better note it down."</p>
</li>
</ol>
<p>And there you have it! The same game, the same process, but now supercharged to be much faster. This shows the beauty of Dynamic Programming - the same logic, but a whole lot more efficient!</p>
<h3 id="heading-time-and-space-complexity-1">Time and Space Complexity</h3>
<p>Now that we've given our code a dynamic programming boost, you might be curious about how much faster it is and how much more space it needs. Let's look into that:</p>
<ol>
<li><p><strong>How Fast? (Time Complexity):</strong> Before, our code was taking a long time because it was checking every possible coin pick over and over again, which is why the time complexity was O(2^n). But now, thanks to our DP 'notebook', we don't do any calculations more than once. For each possible start and end of the pile (given by the indices), we calculate the result only once and then just look it up whenever needed. So, we've got 'n' possible start points and 'n' possible end points, making it n times n or 'n squared'. Therefore, our new time complexity is O(n^2), which is a whole lot faster!</p>
</li>
<li><p><strong>How Much Space? (Space Complexity):</strong> We're using a bit more memory in this new code. That's because of our DP 'notebook', the 2D matrix. It's a grid with 'n' rows and 'n' columns, so it has n times n, or 'n squared' spots to store results. So, the space complexity is O(n^2).</p>
</li>
</ol>
<p>In simple terms, we've traded a bit more space to make our program run much faster. And the best part? Now we can solve the game for up to 1,000 coins (where 'n' equals 1,000) without running into any issues since 1,000*1,000 &lt; 400,000,000.</p>
<h2 id="heading-and-thats-a-wrap-farewell"><strong>And That's a Wrap!</strong> - Farewell</h2>
<p>We've reached the end of this deep dive into Dynamic Programming (DP) and how it can supercharge your problem-solving abilities, even in a seemingly complex game like this. And remember, this is not something you'll perfect overnight, it's a skill that takes time and practice to master. So if it doesn't click right away, don't be hard on yourself. This stuff isn't easy, but I hope the walkthrough and explanations provided some clarity and a good foundation to build on.</p>
<p>Remember, we've only just scratched the surface of what DP can do. There's a whole world of interesting problems and applications waiting for you to discover, and while we covered some key concepts and methods here, there's always more to learn.</p>
<p>I hope you've enjoyed this journey as much as I have, and that you've gained some valuable insights and knowledge along the way. I would love to hear your thoughts and any questions you might have. Let me know in the comments!</p>
<p>Thanks for sticking with me till the end, and keep an eye out for more problem-solving adventures! Until next time,</p>
]]></content:encoded></item><item><title><![CDATA[2D Prefix Array And 2D Segment Tree Overview]]></title><description><![CDATA[Introduction
Hello everyone, in this post we'll be mastering the 2D prefix sum array and 2D segment Tree while we solve a very interesting competitive programming problem to better understand these structures and their capabilities.
Forest Queries Pr...]]></description><link>https://blog.garybricks.com/2d-prefix-array-and-2d-segment-tree-overview</link><guid isPermaLink="true">https://blog.garybricks.com/2d-prefix-array-and-2d-segment-tree-overview</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[data structures]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[problem solving skills]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Mon, 19 Jun 2023 22:23:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686463777494/c012e721-50fc-4ef2-ac80-fb6fa1cda5aa.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, in this post we'll be mastering the 2D prefix sum array and 2D segment Tree while we solve a very interesting competitive programming problem to better understand these structures and their capabilities.</p>
<h2 id="heading-forest-queries-problem">Forest Queries Problem</h2>
<p>You are given an n x n grid representing the map of a forest. Each square is either empty or contains a tree. The upper-left square has coordinates (1,1)(1,1), and the lower-right square has coordinates (n,n).</p>
<p>Your task is to process K queries of the form: how many trees are inside a given rectangle zone in the forest?</p>
<h3 id="heading-input">Input</h3>
<p>In the first line, you are given two integers, N and Q, where N represents the size of the forest, and Q, the number of Queries you need to answer. Then you will receive N x N characters representing the forest. '.' represents an empty space and '*' a tree.</p>
<p>Lastly, you will get Q lines in the form of x1, y1, x2, and y2 which correspond to the corners of a rectangle zone.</p>
<h3 id="heading-output">Output</h3>
<p>For each query output the amount of trees inside the rectangular zone.</p>
<h3 id="heading-limits">Limits</h3>
<ul>
<li><p>1 ≤ n ≤ 10000</p>
</li>
<li><p>1 ≤ q ≤ 200,000</p>
</li>
<li><p>1 ≤ y1 ≤ y2 ≤ n</p>
</li>
<li><p>1 ≤ x1 ≤ x2 ≤n</p>
</li>
</ul>
<h3 id="heading-iterative-solution">Iterative Solution</h3>
<p>When first tasked with this problem, the clearest solution was to iterate through every square in the rectangular zone while adding the values into a counter variable for every query. Such a solution can be implemented like this:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];

<span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x1, <span class="hljs-keyword">int</span> y1, <span class="hljs-keyword">int</span> x2, <span class="hljs-keyword">int</span> y2)</span></span>{
    ll res = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = x1; i&lt;=x2; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j = y1; j&lt;=y2; j++){
            <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>)res++;
        }
    }
    <span class="hljs-keyword">return</span> res;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, k;
    <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++)<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++)<span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
    <span class="hljs-keyword">while</span> (k--){
        <span class="hljs-keyword">int</span> x1, y1, x2, y2; <span class="hljs-built_in">cin</span> &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
        x1--; y1--; x2--; y2--;
        <span class="hljs-built_in">cout</span> &lt;&lt; query(x1, y1, x2, y2) &lt;&lt; <span class="hljs-string">"\n"</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h4 id="heading-time-complexity">Time Complexity:</h4>
<ol>
<li><p>Reading the input: The code reads the values of <code>n</code> and <code>k</code>, which takes constant time. Then it reads the <code>n x n</code> characters of the map, resulting in a time complexity of O(n^2).</p>
</li>
<li><p>Query Calculation: For each query, the code iterates over the rectangular region defined by <code>x1</code>, <code>y1</code>, <code>x2</code>, and <code>y2</code>. Since in a worst-case scenario you are prompted with x1 = 1, y1 = 1, x2 = n, y2 = n. This means that the entire map will be traversed resulting in a time complexity of O(n^2).</p>
</li>
</ol>
<p>since we have to answer 200,000 queries and each of them cost 10,000^2 that means that in a worst-case scenario, we have to compute 20,000,000,000,000 operations which exceeds the 400,000,000 limit resulting in a TLE (Time Limit Exceded) verdict.</p>
<h3 id="heading-prefix-sum-array-solution">Prefix Sum Array Solution</h3>
<p>Let's improve our solution by implementing a technic called Prefix sum Array, the way it works is that we create a helper array that stores the sum of the elements of the original array up to a certain index, basically, the value at index i is going to represent the sum of all elements from index 0 to index i in the original array. Let's see an example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686515652063/38ca4c64-32ab-49bb-bb56-1158c7cbffff.png" alt class="image--center mx-auto" /></p>
<p>Why is this useful? well, notice how the last index contains the sum of all elements from [0, 8] of the original array. Let's say you want to find the sum of all the elements between [2, 4] positions in the original array. With a prefix sum array, you can compute the sum in constant time (very fast) by subtracting two elements from the prefix sum array:</p>
<p>Sum = PrefixSum[5] - PrefixSum[2] = 12 - 5 = 7.</p>
<p>Notice how the prefix sum array has an extra zero at the beginning, this is simply to make the implementation of the queries more straightforward and avoid an index out-of-range error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686517336375/cd1ba209-644c-4743-bc91-dbc054126fa0.png" alt class="image--center mx-auto" /></p>
<p>Knowing this we can implement a prefix sum array for each row in our forest map and of course, we must change the characters to their corresponding values, 1 or 0. Here is my implementation:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];
ll mapRowPrefix[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];

<span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x1, <span class="hljs-keyword">int</span> y1, <span class="hljs-keyword">int</span> x2, <span class="hljs-keyword">int</span> y2)</span></span>{
    ll res = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = x1; i&lt;=x2; i++) res += mapRowPrefix[i][y2+<span class="hljs-number">1</span>] - mapRowPrefix[i][y1];
    <span class="hljs-keyword">return</span> res;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, q;
    <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; q;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
            <span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
            mapRowPrefix[i][j+<span class="hljs-number">1</span>] = mapRowPrefix[i][j] + (<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>);
        }
    }
    <span class="hljs-keyword">while</span> (q--){
        <span class="hljs-keyword">int</span> x1, y1, x2, y2; <span class="hljs-built_in">cin</span> &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
        x1--; y1--; x2--; y2--;
        <span class="hljs-built_in">cout</span> &lt;&lt; query(x1, y1, x2, y2) &lt;&lt; <span class="hljs-string">"\n"</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h4 id="heading-time-and-space-complexity">Time and Space Complexity</h4>
<ul>
<li>See how we are constructing the row sum prefix array at the same time that we are saving the input, this means that the time complexity for constructing the mapRowPrefix remains the same in O(n^2), however, things change with the query function, since now we only iterate the rows and we no longer have to iterate the columns, thanks to our prefix row sum array that allows us to know the result in constant O(1) time for each row.</li>
</ul>
<p>We still have to iterate through all the rows, which in a worst-case scenario it's N for each query. This means that the overall code has a time complexity of O(N^2 + (N * Q)). If we do the math this results in approximately 2,100,000,000 operations. We can clearly see an improvement compared to our previous solution, unfortunately, this still exceeds our 400,000,000 limit. 😥</p>
<h3 id="heading-2d-prefix-sum-matrix-solution">2D Prefix Sum Matrix Solution</h3>
<p>In order to solve this problem we need to make it even more optimal by using a 2D prefix sum Matrix and by doing this removing the need to iterate through the rows.</p>
<p>Since you're familiar with the concept of a prefix sum array, understanding a 2D prefix sum matrix should be straightforward. It's basically the extension of the prefix sum array concept into two dimensions.</p>
<p>Given a 2D grid (or matrix), the 2D prefix sum matrix is another 2D grid of the same size where each cell (i,j) represents the sum of all the values in the rectangle from the top-left cell (0,0) to the current cell (i,j) in the original matrix. This can be clearly understood with the help of an example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686520322514/b9628df9-265c-4b3f-a631-64399b1dacab.png" alt class="image--center mx-auto" /></p>
<p>Calculating the Prefix Sum Matrix values is very simple, notice how once again we added an extra zero at the beginning of each row and each column, this once again just makes the implementation easier since we don't have to worry about creating a special case for those values and we don't worry about index out of range errors.</p>
<p>Excluding those extra zeros, filling the rest of the prefix sum Matrix values just evaluates to summing the value on the square above, the value on the square on the left, and the original value. Then subtract the value on the adjacent top left corner like this:</p>
<pre><code class="lang-cpp">prefix2D[i][j] = prefix2D[i<span class="hljs-number">-1</span>][j] + prefix2D[i][j<span class="hljs-number">-1</span>] - prefix2D[i<span class="hljs-number">-1</span>][j<span class="hljs-number">-1</span>] + <span class="hljs-built_in">map</span>[i][j];
</code></pre>
<p>By using this 2D prefix SumMatrix we can answer each query in constant time O(1) with the following operation:</p>
<pre><code class="lang-cpp">sum = prefix2D[x2 + <span class="hljs-number">1</span>][y2 + <span class="hljs-number">1</span>] - prefix2D[x1][y2 + <span class="hljs-number">1</span>] - prefix2D[x2 + <span class="hljs-number">1</span>][y1] + prefix2D[x1][y1]
</code></pre>
<p>Knowing this allows us to solve the problem in a very efficient way, here is my code implementation:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];
ll prefix2D[<span class="hljs-number">1005</span>][<span class="hljs-number">1005</span>];

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, k;
    <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>; i&lt;=n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">1</span>; j&lt;=n; j++){
            <span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
            prefix2D[i][j] = prefix2D[i<span class="hljs-number">-1</span>][j] + prefix2D[i][j<span class="hljs-number">-1</span>] - prefix2D[i<span class="hljs-number">-1</span>][j<span class="hljs-number">-1</span>] + (<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>);
        }
    }

    <span class="hljs-keyword">while</span> (k--){
        <span class="hljs-keyword">int</span> x1, y1, x2, y2; <span class="hljs-built_in">cin</span> &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
        x1--; y1--; x2--; y2--;
        <span class="hljs-built_in">cout</span> &lt;&lt; (prefix2D[x2 + <span class="hljs-number">1</span>][y2 + <span class="hljs-number">1</span>] - prefix2D[x1][y2 + <span class="hljs-number">1</span>] - prefix2D[x2 + <span class="hljs-number">1</span>][y1] + prefix2D[x1][y1]) &lt;&lt; <span class="hljs-string">"\n"</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h4 id="heading-time-and-space-complexity-1">Time and Space Complexity</h4>
<ol>
<li><p>Constructing the <code>map</code> and <code>prefix2D</code> arrays: O(n^2). You're performing <code>n</code> operations (for each row), each of which involves <code>n</code> operations (for each column). This remains the same as the previous solutions.</p>
</li>
<li><p>Querying <code>k</code> ranges: O(k). You're performing <code>k</code> operations, each of which is a constant time operation thanks to the 2D prefix Matrix.</p>
</li>
</ol>
<p>Therefore, the overall time complexity of the program is O(n^2 + k) which evaluates to approximately 100,200,000 operations, this is well within our 400,000,000 limit that is set by most online judges.</p>
<p>This code is efficient and will get AC (Accepted) verdict. 🥳😁</p>
<h2 id="heading-forest-updates-amp-queries-problem">Forest Updates &amp; Queries Problem</h2>
<p>Let's make this problem more interesting by adding updates. In this version of the previous problem, you are going to process K actions that can either type 1 or 2.</p>
<ol>
<li><p>Change the state of a square, this means that if the square has a tree you can cut it down making the square empty, or if the square is empty you can plant a tree.</p>
</li>
<li><p>Query, the same thing as before, you are given the coordinates of a rectangle zone and you must output how many trees are completely inside the zone.</p>
</li>
</ol>
<h3 id="heading-input-1">Input</h3>
<p>In the first line, you are given the integers N and K, the size of the forest and K actions, then there are N * N characters representing the map. Finally, you are given K actions, the format of each action can either be: "1 x y" or "2 x1 y1 x2 y2".</p>
<h3 id="heading-output-1">Output</h3>
<p>For each action of type 1 you don't need to print anything, just output the answer for each query of type 2.</p>
<h3 id="heading-limits-1">Limits</h3>
<ul>
<li><p>1 ≤ n ≤ 10,000</p>
</li>
<li><p>1 ≤ q ≤ 200,000</p>
</li>
<li><p>1 ≤ y,x ≤ n</p>
</li>
<li><p>1 ≤ y1 ≤ y2 ≤ n</p>
</li>
<li><p>1 ≤ x1 ≤ x2 ≤ n</p>
</li>
</ul>
<h3 id="heading-iterative-solution-1">Iterative Solution</h3>
<p>Up until this point, you can likely implement the most simple solution that involves iterating all of the squares inside the rectangle zone query and summing the values just like we did in the previous solution, however, now we must now add the Update functionality, which for this solution is super easy since we just have to add:</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span></span>{
    <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-built_in">map</span>[x][y] == <span class="hljs-string">'*'</span>?<span class="hljs-string">'.'</span>:<span class="hljs-string">'*'</span>;
}
</code></pre>
<p>If you are not familiar with this syntaxis, don't worry, it's called a ternary operator and does exactly the same as the code cell below but in a single line 😎.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span></span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">map</span>[x][y] == <span class="hljs-string">'*'</span>) {
        <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'.'</span>;
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'*'</span>;
    }
}
</code></pre>
<p>This update solution is super efficient since it works on O(1) constant time. However, as we saw before, the query function has a time complexity of O(N^2).</p>
<h4 id="heading-time-complexity-1">Time Complexity</h4>
<p>As the competitive programmers that we are, we must assume the worst case that it's when absolutely all actions are queries and the queries ask for the sum of the entire map.</p>
<p>This means that the time complexity of this solution is going to be O(n^2 + (K * N^2)) which of course, is going to give a TLE verdict even though the updates happen in O(1) constant time.</p>
<h3 id="heading-2d-prefix-sum-matrix-solution-1">2D Prefix Sum Matrix Solution</h3>
<p>Previously we saw how this was the best solution since each query was computed in O(1) constant time. Let's see how we can adjust this structure to support updates.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y, <span class="hljs-keyword">int</span> n)</span></span>{
    <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-built_in">map</span>[x][y] == <span class="hljs-string">'*'</span> ? <span class="hljs-string">'.'</span>:<span class="hljs-string">'*'</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=x; i&lt;=n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=y; j&lt;=n; j++){
            prefix2D[i][j] = prefix2D[i<span class="hljs-number">-1</span>][j] + prefix2D[i][j<span class="hljs-number">-1</span>] - prefix2D[i<span class="hljs-number">-1</span>][j<span class="hljs-number">-1</span>] + (<span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>);
        }
    }
}
</code></pre>
<p>As you can see we update the map in the correct position and then we recalculate the matrix from that coordinate to the end.</p>
<p>This answer might look great since each query is still answered in O(1) constant time, however, if we analyze the time complexity of the update we can realize that the worst-case scenario would be if the update happens in coordinate {1, 1} because that would mean that the entire prefix2D Matrix is going to be recalculated.</p>
<h4 id="heading-time-complexity-2">Time Complexity</h4>
<p>The overall time complexity of this solution would be O(n^2 + (K * N^2)) since in the worst-case scenario all actions are updates that happen on the coordinate {1,1}.</p>
<p>This is going to give us a TLE verdict, and interestingly enough this solution has a time complexity equal to the iterative solution. 🙃😆</p>
<h3 id="heading-segment-tree-solution">Segment Tree Solution</h3>
<p>Before diving into the solution to this particular problem make absolutely sure you have read my <a target="_blank" href="https://blog.garybricks.com/segment-tree-introduction-in-c">Beginner's Segment Tree Introduction</a> since this post assumes you totally understand how this technic works and how it's implemented.</p>
<p>Basically, a segment tree allows us to know the sum of all elements in a range, it can also be used to know the minimum or maximum value in a range, and allows us to make updates, both of these operations are done in a very efficient O(log(N)) way.</p>
<p>NOTE: in computer science, we work with log in base 2.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686605984486/42d1e64e-f990-4f2a-be24-7109aa2da4b0.avif" alt class="image--center mx-auto" /></p>
<p>Above you can visualize the segment tree in action. on an array of the size shown it might not look very efficient, but when the array becomes very large it becomes clear how the segment tree makes our queries super efficient in log(N).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686606248996/1d0288e3-b6f7-4223-aabb-65d2506f526b.avif" alt class="image--center mx-auto" /></p>
<p>Above you can see the update in action, this operation is also very efficient having a time complexity of log(N).</p>
<p>Knowing this structure, we can solve the problem at hand by doing a segment tree for each row in a very similar way that we solved the first problem that didn't involve updates with a prefix sum array for each row.</p>
<p>I want to take this chance to show you a slightly different Implementation of the segment tree to the one that I showed in my <a target="_blank" href="https://blog.garybricks.com/segment-tree-introduction-in-c">Beginner's Segment Tree Introduction</a>. The logic and theory remain completely the same, but now the implementation is nicely packed in a struct. This is necessary since we are working with several segment trees.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;cmath&gt;</span></span>
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">segTree</span>{</span>
    <span class="hljs-keyword">int</span> n;
    <span class="hljs-built_in">vector</span>&lt;ll&gt;st;
    segTree(<span class="hljs-keyword">int</span> s){
        n = <span class="hljs-number">2</span> * <span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">ceil</span>(log2(s))) - <span class="hljs-number">1</span>;
        st.resize(n, <span class="hljs-number">0</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> newV)</span></span>{
        i += n/<span class="hljs-number">2</span>;
        st[i] += newV;
        <span class="hljs-keyword">while</span> (i){
            i = (i<span class="hljs-number">-1</span>)/<span class="hljs-number">2</span>;
            st[i] = st[i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>] + st[i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>];
        }
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> l, <span class="hljs-keyword">int</span> r, <span class="hljs-keyword">int</span> i)</span></span>{
        <span class="hljs-keyword">if</span>(l &gt;= qr || r &lt;= ql)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        <span class="hljs-keyword">if</span>(l &gt;= ql &amp;&amp; r &lt;= qr)<span class="hljs-keyword">return</span> st[i];
        <span class="hljs-keyword">int</span> mid = (l+r)/<span class="hljs-number">2</span>;
        <span class="hljs-keyword">return</span> query(ql, qr, l, mid, i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>) + query(ql, qr, mid, r, i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>);
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr)</span></span>{
        <span class="hljs-keyword">return</span> query(ql, qr, <span class="hljs-number">0</span>, n/<span class="hljs-number">2</span>+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);
    }

    <span class="hljs-comment">// void print(){for(auto e:st)cout &lt;&lt; e &lt;&lt; " "; cout &lt;&lt; endl;}</span>
};

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, k; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
    <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;segTree&gt; <span class="hljs-title">mapSTrees</span><span class="hljs-params">(n, segTree(n))</span></span>;
    <span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[n][n];
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
            <span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
            mapSTrees[i].update(j, <span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>);
        }
        <span class="hljs-comment">// rowST.print();</span>
    }
    <span class="hljs-keyword">while</span> (k--){
        <span class="hljs-keyword">int</span> action; <span class="hljs-built_in">cin</span> &gt;&gt; action;
        <span class="hljs-keyword">if</span>(action == <span class="hljs-number">1</span>){
            <span class="hljs-keyword">int</span> x, y; <span class="hljs-built_in">cin</span> &gt;&gt; x &gt;&gt; y;
            x--, y--;
            <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[x][y] == <span class="hljs-string">'*'</span>){
                mapSTrees[x].update(y, <span class="hljs-number">-1</span>);
                <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'.'</span>;
            }<span class="hljs-keyword">else</span> {
                mapSTrees[x].update(y, <span class="hljs-number">1</span>);
                <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'*'</span>;
            }
        }<span class="hljs-keyword">else</span>{
            <span class="hljs-keyword">int</span> x1, y1, x2, y2; <span class="hljs-built_in">cin</span> &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
            x1--,y1--,x2--,y2--;
            ll res = <span class="hljs-number">0</span>;
            <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> row=x1; row &lt;= x2; row++){
                res += mapSTrees[row].query(y1,y2+<span class="hljs-number">1</span>);
            }
            <span class="hljs-built_in">cout</span> &lt;&lt; res &lt;&lt; <span class="hljs-string">"\n"</span>;
        }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Notice how everything is the same as in my post except for two minor changes.</p>
<ol>
<li><p>Getting the size of the segment tree is now done in a single line with the help of the following formula<code>: 2 * pow(2, ceil(log2(n))) - 1;</code></p>
</li>
<li><p>There are two query methods, one of them is responsible for actually calculating the answer with recursion and 5 parameters, and the other is just the public interface that only takes two arguments. This is simply to make the usage of the function easy for the user.</p>
</li>
</ol>
<h4 id="heading-time-and-space-complexity-2">Time and Space Complexity</h4>
<ol>
<li><p>The building of each segment tree (performed in the segTree constructor) has a time complexity of O(n), where n is the size of the input array (or the row/column length of the map, in this case). This operation happens n times (once per row), leading to an overall time complexity of O(n^2).</p>
</li>
<li><p>The 'update' operation, where an element of the array is modified and the segment tree is subsequently updated, has a time complexity of O(log n). This operation might be performed n times within the 'k' operations, hence the worst-case time complexity would be O(k log n).</p>
</li>
<li><p>The 'query' operation, where a subarray sum is calculated, also has a time complexity of O(log n). In the worst-case scenario, this operation might be performed for all rows of the map within the 'k' operations, leading to an overall worst-case time complexity of O(nk log n).</p>
</li>
</ol>
<p>Combining all of these operations, the overall time complexity in the worst-case scenario is O(n^2 + nk log n), which is about 28,100,000,000 operations. This solution finally shows improvement but it's still not efficient enough to avoid the TLE verdict.</p>
<h3 id="heading-2d-segment-tree-solution">2D Segment Tree Solution</h3>
<p>In a very similar way to the first problem in which we used a 2D prefix sum Matrix to avoid iterating over the rows, we need to apply that same optimization concept to this problem by using a 2D Segment Tree like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686686366805/360d50c9-59ec-4ab8-8af1-6fa60e1131be.png" alt class="image--center mx-auto" /></p>
<p>This is where having a nicely packed segment tree struct is extremely useful. In order to implement a 2D version we are going to create another additional structure that uses the 1D previously created version.</p>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">segTree2D</span>{</span>
    <span class="hljs-keyword">int</span> n;
    <span class="hljs-built_in">vector</span>&lt;segTree&gt; st;
    segTree2D(<span class="hljs-keyword">int</span> s){
        n = <span class="hljs-number">2</span> * <span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">ceil</span>(log2(s)))<span class="hljs-number">-1</span>;
        st.resize(n, segTree(s));
    }

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y, <span class="hljs-keyword">int</span> newV)</span></span>{
        x += n/<span class="hljs-number">2</span>;
        st[x].update(y, newV);
        <span class="hljs-keyword">while</span> (x){
            x = (x<span class="hljs-number">-1</span>)/<span class="hljs-number">2</span>;
            st[x].update(y, newV);
        } 
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> qt, <span class="hljs-keyword">int</span> qb, <span class="hljs-keyword">int</span> t, <span class="hljs-keyword">int</span> b, <span class="hljs-keyword">int</span> i)</span></span>{
        <span class="hljs-keyword">if</span>(t &gt;= qb || b &lt;= qt)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        <span class="hljs-keyword">if</span>(t &gt;= qt &amp;&amp; b &lt;= qb)<span class="hljs-keyword">return</span> st[i].query(ql, qr);
        <span class="hljs-keyword">int</span> mid = (t+b)/<span class="hljs-number">2</span>;
        <span class="hljs-keyword">return</span> query(ql, qr, qt, qb, t, mid, i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>) + query(ql, qr, qt, qb, mid, b, i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>);
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> qt, <span class="hljs-keyword">int</span> qb)</span></span>{
        <span class="hljs-keyword">return</span> query(ql, qr, qt, qb, <span class="hljs-number">0</span>, n/<span class="hljs-number">2</span>+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);  
    }
};
</code></pre>
<p>Notice how this 2D segment Tree has all the same methods that the 1D version, we have the initialization:</p>
<pre><code class="lang-cpp"><span class="hljs-built_in">vector</span>&lt;segTree&gt; st;
segTree2D(<span class="hljs-keyword">int</span> s){
    n = <span class="hljs-number">2</span> * <span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">ceil</span>(log2(s)))<span class="hljs-number">-1</span>;
    st.resize(n, segTree(s));
}
</code></pre>
<p>Notice how instead of the array of ints, we now have an array of segment trees, also, when we resize the vector we initialize the 1D segment trees at the same time <code>st.resize(n, segTree(s));</code></p>
<p>The query works exactly the same but only over the rows, I like to manage the two pointers as top and bottom, and when the range is completely inside the range we access that particular segment tree and we perform the query for Left and Right.</p>
<p>Lastly, the update, in this case, is very simple because it's a <strong>sum</strong> segment tree, we just access the corresponding segment tree to the x row, we update the value in the y position on that array, and then we return until we reach the root at the same time that we update the value on the y axis of each segment tree along the way. However, keep in mind that min or max segment tree versions are much different.</p>
<h4 id="heading-time-and-space-complexity-3">Time and Space Complexity</h4>
<ul>
<li><p>For the <code>update</code> operation, the time complexity is O(log n). In the worst-case scenario, the update operation affects elements all the way up the segment tree, which has a height of log n.</p>
</li>
<li><p>For the <code>query</code> operation, the time complexity is O(log(n)^2). This is because the query operation may need to traverse the tree in two dimensions: once for the row and once for the column. In the worst-case scenario, this traversal happens over a height of log n in each dimension, resulting in a total time complexity of O(log(n)^2).</p>
</li>
</ul>
<p>These complexities hold true assuming that the underlying 1D segment tree (<code>segTree</code>) operations (<code>update</code> and <code>query</code>) have time complexities of O(log n).</p>
<p>The overall Time complexity of this algorithm is O(N^2 + (q * (log(N)^2))) which results in approximately 100,000,000 + (200,000 * 196) = 139,200,000 operations which is well within our limit.</p>
<h3 id="heading-ac-full-code">AC - Full Code</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;cmath&gt;</span></span>
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">segTree</span>{</span>
    <span class="hljs-keyword">int</span> n;
    <span class="hljs-built_in">vector</span>&lt;ll&gt;st;
    segTree(<span class="hljs-keyword">int</span> s){
        n = <span class="hljs-number">2</span> * <span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">ceil</span>(log2(s)))<span class="hljs-number">-1</span>;
        st.resize(n, <span class="hljs-number">0</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> newV)</span></span>{
        i += n/<span class="hljs-number">2</span>;
        st[i] += newV;
        <span class="hljs-keyword">while</span> (i){
            i = (i<span class="hljs-number">-1</span>)/<span class="hljs-number">2</span>;
            st[i] = st[i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>] + st[i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>];
        }
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> l, <span class="hljs-keyword">int</span> r, <span class="hljs-keyword">int</span> i)</span></span>{
        <span class="hljs-keyword">if</span>(l &gt;= qr || r &lt;= ql)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        <span class="hljs-keyword">if</span>(l &gt;= ql &amp;&amp; r &lt;= qr)<span class="hljs-keyword">return</span> st[i];
        <span class="hljs-keyword">int</span> mid = (l+r)/<span class="hljs-number">2</span>;
        <span class="hljs-keyword">return</span> query(ql, qr, l, mid, i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>) + query(ql, qr, mid, r, i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>);
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr)</span></span>{
        <span class="hljs-keyword">return</span> query(ql, qr, <span class="hljs-number">0</span>, n/<span class="hljs-number">2</span>+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);
    }
};

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">segTree2D</span>{</span>
    <span class="hljs-keyword">int</span> n;
    <span class="hljs-built_in">vector</span>&lt;segTree&gt; st;
    segTree2D(<span class="hljs-keyword">int</span> s){
        n = <span class="hljs-number">2</span> * <span class="hljs-built_in">pow</span>(<span class="hljs-number">2</span>, <span class="hljs-built_in">ceil</span>(log2(s)))<span class="hljs-number">-1</span>;
        st.resize(n, segTree(s));
    }

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y, <span class="hljs-keyword">int</span> newV)</span></span>{
        x += n/<span class="hljs-number">2</span>;
        st[x].update(y, newV);
        <span class="hljs-keyword">while</span> (x){
            x = (x<span class="hljs-number">-1</span>)/<span class="hljs-number">2</span>;
            st[x].update(y, newV);
        } 
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> qt, <span class="hljs-keyword">int</span> qb, <span class="hljs-keyword">int</span> t, <span class="hljs-keyword">int</span> b, <span class="hljs-keyword">int</span> i)</span></span>{
        <span class="hljs-keyword">if</span>(t &gt;= qb || b &lt;= qt)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        <span class="hljs-keyword">if</span>(t &gt;= qt &amp;&amp; b &lt;= qb)<span class="hljs-keyword">return</span> st[i].query(ql, qr);
        <span class="hljs-keyword">int</span> mid = (t+b)/<span class="hljs-number">2</span>;
        <span class="hljs-keyword">return</span> query(ql, qr, qt, qb, t, mid, i*<span class="hljs-number">2</span>+<span class="hljs-number">1</span>) + query(ql, qr, qt, qb, mid, b, i*<span class="hljs-number">2</span>+<span class="hljs-number">2</span>);
    }

    <span class="hljs-function">ll <span class="hljs-title">query</span><span class="hljs-params">(<span class="hljs-keyword">int</span> ql, <span class="hljs-keyword">int</span> qr, <span class="hljs-keyword">int</span> qt, <span class="hljs-keyword">int</span> qb)</span></span>{
        <span class="hljs-keyword">return</span> query(ql, qr, qt, qb, <span class="hljs-number">0</span>, n/<span class="hljs-number">2</span>+<span class="hljs-number">1</span>, <span class="hljs-number">0</span>);  
    }
};

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-built_in">cin</span>.tie(<span class="hljs-literal">nullptr</span>);
    ios_base::sync_with_stdio(<span class="hljs-literal">false</span>);
    <span class="hljs-keyword">int</span> n, k; <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
    <span class="hljs-function">segTree2D <span class="hljs-title">SegTreeMap</span><span class="hljs-params">(n)</span></span>;
    <span class="hljs-keyword">char</span> <span class="hljs-built_in">map</span>[n][n];
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
            <span class="hljs-built_in">cin</span> &gt;&gt; <span class="hljs-built_in">map</span>[i][j];
            SegTreeMap.update(i, j, <span class="hljs-built_in">map</span>[i][j] == <span class="hljs-string">'*'</span>?<span class="hljs-number">1</span>:<span class="hljs-number">0</span>);
        }
    }
    <span class="hljs-keyword">while</span> (k--){
        <span class="hljs-keyword">int</span> action; <span class="hljs-built_in">cin</span> &gt;&gt; action;
        <span class="hljs-keyword">if</span>(action == <span class="hljs-number">1</span>){
            <span class="hljs-keyword">int</span> x, y; <span class="hljs-built_in">cin</span> &gt;&gt; x &gt;&gt; y;
            x--, y--;
            <span class="hljs-keyword">if</span>(<span class="hljs-built_in">map</span>[x][y] == <span class="hljs-string">'*'</span>){
                SegTreeMap.update(x, y, <span class="hljs-number">-1</span>);
                <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'.'</span>;
            }<span class="hljs-keyword">else</span> {
                SegTreeMap.update(x, y, <span class="hljs-number">1</span>);
                <span class="hljs-built_in">map</span>[x][y] = <span class="hljs-string">'*'</span>;
            }
        }<span class="hljs-keyword">else</span>{
            <span class="hljs-keyword">int</span> x1, y1, x2, y2; <span class="hljs-built_in">cin</span> &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
            x1--,y1--,x2--,y2--;
            <span class="hljs-built_in">cout</span> &lt;&lt; SegTreeMap.query(y1, y2+<span class="hljs-number">1</span>, x1, x2+<span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-string">"\n"</span>;
        }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>Competitive programming is vast and filled with seemingly endless complexities. Yet, as we explored these two problems, we realized that even the most intricate challenges have a variety of viable solutions, each with its own efficiency and uniqueness.</p>
<p>Iterative methods, prefix sum arrays, 2D prefix sum matrices, segment trees, and even their 2D counterparts - all these approaches offer unique insights into problem-solving, and I hope this post made you better understand the capabilities of each technic.</p>
<p>Remember, there is no one-size-fits-all solution in programming. The 'best' solution depends heavily on the problem at hand, the constraints we're working within, and, not least, your own creativity and understanding. Continue to explore, to learn, and to challenge yourself - every problem you encounter is an opportunity to grow.</p>
<p>I invite you to delve deeper, to question, and to play with the various strategies we've discussed. They're merely tools in your programming arsenal, and their real power is realized in their application.</p>
<p>Thank you for joining me on this journey. Keep the spirit of learning alive, and I hope to see you in future posts.</p>
<p>Let me know your thoughts and suggestions in the comment section below and wish you happy coding.</p>
]]></content:encoded></item><item><title><![CDATA[Unveiling Dynamic Programming Solutions for 'Roads' and 'Organizing Tiles' Problems.]]></title><description><![CDATA[Introduction
Hello everyone, in this post we will look in detail at the solution to two similar, very classic DP problems: 'Roads' and 'Organizing Tiles', as well as their implementation in C++, altho the solution can be implemented in the language o...]]></description><link>https://blog.garybricks.com/unveiling-dynamic-programming-solutions-for-roads-and-organizing-tiles-problems</link><guid isPermaLink="true">https://blog.garybricks.com/unveiling-dynamic-programming-solutions-for-roads-and-organizing-tiles-problems</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[Dynamic Programming]]></category><category><![CDATA[C++]]></category><category><![CDATA[problem solving skills]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Sun, 11 Jun 2023 00:54:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686169601316/99be8fbb-2310-4c60-a584-7931afca4c61.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, in this post we will look in detail at the solution to two similar, very classic DP problems: 'Roads' and 'Organizing Tiles', as well as their implementation in C++, altho the solution can be implemented in the language of your choice.</p>
<h2 id="heading-organizing-tiles-problem">'Organizing Tiles' Problem</h2>
<p>In this problem we need to imagine a rectangular table of size N x 2, this table needs to be completely covered with tiles of size 2 x 1 in such a way that all tiles are completely inside the table and do not overlap, the image below shows all possible valid coverings for a table where N = 4.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686170244466/b0d62035-043a-4c4e-844f-f43a24893875.png" alt class="image--center mx-auto" /></p>
<p>you are given T test cases and for each case a single line: N. Output the number of valid ways for covering a grid of size 2 x N.</p>
<h3 id="heading-inputs">Inputs</h3>
<p>The first line contains T, the following T lines contain a single integer: N.</p>
<h3 id="heading-output">Output</h3>
<p>for each test case output the answer, since the answer can be very large make sure to apply MOD 1,000,000.</p>
<h3 id="heading-limits">Limits</h3>
<ul>
<li><p>0 &lt;= N &lt;= 1,000,00</p>
</li>
<li><p>1 &lt;= T &lt;= 10,000</p>
</li>
</ul>
<h2 id="heading-organizing-tiles-solution">'Organizing Tiles' Solution</h2>
<p>The first big observation for this problem that we should make is to notice that the height of the table is set to 2 always no matter N, this means that we must only be concerned with the length. Knowing this, a great idea is to manually test and solve the problem as a human for n = 1, n = 2, n = 3, and n = 4. This process can be easily done by drawing all the valid ways we can cover the grid for each N on a notebook.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686247952104/77c848de-710b-49bd-8c30-318d23fbf221.png" alt class="image--center mx-auto" /></p>
<p>By doing these drawings, you can clearly see that it's impossible for a valid solution to contain something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686248908932/27f8bd80-4082-4812-8a4a-3ffacb1123af.png" alt class="image--center mx-auto" /></p>
<p>At first sight of the examples, it appears to not have any sort of pattern with the shapes, by observing the coverings for longer we can realize that the shapes themselves don't provide any information in order to predict another N. Because of this we should only pay attention to the number of coverings possible instead of the shapes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686253114174/08e27fad-7c5b-4bd3-8d40-d22de400caf8.png" alt class="image--center mx-auto" /></p>
<p>Keeping the idea that the only thing that varies is the length, I started to wonder how can I know the solution for position 5 (1st indexed) without using the drawing method. To answer this question I began by only wondering the amount of ways we can fill that specific index.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686254369740/2280b007-293b-48d3-87b1-2f6203785210.png" alt class="image--center mx-auto" /></p>
<p>Here is where the interesting solution starts to show. Notice how we have two ways of covering that index. Logically, if we want to know the ways to fill the entire table we should add the possibilities of the remaining space of the first way, with the possibilities of the remaining space of the second. This is looking like a recursive solution, and like most recursive functions we need some base conditions to end it. This case is very easy since we know the answer for N = 0, N = 1, and N = 2;</p>
<h3 id="heading-recursive-implementation">Recursive Implementation</h3>
<p>Below you can find my implementation of the recursive function that solves for N.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
<span class="hljs-function">ll <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> n)</span></span>{
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">1</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">2</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">2</span>;
    <span class="hljs-keyword">return</span> (solve(n<span class="hljs-number">-1</span>) + solve(n<span class="hljs-number">-2</span>)) % MOD;
}
</code></pre>
<p>Once we code the line <code>solve(n-1) + solve(n-2);</code> it becomes obvious that this code is calculating the Fibonacci sequence. Notice how we are using long long, this is important since the answer can become large, thankfully the problem asks us to apply MOD.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Fibonacci_Spiral.svg/300px-Fibonacci_Spiral.svg.png" alt="Fibonacci sequence - Wikipedia" class="image--center mx-auto" /></p>
<p>The slight problem with this implementation is that for every N query, the recursion will be redone until one of the base conditions is fulfilled, this is very inefficient. however, we can use DP (Dynamic Programming) to compute the solution for N so that if it at some moment N gets repeated we can simply return the pre-computed answer.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
ll DP[<span class="hljs-number">1e6</span> + <span class="hljs-number">5</span>], MOD = <span class="hljs-number">1e6</span>;
<span class="hljs-function">ll <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> n)</span></span>{
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">0</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">1</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span>(n == <span class="hljs-number">2</span>)<span class="hljs-keyword">return</span> <span class="hljs-number">2</span>;
    <span class="hljs-keyword">if</span>(DP[n]) <span class="hljs-keyword">return</span> DP[n];
    <span class="hljs-keyword">return</span> DP[n] = (solve(n<span class="hljs-number">-1</span>) + solve(n<span class="hljs-number">-2</span>))%MOD;
}
</code></pre>
<p>in the code cell above you can see the DP container added, now in our solve function, if a solution for N is already computed in the DP we return the value, else, we compute the solution and save it to the DP.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">return</span> DP[n] = solve(n<span class="hljs-number">-1</span>) + solve(n<span class="hljs-number">-2</span>);
</code></pre>
<p>this is a fancy way of assigning the answer to the DP and returning the value in a single line.</p>
<h3 id="heading-iterative-solution">Iterative Solution</h3>
<p>since the solution to this problem is simply to calculate the Fibonacci sequence, there is no need to use recursion, and you can do something iterative like this:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
<span class="hljs-built_in">vector</span>&lt;ll&gt;fib = {<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">2</span>};
ll MOD = <span class="hljs-number">1e6</span>;
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    ll n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-keyword">for</span>(ll i = <span class="hljs-number">2</span>; i &lt;= <span class="hljs-number">1e6</span> + <span class="hljs-number">5</span>; i++){
        fib.push_back((fib[i]+fib[i<span class="hljs-number">-1</span>])%MOD);
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; fib[n]%MOD;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity">Time and Space Complexity</h3>
<h4 id="heading-recursive-solution">Recursive Solution</h4>
<ul>
<li><p>Time Complexity: The time complexity of this algorithm is O(n), where <code>n</code> is the input to the function. This is because each function call to solve for a particular value of <code>n</code> is made only once due to memoization. Once <code>solve(n)</code> is calculated, its value is stored in the DP array. Therefore, the total number of operations is linear with respect to the input size, leading to a time complexity of O(n).</p>
</li>
<li><p>Space Complexity: The space complexity of this algorithm is also O(n), where <code>n</code> is the input to the function. This is because an array of size <code>n</code> (specifically n + 5, but we ignore constants in Big O notation) is created to store the results of the function for each possible value of n from 0 to n. Thus, the amount of memory used scales linearly with the size of the input, leading to a space complexity of O(n).</p>
</li>
</ul>
<h4 id="heading-iterative-solution-1">Iterative Solution</h4>
<ol>
<li><p>Time Complexity: The time complexity of this code is O(n), where <code>n</code> is the maximum number for which you want to compute the Fibonacci number. This is because there is a loop that iterates <code>n</code> times, and within each iteration, you perform a constant amount of work: retrieving two elements from the vector, adding them, taking the modulus, and appending the result to the vector. All of these operations are assumed to take constant time. Thus, the total amount of work done is proportional to <code>n</code>, leading to a time complexity of O(n).</p>
</li>
<li><p>Space Complexity: The space complexity of the code is also O(n). This is due to the <code>fib</code> vector, which stores <code>n</code> elements. Since the amount of space used by the vector scales linearly with <code>n</code>, the space complexity is O(n).</p>
</li>
</ol>
<h2 id="heading-roads-problem">'Roads' Problem</h2>
<p>Imagine that there is a city represented by a rectangular grid of size H * W, where H is the height of the grid and W is the width. (See picture)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686420470347/249c18cd-0efa-4900-aec9-a5e575115d3b.png" alt class="image--center mx-auto" /></p>
<p>Jhon lives in the left top corner of block {0, 0}. you need to help him figure out the number of ways he can reach his parent's house which is located in the bottom right corner of the grid, by only moving to either right or down.</p>
<p>Note: Jhon moves through the "roads" which are represented by the edge of the block, for better understanding look at the picture below in which W = 1 and H = 1;</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686421535667/4e8becdd-ec2a-4e40-bbf3-558477e30baf.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-inputs-1">Inputs</h3>
<p>The first and only line contains integers W and H, representing the height of the grid,</p>
<h3 id="heading-output-1">Output</h3>
<p>Your code must output a single integer, the number of distinct ways for Jhon to reach his parent's house.</p>
<h3 id="heading-limits-1">Limits</h3>
<ul>
<li>1 &lt;= W, H &lt;= 30</li>
</ul>
<h2 id="heading-roads-solution">'Roads' Solution</h2>
<p>As we usually do when solving a problem, it's a good idea to solve the problem as a human for a couple of examples with the help of a notebook and make drawings of all paths to better understand the relationship between input and output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686424348972/91510332-4e18-4162-a640-4ed0b5a4da0b.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-recursive-solution-1">Recursive Solution</h3>
<p>When doing this manual process we can figure out a first brute-force approach of trying all possible paths. This can be done with a recursive function solve(int x, int y) that tries the two different paths solve(int x + 1, y) + solve(int x, int y + 1);</p>
<p>Let's see how such a solution can be implemented.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
<span class="hljs-keyword">int</span> w, h;

<span class="hljs-function">ll <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span></span>{
    <span class="hljs-keyword">if</span>(x &gt; w || y &gt; h)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(x == w &amp;&amp; y == h)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">return</span> solve(x+<span class="hljs-number">1</span>, y) + solve(x, y+<span class="hljs-number">1</span>);
}


<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; w &gt;&gt; h;
    <span class="hljs-built_in">cout</span> &lt;&lt; solve(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>as you can see the solve solution only uses three lines of code, one condition to see if we have reached the bottom right corner (therefore a path exists), and we also check if it's inside the bounds of the map.</p>
<p>Unfortunately, because this code tries all different paths possible, it means that the Time Complexity In the worst case is O(2^(w+h)) because the function <code>solve</code> will be called for every possible pair <code>(x, y)</code> where <code>x</code> is in the range <code>[0, w]</code> and <code>y</code> is in the range <code>[0, h]</code>. However, due to the nature of the recursive calls (moving right or down), many of these calls will be made multiple times for the same pair of coordinates, leading to a large number of redundant operations. This, of course, is exponential. Given that W and H can be up to 30 this means that approximately 2^60 operations are going to be computed, which of course exceed the 400,000,000 operations that are normally the limit for most online judges. This solution is going to receive a TLE (Time Limit Exceded) verdict. However, because there are repeated solve(x, y) calls, it means that we can apply DP.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;
ll w, h, DP[<span class="hljs-number">31</span>][<span class="hljs-number">31</span>];

<span class="hljs-function">ll <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span></span>{
    <span class="hljs-keyword">if</span>(x &gt; w || y &gt; h)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(x == w &amp;&amp; y == h)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span>(DP[x][y])<span class="hljs-keyword">return</span> DP[x][y];
    <span class="hljs-keyword">return</span> DP[x][y] = solve(x+<span class="hljs-number">1</span>, y) + solve(x, y+<span class="hljs-number">1</span>);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; w &gt;&gt; h;
    <span class="hljs-built_in">cout</span> &lt;&lt; solve(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>by doing this very slight code addition we are Reducing Redundant Calculations, In the previous version of the code, the same calculations were performed many times due to overlapping sub-problems. For example, both <code>solve(1, 2)</code> and <code>solve(2, 1)</code> would end up recursively calculating the result for <code>solve(2, 2)</code>, among other overlapping calculations. This redundancy leads to an exponential time complexity, which is highly inefficient. However, with DP, the result of each unique call to <code>solve(x, y)</code> is stored in the <code>DP[x][y]</code> array after it's calculated for the first time. Then, if <code>solve(x, y)</code> is called again, the function will first check if <code>DP[x][y]</code> is non-zero, and if so, it will immediately return this stored result instead of re-calculating it. By applying this technic we managed to reduce the 2^60 operation to just 60 🤯.</p>
<h3 id="heading-iterative-solution-2">Iterative Solution</h3>
<p>Altho the previous solution is already enough to receive an AC verdict (accepted) it is not the only correct implementation to get it. I made this very cool observation when printing out the DP from the previous solution:</p>
<pre><code class="lang-markdown">35 15 5 1 
20 10 4 1 
10 6 3 1 
4 3 2 1 
1 1 1 0
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686433956628/36b133b1-ce70-44e0-86fe-9a8d98342f76.png" alt class="image--center mx-auto" /></p>
<p>First of all, notice how the orientation of the table does not matter. Then, if we look closely the value clearly represents the number of ways for reaching a certain point if we start from the end which happens to always be the sum of the ways we can reach the cell below, with the ways we can reach the cell in the right. This makes a lot of sense, since if we can reach point A in 20 ways, and point B in 5, and we want to know the number of ways we can reach point C, it's trivial that it's the sum of 20 + 5.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686442216213/e776933e-5310-4c27-b214-57b13dacba7f.png" alt class="image--center mx-auto" /></p>
<p>By knowing this, we can initialize a DP matrix in which all the values in the first row and the first column are set to 1, this is going to be our base case since as we can confirm in our image there is always 1 way only to reach any of the points of the first row and the first column. (see image)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686443093583/b3a0cb96-e66e-4ad5-9cb1-0e0903dffb8a.png" alt class="image--center mx-auto" /></p>
<p>Then we can fill the rest of the table by iterating square by square and making the value of the point equal to the ways we can reach the point above, with the ways we can reach the point on the left. Lastly, we can just access the point {H, W}.</p>
<p>Here is my code implementation:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    ll H, W; <span class="hljs-built_in">cin</span> &gt;&gt; H &gt;&gt; W;
    ll DP[H+<span class="hljs-number">1</span>][W+<span class="hljs-number">1</span>];
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;=W; i++)DP[<span class="hljs-number">0</span>][i] = (ll)<span class="hljs-number">1</span>; <span class="hljs-comment">// filling the first row</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;=H; i++)DP[i][<span class="hljs-number">0</span>] = (ll)<span class="hljs-number">1</span>; <span class="hljs-comment">// filling the first column</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>; i&lt;=H; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">1</span>; j&lt;=W; j++){
            DP[i][j] = DP[i<span class="hljs-number">-1</span>][j] + DP[i][j<span class="hljs-number">-1</span>]; <span class="hljs-comment">// filling DP</span>
        }
    }
    <span class="hljs-built_in">cout</span> &lt;&lt; DP[H][W];
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity-1">Time and Space Complexity</h3>
<h4 id="heading-recursive-solution-2">Recursive Solution</h4>
<ul>
<li><p><strong>Time Complexity:</strong></p>
<p>  The primary operations in this algorithm are done in the <code>solve</code> function, where it calculates the number of paths from (0,0) to (w,h).</p>
<ol>
<li><p>The number of distinct problems to be solved is <code>w*h</code>, where <code>w</code> is the width and <code>h</code> is the height of the 2D grid. This is because we need to compute the number of paths for each cell from (0,0).</p>
</li>
<li><p>The time complexity of each problem is O(1). This is because the function <code>solve</code> either returns the stored result in DP[x][y] (if it has been computed before), or it computes the result as the sum of <code>solve(x+1, y)</code> and <code>solve(x, y+1)</code>. Both of these are O(1) operations because they are simple mathematical operations or array accesses.</p>
</li>
</ol>
</li>
</ul>
<p>    Therefore, the overall time complexity of this algorithm is O(w*h).</p>
<ul>
<li><p><strong>Space Complexity:</strong></p>
<p>  The space complexity is also O(w<em>h) because of the 2D DP array used to store the intermediate results. Each cell in the grid has a corresponding cell in the DP array, thus leading to w</em>h cells in the DP array.</p>
<p>  The 2D array <code>DP</code> is of size [31][31], but the actual space used will be w*h where <code>w</code> and <code>h</code> are the width and height of the 2D grid. This is the space needed to store the number of paths for each cell.</p>
</li>
</ul>
<h4 id="heading-iterative-solution-3">Iterative Solution</h4>
<ul>
<li><p><strong>Time Complexity:</strong></p>
<p>  The time complexity of this program is determined by the double for-loop that iterates over all the cells in the grid to calculate and fill in the DP array.</p>
<p>  The outer loop runs H+1 times (from 0 to H) and for each iteration, the inner loop runs W+1 times (from 0 to W).</p>
<p>  Inside the inner loop, you're performing a constant amount of work (accessing elements in the DP array and adding them together).</p>
</li>
</ul>
<p>Given this, the time complexity is O(H*W).</p>
<ul>
<li><p><strong>Space Complexity:</strong></p>
<p>  The space complexity of this program is determined by the size of the DP array.</p>
<p>  The DP array is of size (H+1)x(W+1). You need to store a long long integer for each cell in the grid, which gives a space complexity of O(H*W).</p>
<p>  Besides the DP array, the rest of the variables occupy constant space that does not grow with the size of the input.</p>
</li>
</ul>
<p>Therefore, the overall space complexity is O(H*W).</p>
<h2 id="heading-conclusion-farewell"><strong>Conclusion - Farewell</strong></h2>
<p>We've explored two dynamic programming (DP) problems in-depth - 'Organizing Tiles' and 'Roads'. Both were tackled with recursive and iterative solutions, helping us appreciate the versatility of DP. By analyzing time and space complexity, we've learned about performance trade-offs in different scenarios.</p>
<p>Dynamic Programming is a powerful technique, breaking down problems into manageable sub-problems. It's essential in competitive programming and beyond. Remember, mastering DP needs practice and intuitive understanding. Identify overlapping subproblems, understand them, and choose between recursion or iteration as per the constraints.</p>
<p>Keep practicing and learning. Every problem solved takes you closer to mastery. The learning journey is as rewarding as the destination itself, enriching you with invaluable skills.</p>
<p>Thank you for joining this DP journey. I hope it's been insightful and encourages you to solve more DP challenges. Until next time, happy coding and stay curious!</p>
]]></content:encoded></item><item><title><![CDATA[Decoding the 'Mario and Luigi' Challenge: An In-depth Guide to Applying BFS (Breadth-First Search)]]></title><description><![CDATA[Make sure you have a solid understanding of the BFS algorithm before starting with this post by reading:
https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c
The Mario & Luigi Problem
Imagine a parallel universe where our beloved character...]]></description><link>https://blog.garybricks.com/decoding-the-mario-and-luigi-challenge-an-in-depth-guide-to-applying-bfs-breadth-first-search</link><guid isPermaLink="true">https://blog.garybricks.com/decoding-the-mario-and-luigi-challenge-an-in-depth-guide-to-applying-bfs-breadth-first-search</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[problem solving skills]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Mon, 29 May 2023 19:23:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684874158243/0c07e2e8-6af4-46bf-8462-c657f2feae5c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Make sure you have a solid understanding of the BFS algorithm before starting with this post by reading:</p>
<p><a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c</a></p>
<h2 id="heading-the-mario-amp-luigi-problem">The Mario &amp; Luigi Problem</h2>
<p>Imagine a parallel universe where our beloved characters, Mario and Luigi, find themselves in a challenging situation. They are trapped within an intricate maze filled with rocks and spaces ablaze with fire. Navigating through these hazards is no easy task - the brothers cannot move through the fire, and the rocks form impregnable barriers.</p>
<p>Luckily, this world has an interesting mechanism - buttons distributed randomly within the maze. When either of the brothers steps on one of these buttons, something miraculous happens: every fire within the maze is instantly extinguished. This only happens as long as the brother is on top of the button, the moment he moves out of the button, all fires reappear.</p>
<p>The brothers are aware that somewhere within this maze lies an elusive exit. They are desperate to find a path to this escape route but two pressing questions loom in their minds: "Is it even feasible for both of us to reach this exit together?" and "If so, what is the quickest time in which we can both safely reach the exit?"</p>
<p>Here's where you come in. Your mission is to assist Mario and Luigi in finding answers to these questions. Keep in mind the following rules of movement:</p>
<ol>
<li><p>For each second that ticks by, only one brother can make a move. This means they must strategize and choose their steps wisely.</p>
</li>
<li><p>Mario and Luigi can only move to the four adjacent spaces (up, down, left, right) in the maze, provided that the spaces are free from fire or rocks.</p>
</li>
<li><p>Lastly, don't worry about them colliding - both brothers are able to occupy the same space within the maze.</p>
</li>
</ol>
<p>This is a tale of brotherhood, strategy, and survival. Are you ready to guide Mario and Luigi toward their escape?</p>
<h2 id="heading-inputs">Inputs</h2>
<p>The first line of input will consist of a single integer, N, representing the dimensions of the maze. The maze itself is represented by a character matrix of size N x N, with specific characters symbolizing different elements within the maze. Here's what each character represents:</p>
<ul>
<li><p>'.' Empty space</p>
</li>
<li><p>'*' Fire</p>
</li>
<li><p>'L' Luigi</p>
</li>
<li><p>'M' Mario</p>
</li>
<li><p>'S' Exit point</p>
</li>
<li><p>'#' Rock (forming an impenetrable wall)</p>
</li>
</ul>
<h3 id="heading-examples">Examples:</h3>
<p>For a clearer understanding, let's look at a few examples:</p>
<pre><code class="lang-plaintext">-------- EXAMPLE1 ---------
6
######
#S.B.#
#****#
#L.M.#
#B...#
######
output: 8
-------- EXAMPLE2 ---------
7
#######
#S.*LB#
#...**#
#....B#
#....*#
#...*M#
#######
output: 13
---------------------------
</code></pre>
<h3 id="heading-constraints">Constraints</h3>
<ul>
<li>The size of the maze, N, is bounded as follows: 5 ≤ N ≤ 50.</li>
</ul>
<h2 id="heading-output">Output</h2>
<p>Your code should generate a single-line output. Depending on the maze configuration and the feasibility of the problem, it can be one of two possible statements:</p>
<ol>
<li><p>"Not possible for both Brothers to reach the exit" - This output should be returned when it is impossible for both Mario and Luigi to arrive at the exit given the current maze conditions.</p>
</li>
<li><p>"The minimum time for both brothers to reach the exit is: X" - This statement should be the output when there exists a path for both brothers to reach the exit. Here, 'X' should be replaced with an integer representing the minimum time required for both Mario and Luigi to reach the exit.</p>
</li>
</ol>
<h2 id="heading-problem-solving-as-a-human"><strong>Problem-Solving as a Human</strong></h2>
<p>We'll begin our problem-solving journey by dissecting the relationship between the provided input and output examples.</p>
<p>In our first example, it's apparent that the exit is entirely encircled by fire. As a consequence, Luigi is compelled to rush to the closest button, thereby allowing Mario to activate the button adjacent to the exit. This course of action then provides Luigi with a clear path to the exit, which he can take before Mario. Two crucial insights were gleaned from this analysis:</p>
<ol>
<li><p>If the exit is enveloped by fire, both characters can only reach the exit if a button is located within the fiery perimeter.</p>
</li>
<li><p>To determine the shortest possible path in this instance, we must evaluate both potential routes. This entails testing scenarios in which Mario reaches the first button prior to Luigi and vice versa.</p>
</li>
</ol>
<p>Let's now turn our attention to the second example. Notably, a button exists within the fiery exit zone, suggesting that a viable solution may be at hand. However, Mario is entirely ensnared, immobilized by the fire. Thankfully, Luigi is free to move and can reach a button. Upon pressing this button, Luigi frees Mario, who can then head to the button within the exit zone. This subsequently paves the way for Luigi to arrive at the exit, followed closely by Mario.</p>
<p>Based on the insights drawn from these examples, I began formulating a general solution. My initial idea involved testing all possible moves for Mario. This would involve him attempting to reach all buttons and the exit. Then, for each of these scenarios, we would repeat the process for Luigi. This essentially amounts to exploring all possible routes and then identifying the most efficient one.</p>
<h2 id="heading-solution-implementation">Solution Implementation</h2>
<p>Retaining our initial thought:</p>
<p><em>"Explore all feasible movements for Mario and Luigi to identify the most efficient path."</em></p>
<p>My first instinct was to employ Breadth-First Search (BFS) independently for Mario, tracing all accessible buttons. For each of these options, Luigi should also execute a BFS to reach all buttons located within the fire zone surrounding the exit, as well as the exit itself. Following each of Luigi's paths, Mario should again perform a BFS towards the exit. We then repeat all these steps, this time initiating with Luigi. Quite a whirlwind of thoughts, right? 🤯😵</p>
<p>This solution, although exhaustive, appears immensely complex and potentially riddled with challenges during implementation. Primarily, it involves launching multiple BFS procedures, each accompanied by unique conditions.</p>
<p>The intricacy of this implementation mainly stems from the fact that we're dealing with Mario and Luigi separately. This prompts us to ask, "Could we conduct a single BFS that examines all potential routes, treating Mario and Luigi as a unified entity?"</p>
<p>And that, dear readers, is indeed the golden key to unlocking this problem.</p>
<h3 id="heading-bfs-implementation-for-mario-only">BFS Implementation for Mario only</h3>
<p>Assuming you're familiar with BFS and have taken a glance at my <a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">BFS beginners overview</a>, implementing a solution for this problem would be fairly straightforward if it only concerned <strong>one</strong> character. The completed code for such a scenario might look like this:</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// ( Scenario with Mario only )</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> X[<span class="hljs-number">4</span>] = {<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>}; <span class="hljs-comment">// helper directions for X (right, up, left, down)</span>
<span class="hljs-keyword">int</span> Y[<span class="hljs-number">4</span>] = {<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>}; <span class="hljs-comment">// helper directions for Y (right, up, left, down)</span>
<span class="hljs-keyword">int</span> dist[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>], n;
<span class="hljs-keyword">char</span> MAP[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>];

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span>{</span><span class="hljs-keyword">int</span> x, y;}; <span class="hljs-comment">// node represented by coordinates</span>

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span></span>{
    <span class="hljs-comment">// checks if the coordinate is within the map, is not fire and not rock, and has not been visited</span>
    <span class="hljs-keyword">return</span> x &gt;= <span class="hljs-number">0</span> &amp;&amp; x &lt; n &amp;&amp; y &gt;= <span class="hljs-number">0</span> &amp;&amp; y &lt; n &amp;&amp; dist[x][y] == <span class="hljs-number">-1</span> &amp;&amp; MAP[x][y] != <span class="hljs-string">'*'</span> &amp;&amp; MAP[x][y] != <span class="hljs-string">'#'</span>;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> mx, my, ex, ey; <span class="hljs-comment">// mario {x, y} and exit {x, y}</span>
    <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-comment">// --------- getting input --------- //</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
            dist[i][j] = <span class="hljs-number">-1</span>; <span class="hljs-comment">// initializing the Dist for that node to not visited</span>
            <span class="hljs-built_in">cin</span> &gt;&gt; MAP[i][j];
            <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'S'</span>){ex = i, ey = j;} <span class="hljs-comment">// exit found</span>
            <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'M'</span>){mx = i, my = j;} <span class="hljs-comment">// mario found</span>
        }
    }
    <span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
    BFS.push({mx, my}); <span class="hljs-comment">// starting BFS</span>
    dist[mx][my] = <span class="hljs-number">0</span>; <span class="hljs-comment">// starting node distance set to 0</span>

    <span class="hljs-keyword">while</span> (BFS.size()){
        node current_node = BFS.front();
        BFS.pop();
        <span class="hljs-comment">// visiting all 4 adjacent coords</span>
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
            <span class="hljs-keyword">int</span> newX = current_node.x + X[d];
            <span class="hljs-keyword">int</span> newY = current_node.y + Y[d];
            <span class="hljs-keyword">if</span>(valid(newX, newY)){
                BFS.push({newX, newY});
                dist[newX][newY] = dist[current_node.x][current_node.y] + <span class="hljs-number">1</span>;
            }
        }
    }
    <span class="hljs-keyword">if</span>(dist[ex][ey] == <span class="hljs-number">-1</span>)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"imposible to reach the exit"</span>;
    <span class="hljs-keyword">else</span> <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"the minimum time for reaching the exit: "</span> &lt;&lt; dist[ex][ey];
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>The code shown above should look very familiar, it's the very classic implementation for a BFS on an implicit Graph, shown in numerous examples in my: <a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">BFS beginners overview</a>.</p>
<h3 id="heading-node-representation-for-both-brothers">Node representation for both brothers</h3>
<p>So how might we modify this single-character set up to accommodate two characters? Our initial question is: "What would a node comprising two characters look like?" Here's a possible idea:</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// Before (Only one character)</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span>{</span><span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y};

<span class="hljs-comment">// After (Mario and Luigi)</span>
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">character</span>{</span><span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y};
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Node</span>{</span>
    character Mario;
    character Luigi;
};
</code></pre>
<p>This structure appears plausible. However, referring to the x and y coordinates of Mario and Luigi in the later parts of our code using <code>currentNode.Mario.x</code> and <code>currentNode.Luigi.x</code> might be a tad cumbersome. Let's streamline this with a simpler approach:</p>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Node</span>{</span><span class="hljs-keyword">int</span> Mx, My, Lx, Ly};
</code></pre>
<p>In this structure, we're tracking Mario with the first pair of integers and Luigi with the second pair. This approach leads to more straightforward and cleaner code.</p>
<h3 id="heading-adapting-the-distance-matrix-for-our-new-node">Adapting the Distance Matrix for Our New Node</h3>
<p>To begin, let's accommodate the new node in the <code>dist</code> matrix which keeps track of the minimum distance to a node and also indicates if it hasn't been visited yet.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">int</span> dist[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>] <span class="hljs-comment">// before, mario only {x, y}</span>

<span class="hljs-keyword">int</span> dist[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>][<span class="hljs-number">60</span>][<span class="hljs-number">60</span>] <span class="hljs-comment">// after, both brothers {Mx, My, Lx, Ly}</span>
</code></pre>
<p>this is a very simple change that often confuses many programmers at the beginning (me included) because you get used to seeing the distance the same way you see the map, which for this example is 2D. however, remember that in reality <code>dist</code> is made specifically for whatever the node is, and must be adjusted. on a side note, you are not obligated to use a matrix like I'm doing here, you can also use an unordered map for example, and give an "id" to the nodes. However, this matrix approach simplifies matters for this case. It's important to note that this solution is feasible because N is at most 50. The required space for this matrix is 60^4, which is suitable for this problem but may pose issues for larger constraints.</p>
<p>Earlier, we initialized the 'dist' matrix at the same time as taking our input, but given the change, don't forget to initialize the matrix separately like so:</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">initDist</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">60</span>; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;<span class="hljs-number">60</span>; j++){
            <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> k=<span class="hljs-number">0</span>; k&lt;<span class="hljs-number">60</span>; k++){
                <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> l=<span class="hljs-number">0</span>; l&lt;<span class="hljs-number">60</span>; l++)dist[i][j][k][l] = <span class="hljs-number">-1</span>;
            }
        }
    }
}
</code></pre>
<h3 id="heading-adjusting-bfs-for-our-new-node">Adjusting BFS for Our New Node</h3>
<p>Before we revise the actual BFS, let's update the input-receiving part to consider Luigi:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">int</span> mx, my, lx, ly, ex, ey; <span class="hljs-comment">// mario {x, y}, Luigi {x, y}, and exit {x, y}</span>
<span class="hljs-built_in">cin</span> &gt;&gt; n;
<span class="hljs-comment">// --------- getting input --------- //</span>
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
        <span class="hljs-built_in">cin</span> &gt;&gt; MAP[i][j];
        <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'S'</span>){ex = i, ey = j;} <span class="hljs-comment">// exit found</span>
        <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'M'</span>){mx = i, my = j;} <span class="hljs-comment">// Mario found</span>
        <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'L'</span>){lx = i, ly = j;} <span class="hljs-comment">// Luigi found</span>
    }
}
</code></pre>
<p>Next, we can rectify the initial part of the BFS algorithm that involves adding the starting node to the queue and setting its distance to 0:</p>
<pre><code class="lang-cpp">initDist();
<span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
BFS.push({mx, my, lx, ly}); <span class="hljs-comment">// starting BFS</span>
dist[mx][my][lx][ly] = <span class="hljs-number">0</span>; <span class="hljs-comment">// starting node distance set to 0</span>
</code></pre>
<p>Let's then refine the part of the algorithm that handles visiting all nodes adjacent to the current one:</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// Before:</span>
node current_node = BFS.front();
BFS.pop();
<span class="hljs-comment">// visiting all 4 adjacent coords</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
    <span class="hljs-keyword">int</span> newX = current_node.x + X[d];
    <span class="hljs-keyword">int</span> newY = current_node.y + Y[d];
    <span class="hljs-keyword">if</span>(valid(newX, newY)){
        BFS.push({newX, newY});
        dist[newX][newY] = dist[current_node.x][current_node.y] + <span class="hljs-number">1</span>;
    }
}
</code></pre>
<pre><code class="lang-cpp"><span class="hljs-comment">// After</span>
node current_node = BFS.front();
BFS.pop();
<span class="hljs-comment">// visiting all 4 adjacent coordinates for Mario only</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
    <span class="hljs-keyword">int</span> newMX = current_node.Mx + X[d];
    <span class="hljs-keyword">int</span> newMY = current_node.My + Y[d];
    <span class="hljs-keyword">int</span> newLX = current_node.Lx;
    <span class="hljs-keyword">int</span> newLY = current_node.Ly;
    <span class="hljs-keyword">if</span>(valid(newMX, newMY, newLX, newLY)){
        BFS.push({newMX, newMY, newLX, newLY});
        dist[newMX][newMY][newLX][newLY] = dist[current_node.Mx][current_node.My][current_node.Lx][current_node.Ly] + <span class="hljs-number">1</span>;
    }
}
<span class="hljs-comment">// visiting all 4 adjacent coordinates for Luigi only</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
    <span class="hljs-keyword">int</span> newMX = current_node.Mx;
    <span class="hljs-keyword">int</span> newMY = current_node.My;
    <span class="hljs-keyword">int</span> newLX = current_node.Lx + X[d];
    <span class="hljs-keyword">int</span> newLY = current_node.Ly + Y[d];
    <span class="hljs-keyword">if</span>(valid(newMX, newMY, newLX, newLY)){
        BFS.push({newMX, newMY, newLX, newLY});
        dist[newMX][newMY][newLX][newLY] = dist[current_node.Mx][current_node.My][current_node.Lx][current_node.Ly] + <span class="hljs-number">1</span>;
    }
}
</code></pre>
<p>Where we once checked the 4 adjacent coordinates to the current one and pushed the BFS if it was valid, now however, we must do that independently for Mario but considering that Luigi is part of the node, and his "new" position, is the same, and once the 4 possible changes for Mario have been made, we repeat the process but for Luigi.</p>
<h3 id="heading-adjusting-valid-for-our-new-node-and-buttons">Adjusting Valid() for Our New Node and Buttons</h3>
<p>We're nearly done! The last adjustment we need is to modify the 'valid' function to consider coordinates for both brothers. This entails checking that both coordinates are within the map and legal. Given the exact coordinates for both Mario and Luigi, we can easily add the condition for the scenario in which one of them is standing on a button, thereby allowing passage through fire. Here is my implementation:</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> Mx, <span class="hljs-keyword">int</span> My, <span class="hljs-keyword">int</span> Lx, <span class="hljs-keyword">int</span> Ly)</span></span>{
    <span class="hljs-comment">// checks if both coordinates are within the map and the node has not been visited.</span>
    <span class="hljs-keyword">if</span>(Mx &gt;= <span class="hljs-number">0</span> &amp;&amp; My &gt;= <span class="hljs-number">0</span> &amp;&amp; Mx &lt; n &amp;&amp; My &lt; n &amp;&amp; dist[Mx][My][Lx][Ly] == <span class="hljs-number">-1</span>){
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'#'</span> || MAP[Lx][Ly] == <span class="hljs-string">'#'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// Rock Wall always illegal for either one</span>
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'*'</span> &amp;&amp; MAP[Lx][Ly] == <span class="hljs-string">'B'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// If Mario on fire and Luigi on button</span>
        <span class="hljs-keyword">if</span>(MAP[Lx][Ly] == <span class="hljs-string">'*'</span> &amp;&amp; MAP[Mx][My] == <span class="hljs-string">'B'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// if Luigi on fire and Mario on button</span>
        <span class="hljs-comment">// if the code didn't enter the previous conditions, it means that no buttons are pressed</span>
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'*'</span> || MAP[Lx][Ly] == <span class="hljs-string">'*'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// fire illegal</span>
        <span class="hljs-comment">// else it means that this node is valid :D</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
</code></pre>
<h3 id="heading-accessing-the-solution">Accessing the Solution</h3>
<p>To retrieve the actual answer, we must access the desired final node. For a single character, this would be implemented as follows:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span>(dist[ex][ey] == <span class="hljs-number">-1</span>)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"imposible to reach the exit"</span>;
<span class="hljs-keyword">else</span> <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"the minimum time for reaching the exit: "</span> &lt;&lt; dist[ex][ey];
</code></pre>
<p>However, we now need to revise this to work with the new 4D node distance matrix. This can be perplexing, given that we only have a single exit represented with two numbers: ex, ey, and we require 4 values for accessing the 4D matrix. But don't panic, the solution is quite straightforward:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span>(dist[ex][ey][ex][ey] == <span class="hljs-number">-1</span>)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"imposible to reach the exit"</span>;
<span class="hljs-keyword">else</span> <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"the minimum time for reaching the exit: "</span> &lt;&lt; dist[ex][ey][ex][ey];
</code></pre>
<p>Remember, the first pair of values represents Mario's position, and the second pair signifies Luigi's location. We are interested in the distance for the node where both characters reach the same exit.</p>
<h3 id="heading-time-and-space-complexity">Time and space Complexity</h3>
<p>Let's examine the time and space complexity for this algorithm:</p>
<ol>
<li><p>Time Complexity: The main factor affecting time complexity in this algorithm is the breadth-first search (BFS) which in the worst case, visits all nodes in the graph. As the graph in this case is essentially a 4-dimensional grid of size 60 (considering both Mario and Luigi's x, y positions), the time complexity can be considered as O(N^4) where N is the size of the graph (here, N = 60). This is because BFS in the worst case explores all possible combinations of Mario and Luigi's positions.</p>
</li>
<li><p>Space Complexity: The space complexity is largely driven by the 4-dimensional distance matrix of size 60, 'dist'. As each element of the matrix can be occupied, the space complexity is O(N^4), the same as the time complexity. This is because we need to store the distance for each possible combination of positions for Mario and Luigi.</p>
</li>
</ol>
<p>It's important to note that this solution takes advantage of the fact that N is small (60), as both the time and space complexity are polynomial, making the algorithm impractical for larger inputs.</p>
<h3 id="heading-optimizing-solution">Optimizing Solution</h3>
<p>The first time I submitted this implemented solution, I got a 90% TLE verdict, which forced me to think of a way of optimizing this solution, This compelled me to consider optimizing the solution. Initially, my focus was on streamlining the code while maintaining the underlying logic. Unfortunately, this approach didn't yield the desired improvement. Then I stumbled upon a realization. Consider two nodes, one with coordinates {Mx = 5, My = 5, Lx = 1, Ly = 4} and the other with {Mx = 1, My = 4, Lx = 5, Ly = 5}. Interestingly, the minimum distance from either of these nodes to the exit would be identical. Refer to the image below for a clearer understanding.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1685383608229/7bfe7e45-8553-4749-a3cf-28b5f3e539cd.png" alt class="image--center mx-auto" /></p>
<p>This observation led me to understand that these nodes are effectively identical for our purpose, yet the current code treats them as separate entities. If the code has marked the first node as visited, upon encountering the second node, it erroneously treats it as unvisited. To fix this, we can simply add one additional check to our <code>valid</code> function like so:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span>(Mx &gt;= <span class="hljs-number">0</span> &amp;&amp; My &gt;= <span class="hljs-number">0</span> &amp;&amp; Mx &lt; n &amp;&amp; My &lt; n &amp;&amp; dist[Mx][My][Lx][Ly] == <span class="hljs-number">-1</span> &amp;&amp; dist[Lx][Ly][Mx][My] == <span class="hljs-number">-1</span>)
</code></pre>
<p>The remedy for this issue is a simple augmentation to our 'valid' function, adding an extra check for the node where Mario and Luigi have swapped positions. By making this minor adjustment, we effectively halve the number of possibilities, significantly improving the solution's efficiency.</p>
<h3 id="heading-full-code">Full Code</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> X[<span class="hljs-number">4</span>] = {<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>}; <span class="hljs-comment">// helper directions for X (right, up, left, down)</span>
<span class="hljs-keyword">int</span> Y[<span class="hljs-number">4</span>] = {<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>}; <span class="hljs-comment">// helper directions for Y (right, up, left, down)</span>
<span class="hljs-keyword">int</span> dist[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>][<span class="hljs-number">60</span>][<span class="hljs-number">60</span>], n;
<span class="hljs-keyword">char</span> MAP[<span class="hljs-number">60</span>][<span class="hljs-number">60</span>];

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span>{</span><span class="hljs-keyword">int</span> Mx, My, Lx, Ly;}; <span class="hljs-comment">// node represented by coordinates</span>

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> Mx, <span class="hljs-keyword">int</span> My, <span class="hljs-keyword">int</span> Lx, <span class="hljs-keyword">int</span> Ly)</span></span>{
    <span class="hljs-comment">// checks if both coordinates are within the map and the node has not been visited.</span>
    <span class="hljs-keyword">if</span>(Mx &gt;= <span class="hljs-number">0</span> &amp;&amp; My &gt;= <span class="hljs-number">0</span> &amp;&amp; Mx &lt; n &amp;&amp; My &lt; n &amp;&amp; dist[Mx][My][Lx][Ly] == <span class="hljs-number">-1</span> &amp;&amp; dist[Lx][Ly][Mx][My] == <span class="hljs-number">-1</span>){
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'#'</span> || MAP[Lx][Ly] == <span class="hljs-string">'#'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// Rock Wall always illegal for either one</span>
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'*'</span> &amp;&amp; MAP[Lx][Ly] == <span class="hljs-string">'B'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// If Mario on fire and Luigi on button</span>
        <span class="hljs-keyword">if</span>(MAP[Lx][Ly] == <span class="hljs-string">'*'</span> &amp;&amp; MAP[Mx][My] == <span class="hljs-string">'B'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// if Luigi on fire and Mario on button</span>
        <span class="hljs-comment">// if the code didn't enter the previous conditions, it means that no buttons are pressed</span>
        <span class="hljs-keyword">if</span>(MAP[Mx][My] == <span class="hljs-string">'*'</span> || MAP[Lx][Ly] == <span class="hljs-string">'*'</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// fire illegal</span>
        <span class="hljs-comment">// else it means that you are ok :D</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">initDist</span><span class="hljs-params">()</span></span>{ <span class="hljs-comment">// Initialized the Dist matrix to -1</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">60</span>; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;<span class="hljs-number">60</span>; j++){
            <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> k=<span class="hljs-number">0</span>; k&lt;<span class="hljs-number">60</span>; k++){
                <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> l=<span class="hljs-number">0</span>; l&lt;<span class="hljs-number">60</span>; l++)dist[i][j][k][l] = <span class="hljs-number">-1</span>;
            }
        }
    }
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> mx, my, lx, ly, ex, ey; <span class="hljs-comment">// mario {x, y}, Luigi {x, y}, and exit {x, y}</span>
    <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-comment">// --------- getting input --------- //</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;n; j++){
            <span class="hljs-built_in">cin</span> &gt;&gt; MAP[i][j];
            <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'S'</span>){ex = i, ey = j;} <span class="hljs-comment">// exit found</span>
            <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'M'</span>){mx = i, my = j;} <span class="hljs-comment">// Mario found</span>
            <span class="hljs-keyword">if</span>(MAP[i][j] == <span class="hljs-string">'L'</span>){lx = i, ly = j;} <span class="hljs-comment">// Lario found</span>
        }
    }
    initDist();
    <span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
    BFS.push({mx, my, lx, ly}); <span class="hljs-comment">// starting BFS</span>
    dist[mx][my][lx][ly] = <span class="hljs-number">0</span>; <span class="hljs-comment">// starting node distance set to 0</span>

    <span class="hljs-keyword">while</span> (BFS.size()){
        node current_node = BFS.front();
        BFS.pop();
        <span class="hljs-comment">// visiting all 4 adjacent coordinates for Mario only</span>
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
            <span class="hljs-keyword">int</span> newMX = current_node.Mx + X[d];
            <span class="hljs-keyword">int</span> newMY = current_node.My + Y[d];
            <span class="hljs-keyword">int</span> newLX = current_node.Lx;
            <span class="hljs-keyword">int</span> newLY = current_node.Ly;
            <span class="hljs-keyword">if</span>(valid(newMX, newMY, newLX, newLY)){
                BFS.push({newMX, newMY, newLX, newLY});
                dist[newMX][newMY][newLX][newLY] = dist[current_node.Mx][current_node.My][current_node.Lx][current_node.Ly] + <span class="hljs-number">1</span>;
            }
        }
        <span class="hljs-comment">// visiting all 4 adjacent coordinates for Luigi only</span>
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d&lt;<span class="hljs-number">4</span>; d++){
            <span class="hljs-keyword">int</span> newMX = current_node.Mx;
            <span class="hljs-keyword">int</span> newMY = current_node.My;
            <span class="hljs-keyword">int</span> newLX = current_node.Lx + X[d];
            <span class="hljs-keyword">int</span> newLY = current_node.Ly + Y[d];
            <span class="hljs-keyword">if</span>(valid(newMX, newMY, newLX, newLY)){
                BFS.push({newMX, newMY, newLX, newLY});
                dist[newMX][newMY][newLX][newLY] = dist[current_node.Mx][current_node.My][current_node.Lx][current_node.Ly] + <span class="hljs-number">1</span>;
            }
        }
    }
    <span class="hljs-keyword">if</span>(dist[ex][ey][ex][ey] == <span class="hljs-number">-1</span>)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"imposible to reach the exit"</span>;
    <span class="hljs-keyword">else</span> <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"the minimum time for reaching the exit: "</span> &lt;&lt; dist[ex][ey][ex][ey];
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>In wrapping up, we've navigated through the intricate details of a 4D Breadth-First Search algorithm for a captivating problem. We've traveled from understanding the problem, implementing the solution, encountering setbacks, and eventually triumphing by innovating an optimized solution.</p>
<p>Before I sign off, I would like to remind you that the process of learning and improving is an iterative one. If your first solution doesn't work or isn't efficient enough, don't be disheartened. Every attempt, every setback, and every small victory serves as a stepping stone toward becoming a better problem solver.</p>
<p>I trust this walkthrough has offered you valuable insights and has further sharpened your skills in tackling complex algorithmic problems. I hope to see you take these lessons forward into your next challenge.</p>
<p>Stay tuned for more competitive programming problem breakdowns and insights. Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Mastering The "k-Tree" Problem with Dynamic Programming]]></title><description><![CDATA[The K-Tree Problem
A k-Tree is a unique tree structure where each node has exactly k children nodes, extending infinitely. The tree is weighted, such that each of the k edges stemming from a node carries a weight value ranging from 1 to k. In the ill...]]></description><link>https://blog.garybricks.com/mastering-the-k-tree-problem-with-dynamic-programming</link><guid isPermaLink="true">https://blog.garybricks.com/mastering-the-k-tree-problem-with-dynamic-programming</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[problem solving skills]]></category><category><![CDATA[Dynamic Programming]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Sat, 20 May 2023 05:09:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684559333306/70a431da-2bb1-4cdb-884a-3bffbee40c96.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-the-k-tree-problem">The K-Tree Problem</h2>
<p>A k-Tree is a unique tree structure where each node has exactly k children nodes, extending infinitely. The tree is weighted, such that each of the k edges stemming from a node carries a weight value ranging from 1 to k. In the illustration below, we have an example of a k-tree where k equals 3.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1684509788475/bb67e9e1-cf75-44c0-b078-c8561ff14e93.png" alt class="image--center mx-auto" /></p>
<p>Please note that in this particular image, the tree is depicted to a depth of 3. However, remember that a k-tree is infinite, and this pattern of branching continues endlessly from each child node.</p>
<p>Now, let's consider the following problem:</p>
<p>Given three parameters <strong>K, N, and D</strong>, write a program that answers the following question:</p>
<p><em>'How many paths are there starting from the root node, such that the total sum of the edge weights in a path equals N, and the path includes at least one edge of weight D or more?'</em></p>
<h3 id="heading-inputs">Inputs</h3>
<p>A single line containing three integers: N, K, and D.</p>
<h4 id="heading-constraints">Constraints:</h4>
<ul>
<li>1 &lt;= N, K &lt;= 100</li>
</ul>
<ul>
<li>1 &lt;= D &lt;= K</li>
</ul>
<h3 id="heading-outputs">Outputs</h3>
<p>A single integer: the answer to the problem. Given that the answer can be quite large, ensure to output your answer modulo 10^9 + 7.</p>
<h3 id="heading-examples">Examples</h3>
<pre><code class="lang-plaintext">Example 1:
Input: 3 3 2 
Output: 3

Example 2: 
Input: 3 3 3 
Output: 1

Example 3: 
Input: 4 5 2 
Output: 7
</code></pre>
<p>Here is an image for the first example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1684517792999/f65829f9-19ab-4039-b050-2ddd4bddbb01.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-problem-solving-as-a-human">Problem-Solving as a Human</h2>
<p>When tackling a problem, it's often best to start by examining an example and trying to solve it logically, as a human would. In this case, it's helpful to sketch out a tree for the first example to understand the relationship between the input and output. The first and most apparent solution was to model the tree structure and attempt to traverse all possible paths.</p>
<h3 id="heading-pausing-to-evaluate-the-approach">Pausing to Evaluate the Approach</h3>
<p>Before diving into implementing this approach, let's pause and consider potential challenges. The first thing I noticed is that the tree's "nodes" are irrelevant - they carry no intrinsic value. We are only interested in the edges, and the order in which we traverse the tree doesn't matter. Moreover, the tree is infinite, which could lead to complications during implementation.</p>
<p>With these insights, I decided to reassess the situation, returning to the drawing board. But this time, instead of focusing on the tree, I would only consider the edge values.</p>
<h3 id="heading-solving-the-problem-without-the-tree">Solving the Problem Without the Tree</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1684521746588/72911d6b-f994-4dbe-9a4b-35f08e6199d0.png" alt class="image--center mx-auto" /></p>
<p>For the first example, I wrote down the variable values. This reminded me of three key points:</p>
<ol>
<li><p>The sum of the path should be <strong><mark>exactly</mark></strong> N</p>
</li>
<li><p>All Edges used must be <strong><mark>less or equal to K</mark></strong></p>
</li>
<li><p>A path is valid only if there is an edge with a weight greater than or equal to D.</p>
</li>
</ol>
<p>Taking these points into account, we can rephrase the problem as:</p>
<p><em>"How many ways can you form a sum equal to N using numbers less than or equal to K, with at least one number being greater than or equal to D?"</em></p>
<p>This greatly simplifies the problem since we have effectively removed the "tree" aspect from it. Now, we can solve the problem using only numbers and we can still maintain the same basic approach of testing all possible number combinations.</p>
<h2 id="heading-solution-pseudo-code">Solution Pseudo Code</h2>
<p>For problems involving combinations, a recursive function often comes in handy. However, it's crucial to define base cases and divide the problem into manageable components. In this scenario, we'll start with:</p>
<p><em>"<mark>How many ways can you form a sum equal to N using numbers less than or equal to K</mark>, with at least one number being greater than or equal to D?"</em></p>
<h3 id="heading-base-cases-for-the-first-part">Base cases for the first part:</h3>
<ul>
<li><p>Since the Tree is infinite, we need a condition to stop the current path when the sum exceeds N. This is important as further exploration of this path won't yield a valid solution (given that there are no negative edges).</p>
</li>
<li><p>We need to acknowledge when we've successfully formed a sum equal to N. This involves incrementing our answer count and halting the current path exploration.</p>
</li>
</ul>
<p>With these two considerations, let's lay out the following pseudo code:</p>
<pre><code class="lang-bash">N = 3, K = 3
RESULT = 0
<span class="hljs-keyword">function</span> solve(sum):
    <span class="hljs-keyword">if</span> sum &gt; N: <span class="hljs-built_in">return</span>
    <span class="hljs-keyword">if</span> sum == N: {RESULT += 1; <span class="hljs-built_in">return</span>}
    <span class="hljs-keyword">for</span> each number from 1 to k:
        solve(sum + number)
</code></pre>
<p>now let's consider the second part of the problem:</p>
<p><em>"How many ways can you form a sum equal to N using numbers less than or equal to K, <mark>with at least one number being greater than or equal to D?</mark>"</em></p>
<h3 id="heading-base-cases-for-the-second-part">Base cases for the second part:</h3>
<ul>
<li><p>We're interested in whether there's at least one number greater than or equal to D. To capture this, we add a boolean parameter to our function, <code>valid</code>, which becomes true if a number meets this condition.</p>
</li>
<li><p>Additionally, we need to modify the base case that increments the result. Now, we should only increment if <code>valid</code> equals true.</p>
</li>
</ul>
<p>Combining both problem parts, we can arrive at our final pseudo code:</p>
<pre><code class="lang-bash">N = 3, K = 3, D = 2
RESULT = 0
<span class="hljs-keyword">function</span> solve(sum, valid):
    <span class="hljs-keyword">if</span> sum &gt; N: <span class="hljs-built_in">return</span>
    <span class="hljs-keyword">if</span> sum == N and valid: {RESULT += 1; <span class="hljs-built_in">return</span>}
    <span class="hljs-keyword">for</span> each number from 1 to k:
        solve(sum + number, number &gt;= D or already valid)

solve(0, <span class="hljs-literal">false</span>)
<span class="hljs-built_in">print</span>(RESULT)
</code></pre>
<h2 id="heading-code-implementation">Code Implementation</h2>
<p>I highly recommend trying to implement the solution in your preferred programming language. Below is my implementation in C++:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> N, K, D, RES = <span class="hljs-number">0</span>;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sum, <span class="hljs-keyword">bool</span> valid)</span></span>{
    <span class="hljs-keyword">if</span>(sum &gt; N)<span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">if</span>(sum == N &amp;&amp; valid){RES++; <span class="hljs-keyword">return</span>;}
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>; i&lt;=K; i++)solve(sum + i, i &gt;= D || valid);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; N &gt;&gt; K &gt;&gt; D;
    solve(<span class="hljs-number">0</span>, <span class="hljs-literal">false</span>);
    <span class="hljs-built_in">cout</span> &lt;&lt; RES;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity">Time and Space complexity</h3>
<p>The worst-case time complexity is exponential, O(K^N), as the function <code>solve</code> can potentially make K recursive calls at each depth level, with the maximum depth level being N. However, the actual time complexity will likely be significantly less than O(K^N) due to the early return condition (if(sum &gt; N)return;) which prunes many branches of the recursion tree where the sum has already exceeded N.</p>
<p>The space complexity is O(N), which represents the maximum depth of the recursive call stack. Each recursive call adds a new level to the stack.</p>
<p>However, keep in mind that the time complexity for this solution is not desirable given that N and K can be up to 100. This could result in up to 1.e+200 operations, which is far beyond what can be executed without encountering a Time Limit Exceeded (TLE) verdict.</p>
<h2 id="heading-optimizing-our-solution"><strong>Optimizing Our Solution</strong></h2>
<p>Whenever I create a recursive solution that tests for all possibilities and it needs optimization, the first thing I check is the possibility of repeated function calls, or what I call "repeated states".</p>
<h3 id="heading-what-is-the-state-of-our-solution">What is the state of our solution?</h3>
<p>In this specific solution, the state is represented by the parameters of the function {sum, valid}. Both values are critical to defining the state.</p>
<h3 id="heading-identifying-repeated-states"><strong>Identifying repeated states</strong></h3>
<p>An easy method to identify repeated states is to add a print statement in our function like this:</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sum, <span class="hljs-keyword">bool</span> valid)</span></span>{
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"{ "</span> &lt;&lt; sum &lt;&lt; <span class="hljs-string">" , "</span> &lt;&lt; valid &lt;&lt; <span class="hljs-string">" }\n"</span>;
</code></pre>
<p>By running the code with input: 4, 5, 2, it becomes evident that state { 6, 1 } is repeated eight times.</p>
<h3 id="heading-implementing-dynamic-programming-dp"><strong>Implementing Dynamic Programming (DP)</strong></h3>
<p>If repeated states exist, it indicates that Dynamic Programming (DP) can be applied to optimize the code. DP involves computing the solution for a state, storing it, and reusing it whenever the state is encountered again. This approach saves significant computation time.</p>
<p>Here's the C++ implementation utilizing DP:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">int</span> N, K, D;

<span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; <span class="hljs-title">DP</span><span class="hljs-params">(<span class="hljs-number">105</span>,<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;(<span class="hljs-number">2</span>, <span class="hljs-number">-1</span>))</span></span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">solve</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sum, <span class="hljs-keyword">bool</span> valid)</span></span>{
    <span class="hljs-keyword">if</span>(sum &gt; N)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(sum == N &amp;&amp; valid)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span>(DP[sum][valid] != <span class="hljs-number">-1</span>) <span class="hljs-keyword">return</span> DP[sum][valid];
    <span class="hljs-keyword">int</span> resultForThisState = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">1</span>; i&lt;=K; i++){
        resultForThisState += solve(sum + i, i &gt;= D || valid);
    }
    <span class="hljs-keyword">return</span> DP[sum][valid] = resultForThisState;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; N &gt;&gt; K &gt;&gt; D;
    <span class="hljs-built_in">cout</span> &lt;&lt; solve(<span class="hljs-number">0</span>, <span class="hljs-literal">false</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h4 id="heading-breaking-down-the-dp-implementation"><strong>Breaking Down the DP Implementation</strong></h4>
<p>This code is similar to the original recursive solution with the addition of a DP approach. Let's look at the new elements in detail.</p>
<p><code>vector&lt;vector&lt;int&gt;&gt; DP(105,vector&lt;int&gt;(2, -1));</code> This line of code initializes our DP storage. It's a 2D matrix of size 105x2. We use 105 as the size because, although N can only reach 100, it's a good practice to leave a little margin for error. The second dimension is 2, as <code>valid</code> is a boolean variable and can only have two values (true or false).</p>
<p>Note: The entire matrix is initialized with -1. This is critical because 0 can be a valid computed answer.</p>
<p><code>if(DP[sum][valid] != -1) return DP[sum][valid];</code> This line checks if there's a precomputed result for this state. If there is, it returns that value, saving us from unnecessary computation.</p>
<p>if none of the base case conditions are met, we store the result for the current state, which is the sum of all of its children's results.</p>
<p><code>return DP[sum][valid] = resultForThisState;</code> This line stores the result of the current state in the DP table and returns that value. It's a concise way of accomplishing two tasks at once.</p>
<h3 id="heading-time-and-space-complexity-1">Time and Space Complexity</h3>
<p>This solution using Dynamic Programming has considerably improved the time and space complexity compared to the previous recursive solution without memoization.</p>
<p>Time complexity: The time complexity of the function is O(NK), since the function solve is called for all sums from 0 to N (N+1 states), and for each sum, there are K possibilities to consider. But due to memoization, each state {sum, valid} is computed only once, giving us a time complexity of O(NK).</p>
<p>Space complexity: The space complexity of the program is O(N) due to the DP array, which has a size of 105x2. The recursion stack in this case doesn't contribute significantly to the space complexity because once a state is computed, it is stored and doesn't need to be computed again. The 2D DP array size is constant (105x2) and does not depend on the inputs N, K, or D. Therefore, the space complexity is O(1). However, considering that the size of the DP array is proportional to N, it could also be considered as O(N) in terms of input size.</p>
<p>So, we can say that the time complexity is O(N*K) and the space complexity is O(N) (or O(1) if considering the fixed size of the DP array).</p>
<p>This is incredibly efficient because N and K can be up to 100, this means that at most, this code runs 10,000 operations. 😎🥳</p>
<h2 id="heading-full-code-small-corrections">Full Code + Small Corrections</h2>
<p>Two small details we left out in our coded solution were: <em>"Given that <mark> the answer can be quite large</mark>, ensure to <mark>output your answer modulo 10^9 + 7</mark>."</em></p>
<p>However, this can be added very simply by using the C++ long long data type for large numbers and adding the Modulo operation every time the solve() function gets used.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-keyword">int</span> N, K, D;
ll MOD = <span class="hljs-number">1e9</span> + <span class="hljs-number">7</span>

<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;ll&gt;&gt; DP(<span class="hljs-number">105</span>,<span class="hljs-built_in">vector</span>&lt;ll&gt;(<span class="hljs-number">2</span>, <span class="hljs-number">-1</span>));

<span class="hljs-function">ll <span class="hljs-title">solve</span><span class="hljs-params">(ll sum, <span class="hljs-keyword">bool</span> valid)</span></span>{
    <span class="hljs-keyword">if</span>(sum &gt; N)<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span>(sum == N &amp;&amp; valid)<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span>(DP[sum][valid] != <span class="hljs-number">-1</span>) <span class="hljs-keyword">return</span> DP[sum][valid];
    ll resultForThisState = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span>(ll i=<span class="hljs-number">1</span>; i&lt;=K; i++){
        resultForThisState += solve(sum + i, i &gt;= D || valid) % MOD;
    }
    <span class="hljs-keyword">return</span> DP[sum][valid] = resultForThisState % MOD;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-built_in">cin</span> &gt;&gt; N &gt;&gt; K &gt;&gt; D;
    <span class="hljs-built_in">cout</span> &lt;&lt; solve(<span class="hljs-number">0</span>, <span class="hljs-literal">false</span>) % MOD;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion + Farewell</h2>
<p>In conclusion, solving a competitive programming problem requires an understanding of the problem statement, the ability to break down the problem, and knowing the right approach to use. The k-Tree problem provided a clear illustration of these steps, taking us from an initial analysis and solution that wasn't efficient, to a significantly more efficient solution using Dynamic Programming.</p>
<p>Don't be disheartened if you don't immediately see how to solve a problem. The beauty of competitive programming is in the journey and the learning process. With practice and a determination to understand the concepts, you will continually improve. Always remember to keep refining your skills, keep learning, and most importantly, enjoy the journey!</p>
<p>We hope you found this article useful and educational. Stay tuned for more competitive programming problem breakdowns and insights. Happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Dijkstra Algorithm - Introduction For Beginners]]></title><description><![CDATA[Introduction
Hello everyone 👋, In today's post I wanted to talk about the famous Dijkstra algorithm, we are going to see what it is, what it's used for, how it works, and the implementation of the algorithm in c++ altho the idea can be applied in an...]]></description><link>https://blog.garybricks.com/dijkstra-algorithm-introduction-for-beginners</link><guid isPermaLink="true">https://blog.garybricks.com/dijkstra-algorithm-introduction-for-beginners</guid><category><![CDATA[algorithms]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[data structures]]></category><category><![CDATA[C++]]></category><category><![CDATA[dijkstra]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Fri, 30 Dec 2022 03:37:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671745151505/5488136c-81a8-4a65-9d52-fa966d645b3f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone 👋, In today's post I wanted to talk about the famous Dijkstra algorithm, we are going to see what it is, what it's used for, how it works, and the implementation of the algorithm in c++ altho the idea can be applied in any language.</p>
<p>Before we continue I highly recommend you read the following resources:</p>
<ul>
<li><p><a target="_blank" href="https://blog.garybricks.com/graphs-introduction-for-beginners">Graphs Introduction For Beginners</a></p>
</li>
<li><p><a target="_blank" href="https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c">BFS and DFS Beginners Overview</a></p>
</li>
</ul>
<h2 id="heading-what-is-dijkstra">What is Dijkstra?</h2>
<p>The Dijkstra algorithm is a graph search algorithm that solves the single-source shortest path problem for a graph with non-negative edge weights, producing a shortest path tree, this means that we can know the <strong>shortest</strong> distance from the origin node to the rest of the nodes in a graph. It is very similar to the BFS algorithm, however, the BFS algorithm does not give the shortest distance in a <strong>weighted</strong> graph.</p>
<h2 id="heading-what-is-dijkstra-used-for">What is Dijkstra Used For?</h2>
<p>Dijkstra's algorithm is a popular choice for finding the shortest path in a graph, and it has many practical applications. Some examples of where Dijkstra's algorithm is used include:</p>
<ol>
<li><p>Navigation: Dijkstra's algorithm can be used to find the shortest route between two locations on a map, taking into account factors such as distance, time, and traffic.</p>
</li>
<li><p>Network routing: In computer networking, Dijkstra's algorithm can be used to find the shortest path between two nodes in a network, such as routers or servers.</p>
</li>
<li><p>Traffic management: Dijkstra's algorithm can be used to optimize traffic flow by finding the shortest routes for vehicles to take, based on factors such as distance, time, and traffic.</p>
</li>
<li><p>Resource allocation: Dijkstra's algorithm can be used to find the most efficient allocation of resources, such as in a supply chain or manufacturing process.</p>
</li>
<li><p>Artificial intelligence: In artificial intelligence and machine learning, Dijkstra's algorithm can be used to find the shortest path in a graph representing a problem space, such as in pathfinding or planning.</p>
</li>
</ol>
<p>These are just some examples, in my case I use Dijkstra for competitive programming problems, we'll look at an example later in this post.</p>
<h2 id="heading-how-does-the-algorithm-work">How Does The Algorithm Work?</h2>
<p>The Dijkstra algorithm works by starting from a specified node and repeatedly expanding to the closest adjacent node until it reaches the destination node, very similar to the BFS algorithm however the Dijkstra algorithm uses a priority queue instead of a queue, this is necessary since the adjacent node with the less cost has the highest priority. At each step, the algorithm removes the node at the front of the priority queue and updates the distances of its adjacent nodes based on the distance from the starting node to the current node.</p>
<p>To implement Dijkstra's algorithm, we need to keep track of the following information for each node:</p>
<ul>
<li><p>The distance from the starting node to the current node.</p>
</li>
<li><p>The previous node in the path from the starting node to the current node.</p>
</li>
</ul>
<p>Initially, the distance of the starting node is set to 0, and the distances of all other nodes are set to infinity. As the algorithm progresses, it updates the distances of the neighboring nodes based on the distance from the starting node to the current node.</p>
<p>Here is an outline of the steps:</p>
<ol>
<li><p>Set the distance of the starting node to 0 and the distance of all other nodes to infinity.</p>
</li>
<li><p>Add the starting node to the priority queue</p>
</li>
<li><p>While the priority queue is not empty:</p>
<ol>
<li><p>Remove the node with the highest priority (lowest distance) from the priority queue, (The Top).</p>
</li>
<li><p>Check if the current node has a cost greater than what it already has, if this is true, it means that the cost is not being improved and we can <code>continue</code> .</p>
</li>
<li><p>Update the distances of its neighboring nodes based on the distance from the current node to the neighboring node.</p>
</li>
<li><p>Save that the neighboring node comes from the current node in the <code>BACK</code> array, this is going to help us to recreate the path.</p>
</li>
<li><p>Add the neighboring nodes to the priority queue.</p>
</li>
</ol>
</li>
<li><p>Once the priority queue is empty, we can reconstruct the shortest path from the starting node to the destination node by following the previous nodes back from the destination node to the starting node using the <code>BACK</code>.</p>
</li>
</ol>
<p>This algorithm is more efficient and can handle larger graphs in comparison to other algorithms like the "Bellman-Ford". However, the Dijkstra algorithm requires that there are no negative weight edges.</p>
<h2 id="heading-example-visualization">Example - Visualization</h2>
<p>In order to better understand the algorithm I made the following animation:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672369911767/2a6f9c8d-1351-4ff2-b113-b3f964966dd0.gif" alt class="image--center mx-auto" /></p>
<p>the input for the example graph shown above would be:</p>
<pre><code class="lang-cpp"><span class="hljs-number">8</span> <span class="hljs-number">11</span>
<span class="hljs-number">0</span> <span class="hljs-number">3</span> <span class="hljs-number">3</span>
<span class="hljs-number">0</span> <span class="hljs-number">2</span> <span class="hljs-number">8</span>
<span class="hljs-number">1</span> <span class="hljs-number">3</span> <span class="hljs-number">1</span>
<span class="hljs-number">1</span> <span class="hljs-number">6</span> <span class="hljs-number">1</span>
<span class="hljs-number">2</span> <span class="hljs-number">5</span> <span class="hljs-number">8</span>
<span class="hljs-number">2</span> <span class="hljs-number">4</span> <span class="hljs-number">7</span>
<span class="hljs-number">3</span> <span class="hljs-number">7</span> <span class="hljs-number">4</span>
<span class="hljs-number">4</span> <span class="hljs-number">7</span> <span class="hljs-number">2</span>
<span class="hljs-number">4</span> <span class="hljs-number">6</span> <span class="hljs-number">3</span>
<span class="hljs-number">5</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>
<span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">7</span>
<span class="hljs-number">1</span>
</code></pre>
<p>The last number is the starting node.</p>
<h2 id="heading-code-implementation">Code Implementation</h2>
<p>Below you can find the implementation of the algorithm in c++, remember that there are several ways to code this algorithm and I'm just showing the version I use. you can find the explanation below the code cell.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;algorithm&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;
<span class="hljs-keyword">typedef</span> <span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> ll;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span>{</span>
    <span class="hljs-keyword">int</span> node;
    ll cost;
    <span class="hljs-keyword">bool</span> <span class="hljs-keyword">operator</span> &lt; (<span class="hljs-keyword">const</span> struct node &amp;b) <span class="hljs-keyword">const</span>{
        <span class="hljs-keyword">if</span>(cost != b.cost) <span class="hljs-keyword">return</span> cost &gt; b.cost;
        <span class="hljs-keyword">if</span>(node != b.node) <span class="hljs-keyword">return</span> node &gt; b.node;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }
};

<span class="hljs-keyword">const</span> ll INF = <span class="hljs-number">1E18</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n, m; <span class="hljs-built_in">cin</span>&gt;&gt;n&gt;&gt;m;
    <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;node&gt;&gt; <span class="hljs-title">adj</span><span class="hljs-params">(n)</span></span>;
    <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">BACK</span><span class="hljs-params">(n, <span class="hljs-number">-1</span>)</span></span>;

    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; m; i++){
        <span class="hljs-keyword">int</span> u, v; ll w;
        <span class="hljs-built_in">cin</span>&gt;&gt;u&gt;&gt;v&gt;&gt;w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;ll&gt; <span class="hljs-title">dist</span><span class="hljs-params">(n, INF)</span></span>;
    <span class="hljs-keyword">int</span> source; <span class="hljs-built_in">cin</span> &gt;&gt; source;
    dist[source] = <span class="hljs-number">0</span>;

    <span class="hljs-built_in">priority_queue</span>&lt;node&gt; dijkstra;
    dijkstra.push({source, <span class="hljs-number">0</span>});

    <span class="hljs-keyword">while</span>(!dijkstra.empty()){
        node c = dijkstra.top();
        dijkstra.pop();
        <span class="hljs-keyword">if</span>(c.cost &gt; dist[c.node]) <span class="hljs-keyword">continue</span>;

        <span class="hljs-keyword">for</span>(node adj: adj[c.node]){
            <span class="hljs-keyword">if</span>(c.cost + adj.cost &gt;= dist[adj.node])<span class="hljs-keyword">continue</span>;
            dist[adj.node] = c.cost + adj.cost;
            BACK[adj.node] = c.node;
            dijkstra.push({adj.node,c.cost + adj.cost});
        }
    }

    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++){
        <span class="hljs-built_in">cout</span>&lt;&lt;i&lt;&lt;<span class="hljs-string">": cost:"</span>&lt;&lt;dist[i]&lt;&lt;<span class="hljs-string">" path:"</span>;
        <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; path;
        <span class="hljs-keyword">int</span> current = i;
        <span class="hljs-keyword">while</span> (current != <span class="hljs-number">-1</span>) {
            path.push_back(current);
            current = BACK[current];
        }
        reverse(path.begin(), path.end());
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:path)<span class="hljs-built_in">cout</span> &lt;&lt; e &lt;&lt; <span class="hljs-string">" ==&gt; "</span>;
        <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>First, we define our node struct, which is going to have two properties, the name or in this case number of the node, and the cost or weight. Notice that we also define the "&lt;" operator, this is necessary and very important for the priority queue to know how to order the nodes by cost. Then we input the graph itself in the exact same way as we do with a BFS algorithm and we set the source distance to 0. Notice how we are going to keep track of the distances in the <code>dist</code> vector. Additionally, we also define the Back vector, with -1 as the default value.</p>
<p>Now we define our Priority Queue which I like to call "Dijkstra" and we push the origin node while it's not empty, we are going to perform the following actions:</p>
<p>remove the top of the priority queue. Check if the node has a cost greater than the already saved distance for that node in the <code>dist</code> vector, in which case you continue.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span>(c.cost &gt; dist[c.node]) <span class="hljs-keyword">continue</span>;
</code></pre>
<p>This is going to help to not come back from where you came from. Else, we are going to iterate through the adjacent nodes to that node and once again check if the distance from the current node plus the neighboring node improves the cost. If it is greater, that means worse so continue.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span>(c.cost + adj.cost &gt;= dist[adj.node])<span class="hljs-keyword">continue</span>;
</code></pre>
<p>else we update the distance to that adjacent node, the back, and push that adjacent node with the updated cost.</p>
<pre><code class="lang-cpp">dist[adj.node] = c.cost + adj.cost;
BACK[adj.node] = c.node;
dijkstra.push({adj.node,c.cost + adj.cost});
</code></pre>
<p>Once the Dijkstra is empty, we can prove that it worked by showing the minimum cost from the origin to the rest of the nodes, AND the path that it took.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++){
    <span class="hljs-built_in">cout</span>&lt;&lt;i&lt;&lt;<span class="hljs-string">": cost:"</span>&lt;&lt;dist[i]&lt;&lt;<span class="hljs-string">" path:"</span>;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; path;
    <span class="hljs-keyword">int</span> current = i;
    <span class="hljs-keyword">while</span> (current != <span class="hljs-number">-1</span>) {
        path.push_back(current);
        current = BACK[current];
    }
    reverse(path.begin(), path.end());
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:path)<span class="hljs-built_in">cout</span> &lt;&lt; e &lt;&lt; <span class="hljs-string">" ==&gt; "</span>;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;
}
</code></pre>
<p>The process to recover the path is exactly the same as with the BFS.</p>
<p>Now you can try to run the full code with the example input and you should get the following output:</p>
<pre><code class="lang-cpp"><span class="hljs-number">0</span>: cost:<span class="hljs-number">4</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">3</span> ==&gt; <span class="hljs-number">0</span> ==&gt; 
<span class="hljs-number">1</span>: cost:<span class="hljs-number">0</span> path:<span class="hljs-number">1</span> ==&gt; 
<span class="hljs-number">2</span>: cost:<span class="hljs-number">11</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">6</span> ==&gt; <span class="hljs-number">4</span> ==&gt; <span class="hljs-number">2</span> ==&gt; 
<span class="hljs-number">3</span>: cost:<span class="hljs-number">1</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">3</span> ==&gt; 
<span class="hljs-number">4</span>: cost:<span class="hljs-number">4</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">6</span> ==&gt; <span class="hljs-number">4</span> ==&gt; 
<span class="hljs-number">5</span>: cost:<span class="hljs-number">13</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">3</span> ==&gt; <span class="hljs-number">7</span> ==&gt; <span class="hljs-number">5</span> ==&gt; 
<span class="hljs-number">6</span>: cost:<span class="hljs-number">1</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">6</span> ==&gt; 
<span class="hljs-number">7</span>: cost:<span class="hljs-number">5</span> path:<span class="hljs-number">1</span> ==&gt; <span class="hljs-number">3</span> ==&gt; <span class="hljs-number">7</span> ==&gt;
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>In conclusion, the Dijkstra algorithm is a powerful tool for finding the shortest path between two nodes in a graph. Whether you are a beginner or an experienced programmer, understanding how the Dijkstra algorithm works is an important skill to have in your toolkit. Whether you are navigating a map, routing network traffic, or optimizing the allocation of resources, the Dijkstra algorithm can help you find the most efficient solution to a wide range of problems. So if you want to learn more about the Dijkstra algorithm and how to implement it in your own projects, be sure to check out the resources and code samples provided in this post.</p>
<p>remember that this is a skill that takes a lifetime to master so don't feel frustrated if you don't get it right away because this isn't easy, but I hope some of the guidelines we saw today were helpful and the basic foundations on this topic were well understood, remember, there is still a lot to learn and we definitively didn't cover everything on Dijkstra, but I hope this was a good beginner overview and that you managed to grasp the basic ideas.</p>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. Stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Nearest Smallest Element, Classical Stack Problem]]></title><description><![CDATA[Introduction
Hello Everyone! 👋, welcome back, in this post I want to show you one of my favorite trivial stack problems and some variations, I will explain the problem, go through the most simple but inefficient answer, and then the correct and bril...]]></description><link>https://blog.garybricks.com/nearest-smallest-element-classical-stack-problem</link><guid isPermaLink="true">https://blog.garybricks.com/nearest-smallest-element-classical-stack-problem</guid><category><![CDATA[algorithms]]></category><category><![CDATA[data structures]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[C++]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Fri, 16 Dec 2022 19:33:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671213725881/s18Y8CnzC.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello Everyone! 👋, welcome back, in this post I want to show you one of my favorite trivial stack problems and some variations, I will explain the problem, go through the most simple but inefficient answer, and then the correct and brilliant solution using stacks.</p>
<h2 id="heading-problem">Problem</h2>
<h3 id="heading-statement">Statement</h3>
<p>Given an Array of positive integers, for each array element output the nearest smaller element, i.e., the first smaller element that comes after the element in the array, if no element exists, output -1.</p>
<h3 id="heading-limits">Limits</h3>
<ul>
<li><p>N (the size of the array) 1 &lt;= N &lt;= 10^6</p>
</li>
<li><p>Ai (Element in the array) 1 &lt;= Ai &lt;= 10^6</p>
</li>
</ul>
<h3 id="heading-examples">Examples</h3>
<pre><code class="lang-cpp">INPUT:
<span class="hljs-number">6</span>
<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">1</span> <span class="hljs-number">6</span>
OUTPUT:
<span class="hljs-number">2</span> <span class="hljs-number">1</span> <span class="hljs-number">1</span> <span class="hljs-number">1</span> <span class="hljs-number">-1</span> <span class="hljs-number">-1</span>
</code></pre>
<pre><code class="lang-cpp">INPUT:
<span class="hljs-number">3</span>
<span class="hljs-number">3</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>
OUTPUT:
<span class="hljs-number">1</span> <span class="hljs-number">-1</span> <span class="hljs-number">-1</span>
</code></pre>
<h2 id="heading-iterative-solution">Iterative Solution</h2>
<p>If you understood the problem then it's very likely that you already thought of this solution, the algorithm is very simple, for each element simply iterate from that position to the end of the array in the search for a smallest element, and if found, immediately output that element, finish the search, and continue to the next item. If not found output -1.</p>
<h3 id="heading-code-implementation">Code Implementation</h3>
<p>Based on the explanation above, I highly recommend that you try to code the solution for yourself, and then compare it to the code implementation below.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
  <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;arr(n); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e; <span class="hljs-comment">// getting input</span>

  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
    <span class="hljs-keyword">int</span> current = arr[i];
    <span class="hljs-keyword">bool</span> found = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=i; j&lt;n; j++){
      <span class="hljs-keyword">if</span>(arr[j] &lt; current){<span class="hljs-built_in">cout</span> &lt;&lt; arr[j] &lt;&lt; <span class="hljs-string">" "</span>; found=<span class="hljs-literal">true</span>; <span class="hljs-keyword">break</span>;}
    }
    <span class="hljs-keyword">if</span>(!found)<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-number">-1</span> &lt;&lt; <span class="hljs-string">" "</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>When I first made this solution, I thought: "Hey! this is a great simple solution let's submit this code!", but that's because I didn't had a great understanding of complexity and efficiency at the time, and I got a TLE verdict 😔.</p>
<h3 id="heading-time-and-space-complexity">Time and Space Complexity</h3>
<p>If you have never heard of time and space complexity and Big-O notation, I highly suggest that you read my post: <a target="_blank" href="https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples">Efficiency and Big-O Notation Overview</a></p>
<p>This code has a time complexity of <strong><em>O(n^2)</em></strong> and a space complexity of <strong><em>O(n)</em></strong>. The time complexity is determined by the two nested loops, which both run in linear time with respect to the size of the input <code>n</code>. The space complexity is determined by the use of the <code>vector</code> container, which has a size of <code>n</code>.</p>
<p>in the worst case, <strong><em>n</em></strong> can be 1,000,000, with this algorithm the amount of operations is going to be approximately 1,000,000,000,000 in a worst-case scenario which is why we get a Time Limit Exceeded (TLE) verdict.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670705510379/8lReYEDdq.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-stack-solution">Stack Solution</h2>
<p>Now that we understand why the iterative solution is not the right choice, let's think of a different solution, this one involves a stack. If you have never heard about a "stack" I highly recommend you to read my <a target="_blank" href="https://blog.garybricks.com/stacks-and-queues-a-beginners-overview">"Stacks and Queues a Beginners Overview"</a> post and come back here.</p>
<p>We can iterate the array backward from right to left, and for each element perform the following algorithm:</p>
<ol>
<li><p>If our helper stack is empty, output -1, add the element to the stack, and continue to the next element.</p>
</li>
<li><p>else, check the element that is on the top of the stack, and if it's smaller than the current element, output the top of the stack and add the current element to the stack, don't delete the top!</p>
</li>
<li><p>if the top of the stack is not smaller, remove the top of the stack until either steps 1 or 2 are fulfilled.</p>
</li>
</ol>
<h3 id="heading-algorithm-visualization">Algorithm Visualization</h3>
<p>If you are struggling to understand this solution, check out the animation below of the algorithm in action with the first input example.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1671131655858/1SkPALivF.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-code-implementation-1">Code Implementation</h3>
<p>I highly encourage you to code the algorithm as described above in the language of your choice. here is my implementation in c++:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stack&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;algorithm&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;arr(n); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e;
    <span class="hljs-built_in">stack</span>&lt;<span class="hljs-keyword">int</span>&gt;S;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;result;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=n<span class="hljs-number">-1</span>; i&gt;=<span class="hljs-number">0</span>; i--){
        <span class="hljs-keyword">while</span>(<span class="hljs-literal">true</span>){
            <span class="hljs-keyword">if</span>(S.size() == <span class="hljs-number">0</span>){result.push_back(<span class="hljs-number">-1</span>); S.push(arr[i]); <span class="hljs-keyword">break</span>;}
            <span class="hljs-keyword">if</span>(S.top() &lt; arr[i]){
                result.push_back(S.top());
                S.push(arr[i]);
                <span class="hljs-keyword">break</span>;
            }<span class="hljs-keyword">else</span>{
                S.pop();
            }
        }
    }
    reverse(result.begin(), result.end());
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:result)<span class="hljs-built_in">cout</span> &lt;&lt; e &lt;&lt; <span class="hljs-string">" "</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-time-and-space-complexity-1">Time and Space Complexity</h3>
<p>The efficiency of this algorithm depends on the total number of stack operations. if the current item is larger than the top element of the stack it gets directly added to the stack in constant time <strong><em>O(1)</em></strong>. However, if it's not, we might have to remove several elements of the stack which has a worst-case of <strong><em>O(N)</em></strong>, this might look like it can have a total worst-case complexity of <strong><em>O(N^2)</em></strong> but in reality, each item in the array is going to be added exactly once and removed at most one time. Thus, the time complexity of this program is going to be: <strong><em>O(N)</em></strong>.</p>
<h2 id="heading-problem-variations">Problem Variations</h2>
<p>Up until this moment, the problem consists of finding the minimum nearest element to the right, however, you can also find the Maximum item by just changing a single character. before: <code>if(S.top() &lt; arr[i])</code> After: <code>if(S.top() &gt; arr[i])</code>. Another common variation is to find the minimum nearest element to the <strong>left</strong>. To do that simply iterate the array normally from left to right and don't reverse the <code>result</code> array.</p>
<pre><code class="lang-cpp">
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    <span class="hljs-keyword">int</span> n; <span class="hljs-built_in">cin</span> &gt;&gt; n;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;arr(n); <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:arr)<span class="hljs-built_in">cin</span> &gt;&gt; e;
    <span class="hljs-built_in">stack</span>&lt;<span class="hljs-keyword">int</span>&gt;S;
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;result;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;n; i++){
        <span class="hljs-keyword">while</span>(<span class="hljs-literal">true</span>){
            <span class="hljs-keyword">if</span>(S.size() == <span class="hljs-number">0</span>){result.push_back(<span class="hljs-number">-1</span>); S.push(arr[i]); <span class="hljs-keyword">break</span>;}
            <span class="hljs-keyword">if</span>(S.top() &lt; arr[i]){
                result.push_back(S.top());
                S.push(arr[i]);
                <span class="hljs-keyword">break</span>;
            }<span class="hljs-keyword">else</span>{
                S.pop();
            }
        }
    }
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> &amp;e:result)<span class="hljs-built_in">cout</span> &lt;&lt; e &lt;&lt; <span class="hljs-string">" "</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>You've reached the end of this post, hope you enjoyed the solution for this classical competitive programming problem and learned something new. Here are some related posts:</p>
<ul>
<li><p><a target="_blank" href="https://blog.garybricks.com/stacks-and-queues-a-beginners-overview">https://blog.garybricks.com/stacks-and-queues-a-beginners-overview</a></p>
</li>
<li><p><a target="_blank" href="https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples">https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples</a></p>
</li>
<li><p><a target="_blank" href="https://blog.garybricks.com/programmers-guide-to-solving-computational-problems">https://blog.garybricks.com/programmers-guide-to-solving-computational-problems</a></p>
</li>
</ul>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. See you in the next post, stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[BFS and DFS Beginners Overview in c++]]></title><description><![CDATA[Introduction
Hello everyone! 👋, In this Post, we'll dive deeper into Graphs in programming, we'll take a look at the most common algorithms for solving competitive programming problems using Graphs, DFS, and BFS, and how to implement them in c++ whi...]]></description><link>https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c</link><guid isPermaLink="true">https://blog.garybricks.com/bfs-and-dfs-beginners-overview-in-c</guid><category><![CDATA[Competitive programming]]></category><category><![CDATA[data structures]]></category><category><![CDATA[C++]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[beginnersguide]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Fri, 09 Dec 2022 04:25:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670695542429/me-naCOvJ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone! 👋, In this Post, we'll dive deeper into Graphs in programming, we'll take a look at the most common algorithms for solving competitive programming problems using Graphs, DFS, and BFS, and how to implement them in c++ while we solve some interesting problems.</p>
<p>If you have no idea what a graph is and how to represent one check out my previous post: <a target="_blank" href="https://blog.garybricks.com/graphs-introduction-for-beginners#heading-introduction">Graphs Introduction For Beginners</a></p>
<h2 id="heading-depth-first-search-dfs">Depth-first search (DFS)</h2>
<p>Depth-first search is a straightforward graph traversal technique. The idea is that the algorithm begins at a specified node and from there proceeds to visit all nodes that are reachable from the current node. This algorithm always follows a single path in the graph as long as it finds new <strong>unvisited</strong> nodes. If the algorithm has no new unvisited nodes it returns to previous nodes and begins to explore in other directions. With DFS, each node is visited only once.</p>
<h3 id="heading-dfs-visualization">DFS visualization</h3>
<p>Let's see how a DFS algorithm would process the following graph:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666385057024/hfQKW8FrE.gif" alt="DFSanimation.gif" /></p>
<p>In this case, we are starting from node 1, and the algorithm proceeds to visit the neighbor node 2, the process repeats for nodes 3 and 4 until node 5 where there are no longer new <strong>unvisited</strong> nodes, that's the moment our algorithm returns to node 4 and chooses another route, in this case, node 6. Once the algorithm reaches node 6 there are no longer new unvisited nodes so the search terminates. The time complexity of DFS is <code>O(n+m)</code> where <strong>n</strong> is the number of nodes and <strong>m</strong> is the number of edges.</p>
<h3 id="heading-implementation">Implementation</h3>
<p>DFS can be very easy and convenient to implement using recursion, the main idea is that you define a function that receives the current node and marks it as visited, then checks for all of the adjacent nodes to that node and sends the same function with those nodes as long as they are not visited.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">int</span> n, k;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; GRAPH;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt; visited;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DFS</span><span class="hljs-params">(<span class="hljs-keyword">int</span> current)</span> </span>{
  visited[current] = <span class="hljs-number">1</span>; <span class="hljs-comment">// marking the active node as visited</span>
  <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"currently on:"</span> &lt;&lt; current &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> node : GRAPH[current]) <span class="hljs-comment">// iterate through all of it's neighboors </span>
    <span class="hljs-keyword">if</span> (!visited[node]) DFS(node); <span class="hljs-comment">// send DFS if it's a new node</span>
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
  GRAPH.resize(n + <span class="hljs-number">1</span>);
  visited.resize(n + <span class="hljs-number">1</span>);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; k; i++) {
    <span class="hljs-keyword">int</span> a, b;
    <span class="hljs-built_in">cin</span> &gt;&gt; a &gt;&gt; b;
    GRAPH[a].push_back(b);
    GRAPH[b].push_back(a);
  }

  DFS(<span class="hljs-number">1</span>); <span class="hljs-comment">// starting algorithm from node 1</span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>In the code cell above you can see the implementation using an adjacency list to represent the graph and a simple vector of booleans to keep track of the visited nodes. In this case, we are sending the DFS algorithm starting from node 1 but you can try and make the algorithm start from a different node to see what the output is.</p>
<h2 id="heading-breadth-first-search-bfs">Breadth-first search (BFS)</h2>
<p>Breadth-first search is also a traversal algorithm that is very commonly used for searching a node, finding the shortest path in a graph, and for simulations. BFS visits all the nodes but in increasing order based on their distance from the starting node, because of this, BFS can help us calculate the distance from the starting node to all other nodes.</p>
<h3 id="heading-bfs-visualization">BFS visualization</h3>
<p>Let's see what a BFS algorithm would look like on our example graph.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666460750679/xH2mEGQ2E.gif" alt="BFSanimation.gif" /></p>
<p>Just like a DFS, BFS starts from a specified node, and from there visits <strong>ALL</strong> of the nodes that are exactly 1 node away, once all nodes of that level are visited, the algorithm continues with the second level and this process continues until all levels are visited.</p>
<p>The time complexity of BFS is <code>O(n+m)</code> exactly the same as DFS.</p>
<h3 id="heading-implementation-1">Implementation</h3>
<p>The implementation of a BFS algorithm is not as simple as with the DFS but in this section, we'll see the most typical method that is based on a queue of nodes. The algorithm works as follows: First, we define a queue of nodes, I normally like to name it "BFS", and we push the origin (starting node). Here is the interesting part: while the queue is not empty, we are going to save the front of the queue and remove it no matter what, then we check all of the adjacent nodes to that saved node and push them to the queue but <strong>only if they are not visited</strong>, this process is going to repeat until the queue is empty.</p>
<p>If you don't know what a queue is, check out this section on my post about stacks and queues: https://blog.garybricks.com/stacks-and-queues-a-beginners-overview#heading-what-is-a-queue just understand the main idea and come back here since we are going to use c++ handy implementation.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n, k;
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; <span class="hljs-title">GRAPH</span><span class="hljs-params">(n + <span class="hljs-number">1</span>)</span></span>;
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">distance</span><span class="hljs-params">(n + <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>)</span></span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; k; i++) {
    <span class="hljs-keyword">int</span> a, b;
    <span class="hljs-built_in">cin</span> &gt;&gt; a &gt;&gt; b;
    GRAPH[a].push_back(b);
    GRAPH[b].push_back(a);
  }
  <span class="hljs-built_in">queue</span>&lt;<span class="hljs-keyword">int</span>&gt; BFS;
  BFS.push(<span class="hljs-number">1</span>);
  distance[<span class="hljs-number">1</span>] = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">while</span> (!BFS.empty()) {
    <span class="hljs-keyword">int</span> current = BFS.front();
    BFS.pop();
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"currently on:"</span> &lt;&lt; current &lt;&lt; <span class="hljs-built_in">endl</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> node : GRAPH[current])
      <span class="hljs-keyword">if</span> (distance[node] == <span class="hljs-number">-1</span>) {
        distance[node] = distance[current] + <span class="hljs-number">1</span>;
        BFS.push(node);
      }
  }

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt;= n; i++)
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"Node:"</span> &lt;&lt; i &lt;&lt; <span class="hljs-string">" is "</span> &lt;&lt; distance[i]
         &lt;&lt; <span class="hljs-string">" nodes away from node 1\n"</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>In the code cell above you can see my implementation in c++ using an adjacency list to represent the graph, notice how instead of using a vector of bools to see if a node has been visited we use a vector of ints to save the "distance" to node 1. For this case, I decided to initialize that distance vector with -1, "-1" is going to represent a node that has not been visited. Just like DFS, try to change the origin to see what the output is.</p>
<h2 id="heading-dfs-bfs-practice">DFS, BFS - Practice</h2>
<p>In this section, we'll see some competitive programming problems I've faced and how they were solved using a DFS or BFS algorithm, at the same time we dive a little deeper into the topic and learn new things, read the problems and try to solve them by yourself, don't worry, the solutions are at the end of this section.</p>
<h3 id="heading-1-escape-the-maze">1 - Escape The Maze</h3>
<p>Given a Matrix of characters representing a maze, where "*" represents a wall, "E" represents the entry to the maze, and "X" the exit, print whether is possible or not to reach "X" starting from "E" through the empty spaces. Examples:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666474169273/7zxWAVg2G.png" alt="MazeExamples.png" /></p>
<h3 id="heading-2-water-puddles">2 - Water Puddles</h3>
<p>Given a Matrix of characters of size <strong>n * m</strong> in which <strong>"w"</strong> represents water and <strong>"L"</strong> represents land, output how many puddles of water are on the map and the size of the biggest one.</p>
<h4 id="heading-important-notes">IMPORTANT NOTES:</h4>
<p>A puddle is considered valid if it's <strong>completely</strong> surrounded by land, this means that any body of water touching the edges of the map does not count as a puddle.</p>
<p>Any body of water is considered connected to another if it's orthogonally or diagonally adjacent to it. See the examples below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670021555040/0c88f3e4-545e-4c2a-b7e1-85f9d73ff515.png" alt /></p>
<h3 id="heading-3-oil-spill-simulation">3 - Oil Spill Simulation</h3>
<p>Given a Matrix of characters of size n*m in which "." represents water, "#" land, "*" contaminated water, and "$" represents an oil plant that has a spill that every day spreads to an orthogonally adjacent square of water. Output what the Matrix will look like after k days. Example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670199909093/aCjx5Lpom.png" alt /></p>
<h3 id="heading-4-safest-place">4 - Safest Place</h3>
<p>It's 2020 and covid is all over the place, as a responsible human you are trying to stay as furthest away from other people.</p>
<p>Given a Matrix of characters of size n*m in which "#" represents a wall, "." an empty space, and "G" a person. find the empty square in which you can be the furthest from everyone. Example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670529308820/EN7RfGVG1.png" alt class="image--center mx-auto" /></p>
<p>Output the coordinates of the safest place, for the examples above this would be the answer:</p>
<pre><code class="lang-cpp"><span class="hljs-number">3</span> <span class="hljs-number">2</span>
<span class="hljs-number">4</span> <span class="hljs-number">4</span>
</code></pre>
<h3 id="heading-5-king-escape">5 - King Escape</h3>
<p>You are given a chess board of size n*n, the coordinates of an enemy queen, the coordinates of your king, and an exit coordinate, your job is to output whether or not the king can reach the exit coordinate without getting in check and following the king movement rules. If it's possible, output the coordinates the king took to reach the exit, and if it's not possible, output -1;</p>
<p>IMPORTANT:</p>
<ul>
<li><p>For this problem, the enemy queen will never move.</p>
</li>
<li><p>If it's possible to reach the exit coordinate you have to output the <strong>shortest</strong> path the king took, if there are several answers output any of them.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670107659663/-eAXMxLCM.png" alt /></p>
<h3 id="heading-1-escape-the-maze-solution">1 - Escape The Maze - Solution</h3>
<p>This is a very classical problem, however, the tricky part of this problem was to figure out how to represent the graph in order to apply the DFS algorithm.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span> {</span>
  <span class="hljs-keyword">int</span> i, j;
};

<span class="hljs-keyword">int</span> n, m;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">string</span>&gt; MAZE;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;&gt; visited;
node E, X;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">getInput</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">string</span> row;
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;
  getline(<span class="hljs-built_in">cin</span>, row);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++) {
    getline(<span class="hljs-built_in">cin</span>, row);
    MAZE.push_back(row);
  }
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">findStartEnd</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++)
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; m; j++) {
      <span class="hljs-keyword">if</span> (MAZE[i][j] == <span class="hljs-string">'e'</span>) E = {i, j};
      <span class="hljs-keyword">if</span> (MAZE[i][j] == <span class="hljs-string">'x'</span>) X = {i, j};
    }
}

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span> </span>{
  <span class="hljs-keyword">if</span> (i &gt;= <span class="hljs-number">0</span> &amp;&amp; j &gt;= <span class="hljs-number">0</span> &amp;&amp; i &lt; n &amp;&amp; j &lt; m &amp;&amp; MAZE[i][j] != <span class="hljs-string">'*'</span> &amp;&amp; !visited[i][j])
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DFS</span><span class="hljs-params">(node c)</span> </span>{
  visited[c.i][c.j] = <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">if</span> (valid(c.i + <span class="hljs-number">1</span>, c.j)) DFS({c.i + <span class="hljs-number">1</span>, c.j});
  <span class="hljs-keyword">if</span> (valid(c.i - <span class="hljs-number">1</span>, c.j)) DFS({c.i - <span class="hljs-number">1</span>, c.j});
  <span class="hljs-keyword">if</span> (valid(c.i, c.j + <span class="hljs-number">1</span>)) DFS({c.i, c.j + <span class="hljs-number">1</span>});
  <span class="hljs-keyword">if</span> (valid(c.i, c.j - <span class="hljs-number">1</span>)) DFS({c.i, c.j - <span class="hljs-number">1</span>});
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  getInput();
  findStartEnd();
  visited.resize(n, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;(m, <span class="hljs-number">0</span>));
  DFS(E);

  <span class="hljs-keyword">if</span> (visited[X.i][X.j])
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"There is a solution!"</span>;
  <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"IT'S IMPOSSIBLE TO ESCAPE"</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>This is the solution I came up with, it's a bit longer than what we are used to, but don't worry, I carefully separated every part in order to make it as readable as possible. Notice how when working with this type of problem is very comfortable to have your graph and visited matrix global. You might be wondering where our Graph is, we'll get to that in a second, first, let's get the input using our <code>getInput()</code> function. You might already have noticed the problem does not give you a graph as we have seen above, this is where you must think and realize that you can represent the nodes as the coordinates in the <code>MAZE</code> matrix, that's why I defined a node structure that simply saves an <strong>x</strong> and <strong>y</strong> coordinates. Then, we call our <code>findStartEnd()</code> function, this simply iterates through the <code>MAZE</code> and finds the starting and ending nodes. Now we initialize our visited matrix, and finally, we send our DFS starting from the start node. The DFS works as follows: first, we mark the current node as visited as we normally do, here's the interesting part: notice how we don't have our adjacency matrix, that is because it's not necessary, we literally check the adjacent positions in the Matrix! to do that I defined a <code>valid()</code> function that simply checks if it's a valid node for the DFS to go, that function takes care of the walls, if it's visited, and for out-of-bounds cases, this is a perfect example of an implicit graph.</p>
<h3 id="heading-2-water-puddles-solution">2 - Water Puddles - Solution</h3>
<p>The tricky part of this problem was to figure out if a puddle is valid, and its size. Below you can find the code with the explanation.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">int</span> n, m, numPuddles = <span class="hljs-number">0</span>, BiggestPuddle = <span class="hljs-number">0</span>;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;&gt; MAP;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;&gt; visited;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; X = {<span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>};
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; Y = {<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>};

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; m;
  MAP.resize(n, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;(m));
  visited.resize(n, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;(m));
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &amp;row : MAP)
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &amp;e : row) <span class="hljs-built_in">cin</span> &gt;&gt; e;
}

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span> </span>{
  <span class="hljs-keyword">if</span> (i &gt;= <span class="hljs-number">0</span> &amp;&amp; j &gt;= <span class="hljs-number">0</span> &amp;&amp; i &lt; n &amp;&amp; j &lt; m &amp;&amp; !visited[i][j] &amp;&amp; MAP[i][j] == <span class="hljs-string">'W'</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DFS</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j, <span class="hljs-keyword">int</span> &amp;size, <span class="hljs-keyword">bool</span> &amp;puddle)</span> </span>{
  visited[i][j] = <span class="hljs-literal">true</span>;
  size++;
  <span class="hljs-keyword">if</span> (i == <span class="hljs-number">0</span> || j == <span class="hljs-number">0</span> || i == n - <span class="hljs-number">1</span> || j == m - <span class="hljs-number">1</span>) puddle = <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> d = <span class="hljs-number">0</span>; d &lt; <span class="hljs-number">8</span>; d++) {
    <span class="hljs-keyword">if</span> (valid(i + X[d], j + Y[d])) DFS(i + X[d], j + Y[d], size, puddle);
  }
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  init();
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; m; j++)
      <span class="hljs-keyword">if</span> (MAP[i][j] == <span class="hljs-string">'W'</span> &amp;&amp; !visited[i][j]) {
        <span class="hljs-keyword">int</span> size = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">bool</span> isPuddle = <span class="hljs-literal">true</span>;
        DFS(i, j, size, isPuddle);
        <span class="hljs-keyword">if</span> (isPuddle) {
          BiggestPuddle = max(BiggestPuddle, size);
          numPuddles++;
        }
      }
  }

  <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"There are: "</span> &lt;&lt; numPuddles
       &lt;&lt; <span class="hljs-string">" puddles in the map, the largest one has a size of: "</span>
       &lt;&lt; BiggestPuddle;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>To solve this problem, we iterate over the map of chars and if we find water we are going to assume it's a valid puddle and send the <code>dfs</code> on that specific coordinate, notice how we have two more parameters: <code>size</code> and <code>isPuddle</code> which are always passed by reference: <code>&amp;</code>, this is important since we want to be able to modify the variables. <code>DFS</code> is not very different from the others, we mark the current position as visited and send the <code>DFS</code> to the eight possible adjacent coordinates, the only difference is that we always increment the <code>size</code> variable and if we reach an edge of the Map, we are going to say that the puddle is not valid. Once the <code>DFS</code> is done, we check if it's a valid puddle, if true, we increment the number of puddles found, and we check if it's bigger than the biggest puddle.</p>
<h3 id="heading-3-oil-spill-simulation-solution">3 - Oil Spill Simulation - Solution</h3>
<p>Just by looking at the example, you can tell that a BFS algorithm behaves exactly the same, the tricky part was how to stop the BFS at the <strong>k</strong> day. Below you can find my code with the explanation.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span> {</span> <span class="hljs-keyword">int</span> i, j, level; };

<span class="hljs-keyword">int</span> N, M, days;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;&gt; MAP;
<span class="hljs-keyword">int</span> X[<span class="hljs-number">4</span>] = {<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>};
<span class="hljs-keyword">int</span> Y[<span class="hljs-number">4</span>] = {<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>};
node source;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">get_input</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; N &gt;&gt; M &gt;&gt; days;
  MAP.resize(N, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;(M));
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; N; i++) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; M; j++) {
      <span class="hljs-built_in">cin</span> &gt;&gt; MAP[i][j];
      <span class="hljs-keyword">if</span> (MAP[i][j] == <span class="hljs-string">'$'</span>) source = {i, j, <span class="hljs-number">0</span>};
    }
  }
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">print</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> e : MAP) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> c : e) <span class="hljs-built_in">cout</span> &lt;&lt; c;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"\n"</span>;
  }
}

<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span></span>{ <span class="hljs-keyword">return</span> i &gt;= <span class="hljs-number">0</span> &amp;&amp; j &gt;= <span class="hljs-number">0</span> &amp;&amp; i &lt; N &amp;&amp; j &lt; M &amp;&amp; MAP[i][j] == <span class="hljs-string">'.'</span>;}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  get_input();
  <span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
  BFS.push(source);
  <span class="hljs-keyword">while</span> (!BFS.empty()) {
    node e = BFS.front();
    BFS.pop();
    <span class="hljs-keyword">if</span> (e.level &gt;= days) <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">4</span>; i++){
        <span class="hljs-keyword">if</span>(valid(e.i + X[i], e.j + Y[i])){
            MAP[e.i + X[i]][e.j + Y[i]] = <span class="hljs-string">'*'</span>;
            BFS.push({e.i+X[i], e.j+Y[i], e.level+<span class="hljs-number">1</span>});
        }
    }
  }
  print();
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Just like the previous problems, we represented a node as the coordinates on the matrix, and notice how this node has an extra <strong>level</strong> variable, this is going to help us know how far we are from the origin which is going to help us stop the BFS.</p>
<p>The algorithm works as follows:</p>
<ol>
<li><p>while the BFS is not empty get the current node and remove it</p>
</li>
<li><p>check if the node has a distance greater or equal to k. if so, end the algorithm.</p>
</li>
<li><p>for each valid adjacent node, modify that node to become contaminated and add it to the BFS with a level increment.</p>
</li>
</ol>
<p>Once the BFS finishes, print the final Map. This problem cannot be solved with a DFS due to the land that can ruin the simulation and give an incorrect result.</p>
<h3 id="heading-4-safest-place-solution">4 - Safest Place - Solution</h3>
<p>One of the first ideas most people have is to send a BFS from every single empty space and get the distance to the <strong>closest</strong> person and by doing that, find the best square, however, this idea is extremely inefficient. Another idea can be to send a BFS from every single person and get the distance to every single empty square and then fuse them together on a final matrix that contains all of the minimum distances, and lastly just search for the biggest value.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670540476464/CNS0avWP-.png" alt class="image--center mx-auto" /></p>
<p>This is the correct idea, however, creating a distance matrix for each person can bring a lot of implementation and memory problems, the best and easiest solution involves using just a single BFS and distance matrix, it turns out that is totally possible and easy to send a BFS algorithm from several origins. Below you can see my solution.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span> {</span><span class="hljs-keyword">int</span> i, j;};

<span class="hljs-keyword">int</span> N, M;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;&gt; MAP;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; V; <span class="hljs-comment">// Distance Matrix</span>
<span class="hljs-keyword">int</span> X[<span class="hljs-number">4</span>] = {<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>};
<span class="hljs-keyword">int</span> Y[<span class="hljs-number">4</span>] = {<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>};
<span class="hljs-built_in">vector</span>&lt;node&gt; people;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">get_input</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// get Map, initialize the visited matrix, find the people</span>
  <span class="hljs-built_in">cin</span> &gt;&gt; N &gt;&gt; M;
  MAP.resize(N, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">char</span>&gt;(M));
  V.resize(N, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;(M, <span class="hljs-number">-1</span>)); <span class="hljs-comment">// -1 represents not visited</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; N; i++) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; M; j++) {
      <span class="hljs-built_in">cin</span> &gt;&gt; MAP[i][j];
      <span class="hljs-keyword">if</span> (MAP[i][j] == <span class="hljs-string">'G'</span>) people.push_back({i, j});
    }
  }
}
<span class="hljs-comment">// checks if the node is inside bounds, is an empty square, and is not visited</span>
<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> j)</span></span>{ <span class="hljs-keyword">return</span> i &gt;= <span class="hljs-number">0</span> &amp;&amp; j &gt;= <span class="hljs-number">0</span> &amp;&amp; i &lt; N &amp;&amp; j &lt; M &amp;&amp; MAP[i][j] == <span class="hljs-string">'.'</span> &amp;&amp; V[i][j]==<span class="hljs-number">-1</span>;}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  get_input();
<span class="hljs-comment">// instead of adding a single source, we add all people.</span>
  <span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> e:people){BFS.push(e); V[e.i][e.j] = <span class="hljs-number">0</span>;}
  <span class="hljs-keyword">while</span> (!BFS.empty()) {
    node e = BFS.front();
    BFS.pop();
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">4</span>; i++){
        <span class="hljs-keyword">if</span>(valid(e.i + X[i], e.j + Y[i])){
            V[e.i + X[i]][e.j + Y[i]] = V[e.i][e.j] + <span class="hljs-number">1</span>;
            BFS.push({e.i+X[i], e.j+Y[i]});
        }
    }
  }
  node result; <span class="hljs-comment">// final search for the maximum value</span>
  <span class="hljs-keyword">int</span> maxi = <span class="hljs-number">-1</span>;
  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;N; i++){
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> j=<span class="hljs-number">0</span>; j&lt;M; j++)<span class="hljs-keyword">if</span>(V[i][j] &gt; maxi){
      maxi = V[i][j];
      result = {i, j};
    }
  }
  <span class="hljs-built_in">cout</span> &lt;&lt; result.i &lt;&lt; <span class="hljs-string">" "</span> &lt;&lt; result.j;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>This is a very standard BFS the big difference is how we define our visited matrix, for a DFS algorithm we normally use booleans but for a BFS we can actually save ints that represent the distance, and by doing that we can know the minimum distance from the origin to ANY other square which is going to be really helpful. And lastly, instead of sending the BFS from a single origin, we initialize the BFS with all of the nodes representing people, after that the algorithm remains the same.</p>
<p>Once the BFS is done, we are going to have our perfect visited matrix with all of the correct distances and we just need to find the maximum value.</p>
<h3 id="heading-5-king-escape-solution">5 - King Escape - Solution</h3>
<p>This problem was very similar to the escape maze problem, however, the problem was that if there was a solution, you had to output the shortest route the king took, because of this, a <strong>BFS</strong> algorithm was the right choice. Below you can see my implementation with the explanation.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;algorithm&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;queue&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">node</span> {</span>
  <span class="hljs-keyword">int</span> x, y;
};
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; X = {<span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>};  <span class="hljs-comment">// directions</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; Y = {<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>};  <span class="hljs-comment">// directions</span>
<span class="hljs-keyword">int</span> n, qx, qy, kx, ky, ex, ey;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;&gt; M;     <span class="hljs-comment">// 0 = empty, 1 = check</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; V;      <span class="hljs-comment">// distance MAP</span>
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;node&gt;&gt; BACK;  <span class="hljs-comment">// Helper for recreating path</span>
<span class="hljs-built_in">vector</span>&lt;node&gt; path; <span class="hljs-comment">// final path</span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">initBoard</span><span class="hljs-params">()</span> </span>{
  M.resize(n, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;(n, <span class="hljs-number">0</span>));
  V.resize(n, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;(n, <span class="hljs-number">-1</span>));
  BACK.resize(n, <span class="hljs-built_in">vector</span>&lt;node&gt;(n, {<span class="hljs-number">-1</span>, <span class="hljs-number">-1</span>}));
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; i++) {
    M[qx][i] = <span class="hljs-number">1</span>;
    M[i][qy] = <span class="hljs-number">1</span>;
  }
  <span class="hljs-keyword">int</span> x = qx, y = qy;
  <span class="hljs-keyword">while</span> (x &gt;= <span class="hljs-number">0</span> &amp;&amp; y &gt;= <span class="hljs-number">0</span>) {
    M[x][y] = <span class="hljs-number">1</span>;
    x--, y--;
  }
  x = qx, y = qy;
  <span class="hljs-keyword">while</span> (x &gt;= <span class="hljs-number">0</span> &amp;&amp; y &lt; n) {
    M[x][y] = <span class="hljs-number">1</span>;
    x--, y++;
  }
  x = qx, y = qy;
  <span class="hljs-keyword">while</span> (x &lt; n &amp;&amp; y &gt;= <span class="hljs-number">0</span>) {
    M[x][y] = <span class="hljs-number">1</span>;
    x++, y--;
  }
  x = qx, y = qy;
  <span class="hljs-keyword">while</span> (x &lt; n &amp;&amp; y &lt; n) {
    M[x][y] = <span class="hljs-number">1</span>;
    x++, y++;
  }
}
<span class="hljs-comment">// checks if it's not visited, not in check and inside the board.</span>
<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">valid</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y)</span> </span>{ 
  <span class="hljs-keyword">return</span> x &gt;= <span class="hljs-number">0</span> &amp;&amp; y &gt;= <span class="hljs-number">0</span> &amp;&amp; x &lt; n &amp;&amp; y &lt; n &amp;&amp; !M[x][y] &amp;&amp; V[x][y] == <span class="hljs-number">-1</span>;
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; qx &gt;&gt; qy &gt;&gt; kx &gt;&gt; ky &gt;&gt; ex &gt;&gt; ey;
  qx--, qy--, kx--, ky--, ex--, ey--;
  initBoard();
  <span class="hljs-built_in">queue</span>&lt;node&gt; BFS;
  BFS.push({kx, ky});
  V[kx][ky] = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">while</span> (BFS.size()) {
    node current = BFS.front();
    BFS.pop();
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">8</span>; i++) {
      <span class="hljs-keyword">if</span> (valid(current.x + (X[i]), current.y + (Y[i]))) {
        V[current.x + (X[i])][current.y + (Y[i])] = V[current.x][current.y] + <span class="hljs-number">1</span>;
        BACK[current.x + (X[i])][current.y + (Y[i])] = current;
        BFS.push({current.x + (X[i]), current.y + (Y[i])});
      }
    }
  }
  <span class="hljs-keyword">if</span> (V[ex][ey] == <span class="hljs-number">-1</span>) { <span class="hljs-comment">// checking if the escape square was not visited</span>
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-number">-1</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
  }
  node current = {ex, ey};
  <span class="hljs-keyword">while</span> (!(current.x == <span class="hljs-number">-1</span> &amp;&amp; current.y == <span class="hljs-number">-1</span>)) {
    path.push_back(current);
    current = BACK[current.x][current.y];
  }
  reverse(path.begin(), path.end());
  <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"-------------\n"</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">1</span>; i &lt; path.size(); i++)
    <span class="hljs-built_in">cout</span> &lt;&lt; path[i].x + <span class="hljs-number">1</span> &lt;&lt; <span class="hljs-string">" "</span> &lt;&lt; path[i].y + <span class="hljs-number">1</span> &lt;&lt; <span class="hljs-string">" =&gt; "</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Just like every problem until now, we need to represent our graph, in this case, we can create a Matrix as the chessboard, and the values of the matrix can be either 0 or 1 where 1 is going to represent a square under check. We also create our distance matrix which is going to be helpful.</p>
<p>In order to "reconstruct" the path we are going to need an additional BACK matrix this is a brilliant way to know the square a square comes from. And lastly, we have our directions array that is going to help later on in pointing to the adjacent squares.</p>
<p>First, we initialize our Graph "M" with the <code>initBoard()</code> function which means marking every queen attacking square as "check".</p>
<p>Then we send our BFS on the king square and for each valid adjacent square we update the distance on the Visited Matrix "V", we also update our BACK matrix and send the BFS.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">if</span> (valid(current.x + (X[i]), current.y + (Y[i]))) {
<span class="hljs-comment">// the adjacent node is going to have a distance of the current node +1</span>
V[current.x + (X[i])][current.y + (Y[i])] = V[current.x][current.y] + <span class="hljs-number">1</span>;
<span class="hljs-comment">// the adjacent node is going to come from the current node</span>
BACK[current.x + (X[i])][current.y + (Y[i])] = current;
BFS.push({current.x + (X[i]), current.y + (Y[i])});}
</code></pre>
<p>Once the BFS finishes. we check if the escape square was not visited, if this is the case, we output -1 else we can reconstruct the path by starting from the escape square and going back until it's no longer possible.</p>
<pre><code class="lang-cpp">  node current = {ex, ey};
  <span class="hljs-keyword">while</span> (!(current.x == <span class="hljs-number">-1</span> &amp;&amp; current.y == <span class="hljs-number">-1</span>)) {
    path.push_back(current);
    current = BACK[current.x][current.y];
  }
  reverse(path.begin(), path.end());
</code></pre>
<p>Notice how we created a final path vector of nodes, and we push_back the current position, this is going to give us the final route backward, that's why we have to use the reverse() method.</p>
<h2 id="heading-conclusion-farewell"><strong>Conclusion - Farewell</strong></h2>
<p>You've reached the end of this lesson on BFS and DFS, remember that this is a skill that takes a lifetime to master so don't feel frustrated if you don't get it right away because this isn't easy, but I hope some of the guidelines we saw today were helpful and the basic foundations on this topic were well understood, remember, there is still a lot to learn and we definitively didn't cover everything on Graphs, but I hope this was a good beginner overview and that you managed to grasp the basic ideas.</p>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. Stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Graphs Introduction For Beginners]]></title><description><![CDATA[Introduction
Hello everyone! 👋, In this Post, we will take a beginner's dive into Graphs data structure in programming, we'll take a look at what are they, what are they for, the different types of graphs, the differences between graphs and trees, a...]]></description><link>https://blog.garybricks.com/graphs-introduction-for-beginners</link><guid isPermaLink="true">https://blog.garybricks.com/graphs-introduction-for-beginners</guid><category><![CDATA[data structures]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[C++]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[data structure and algorithms ]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Fri, 21 Oct 2022 17:43:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1666373706677/d9ixepteW.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone! 👋, In this Post, we will take a beginner's dive into Graphs data structure in programming, we'll take a look at what are they, what are they for, the different types of graphs, the differences between graphs and trees, and how to implement a Graph structure using c++,</p>
<h2 id="heading-what-is-a-graph">What is a Graph?</h2>
<p>In Computer Science a graph is a non-linear data structure that can be used to represent complex relationships between objects. Graphs are made up of a finite number of nodes or vertices and the edges that connect them. The vertices are sometimes also referred to as nodes and the edges are lines or arcs that connect any two nodes in the graph. In this post, we will follow the node and edge convention. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665285106923/QH4aLLmYc.png" alt="GraphExample.png" /></p>
<h2 id="heading-what-are-graphs-for">What are Graphs for?</h2>
<p>A graph can be a possible choice every time there are relations between objects for example in social networking sites where a user can be represented with a node and connections between them are represented with edges, another good example can be found on google maps where a location can be represented as the node, and the path can be represented with the edges, then we can implement an algorithm to find the shortest route between two nodes. Graphs can also be used for solving puzzles with only one solution like mazes.</p>
<h2 id="heading-types-of-graph">Types Of Graph</h2>
<ol>
<li><p>Null Graph - There are no edges connecting the Nodes.</p>
</li>
<li><p>Trivial Graph - only has one single node and it's the smallest graph possible.</p>
</li>
<li><p>Undirected Graph - Edges don't have any direction, if a node <strong>A</strong> connects a node <strong>B</strong> the opposite is true.</p>
</li>
<li><p>Directed Graph - All edges have a specified direction, the normal convention is that node <strong>A</strong> connects the node <strong>B</strong> in that order.</p>
</li>
<li><p>Connected Graph - Each one of the nodes can visit any other node in the Graph.</p>
</li>
<li><p>Disconnected Graph - If at least one node is not reachable from another node is considered a disconnected Graph.</p>
</li>
<li><p>Complete Graph - Every single node is connected to each other node.</p>
</li>
<li><p>Cycle Graph - A graph where all of the nodes form one perfect cycle.</p>
</li>
<li><p>Cyclic Graph - at least 1 cycle is formed within the Graph.</p>
</li>
<li><p>Bipartite Graph - A graph in which the nodes can be divided into two sets such that the nodes in each set do not contain any edge between them.</p>
</li>
<li><p>Weighted Graph - A graph where all of its edges have a specified value, for example, if each node represents a city, the edges can represent roads with the time it takes to reach another city.</p>
</li>
</ol>
<h2 id="heading-basic-operations-for-graphs">Basic Operations for Graphs</h2>
<p>Here are some of the most common and basic operations for Graphs:</p>
<ul>
<li>Insertion of Nodes/Edges</li>
<li>Deletion of Nodes/Edges</li>
<li>Searching - Uses Algorithms like BFS</li>
<li>Traversal - Visit all the nodes in the graph using algorithms like DFS</li>
</ul>
<h2 id="heading-tree-vs-graph">Tree vs Graph</h2>
<p>If you have worked with trees before, you might get a little confused about the differences, but in simple terms, just know that trees are just more restricted types of graphs. Every tree is always a graph, but not every graph is a tree. The same is true with Linked Lists and Heaps.</p>
<h2 id="heading-representing-a-graph">Representing a Graph</h2>
<p>You might be wondering how can a graph be represented with code. Well, there are 2 simple ways to store a graph, using an Adjacency Matrix or an Adjacency List, we'll see both of them in action.</p>
<h3 id="heading-adjacency-matrix">Adjacency Matrix</h3>
<p>In this method, the graph is stored in the form of a 2D matrix where rows and columns denote the nodes and each entry in the matrix represents either 1(connected) or 0(disconnected), if the graph you are trying to represent is a weighted graph, then you can put the weight instead.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665345194492/YxYvwm3TG.png" alt="Matrix_Adjecent.png" /></p>
<p>In the image above, you can see how that specific graph would be represented using an adjacency matrix, the node 1 is connected to nodes 2 and 5, that's why on row 1 columns 2 and 5 are 1 which means connected, this process repeats for every single node.</p>
<h3 id="heading-adjacency-list">Adjacency List</h3>
<p>This method is very similar to the 2D matrix because we are going to create a collection of N empty lists, and for each node, we push_back() the adjacent nodes like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665349103077/7_ZQcvipD.png" alt="List_Adjecent.png" /></p>
<p>If you want to use this method to represent a weighted graph then you would have to save pairs in each element of the array, the node, and the weight.</p>
<h3 id="heading-differences-between-methods">Differences Between Methods.</h3>
<p>there are several factors to consider when choosing what method to use. If for example, the amount of nodes <strong>N</strong> is very large, then you only have the adjacency list method which in most cases has way less memory usage, however, the Matrix method can perform <code>O(1)</code> constant operation for adding a node as well as for removing a connection which the adjacency list does not. However, if we try to consult the adjacent nodes to a specific node the List method is better since it doesn't have unnecessary nodes stored in it, and on top of that, you can be more creative by ordering the list or changing the List for a priority queue, set, and more.</p>
<h2 id="heading-implement-a-graph-structure-in-c">Implement a Graph Structure in C++</h2>
<h3 id="heading-receiving-input">Receiving Input</h3>
<p>The problem normally specifies how the input is given, but the standard is as follows:
In the first line <strong>N</strong> and <strong>K</strong> where <strong>N</strong> is the number of nodes in the graph and <strong>K</strong> is the number of edges, then we are given <strong>K</strong> lines, and for each line <strong>A</strong> and <strong>B</strong> representing that the node <strong>A</strong> connects node <strong>B</strong>, the problem normally specifies if it's directed or undirected and if it's a weighted graph, if it is, the third number for each line is added representing the weight of the edge.</p>
<h3 id="heading-adjacency-matrix">Adjacency Matrix</h3>
<p>The code below uses a 2D vector of booleans because, for this particular example, the graph is Undirected and has no weight.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n, k;
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
  <span class="hljs-comment">// +1 because the graph nodes start from 1 not 0</span>
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;&gt; <span class="hljs-title">GRAPH</span><span class="hljs-params">(n + <span class="hljs-number">1</span>, <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">bool</span>&gt;(n + <span class="hljs-number">1</span>))</span></span>; 
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; k; i++) {
    <span class="hljs-keyword">int</span> nodeA, nodeB;
    <span class="hljs-built_in">cin</span> &gt;&gt; nodeA &gt;&gt; nodeB;
    GRAPH[nodeA][nodeB] = <span class="hljs-number">1</span>;
    GRAPH[nodeB][nodeA] = <span class="hljs-number">1</span>;
  }
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> row : GRAPH) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> col : row) <span class="hljs-built_in">cout</span> &lt;&lt; col &lt;&lt; <span class="hljs-string">" "</span>;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Remember that if we wanted to represent a weighted graph, we receive an extra parameter for every edge, normally at the end, with the weight of that connection, and the only thing we would have to do is change the <strong>bool</strong> for <strong>int</strong> on our matrix.</p>
<p>If the problem specifies that the graph is directed, we would have to simply remove: <code>GRAPH[nodeB][nodeA] = 1;</code> and that's it!</p>
<h3 id="heading-adjacency-list">Adjacency List</h3>
<p>In the code cell below you can see the implementation. Notice how it's very similar to the Matrix method.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n, k;
  <span class="hljs-built_in">cin</span> &gt;&gt; n &gt;&gt; k;
  <span class="hljs-comment">// +1 because the graph nodes start from 1 not 0</span>
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&gt; <span class="hljs-title">GRAPH</span><span class="hljs-params">(n + <span class="hljs-number">1</span>)</span></span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; k; i++) {
    <span class="hljs-keyword">int</span> nodeA, nodeB;
    <span class="hljs-built_in">cin</span> &gt;&gt; nodeA &gt;&gt; nodeB;
    GRAPH[nodeA].push_back(nodeB);
    GRAPH[nodeB].push_back(nodeA);
  }
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> node = <span class="hljs-number">1</span>; node &lt;= n; node++) {
    <span class="hljs-built_in">cout</span> &lt;&lt; node &lt;&lt; <span class="hljs-string">" : "</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> adjacent : GRAPH[node]) <span class="hljs-built_in">cout</span> &lt;&lt; adjacent &lt;&lt; <span class="hljs-string">", "</span>;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>I personally like this method more because we are saving a lot of memory and it's more readable and easy to understand in my opinion. Remember that if we wanted to add weight to this graph, instead of doing: <code>.push_back(nodeB);</code> we can: <code>.push_back({nodeB, weight});</code> and change the vector type from int, to pair.</p>
<h2 id="heading-conclution-farewell">Conclution - Farewell</h2>
<p>You've reached the end of this lesson on Graphs, remember that this is a skill that takes a lifetime to master so don't feel frustrated if you don't get it right away because this isn't easy, but I really hope some of the guidelines we saw today were helpful and the basic foundations on this topic were well understood, remember, there is still a lot to learn and we definitively didn't cover everything on Graphs, but I hope this was a good beginner overview and that you managed to grasp the basic ideas.</p>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. In the next posts, we are going to dive a little bit more into this topic and we will see the common algorithms that are applied to Graphs, like DFS and BFS, and how we can use them to solve some basic competitive programming problems. Stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Segment Tree Introduction In C++]]></title><description><![CDATA[Introduction
Welcome Back! In this post, we will take a beginner's dive into segment trees in c++, we will look at what are they. what are they for? and we will solve some basic competitive programming problems together.
Before we begin, I highly sug...]]></description><link>https://blog.garybricks.com/segment-tree-introduction-in-c</link><guid isPermaLink="true">https://blog.garybricks.com/segment-tree-introduction-in-c</guid><category><![CDATA[data structures]]></category><category><![CDATA[C++]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[beginnersguide]]></category><category><![CDATA[segment-tree]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Mon, 19 Sep 2022 14:22:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1663555445165/6HTJQjdEj.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Welcome Back! In this post, we will take a beginner's dive into segment trees in c++, we will look at what are they. what are they for? and we will solve some basic competitive programming problems together.</p>
<p>Before we begin, I highly suggest that you check out my post about <a target="_blank" href="https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples">Efficiency And Big O Notation</a> altho it is not required 😉.</p>
<h2 id="heading-what-is-a-segment-tree">What is a Segment Tree?</h2>
<p>Segment Tree is one of the most used data structures in competitive programming, to understand why they are such a big deal, let's think of the following problem:</p>
<p>Let's say we have an array of N elements, like the one shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663115987315/MubmwLDDI.png" alt="simple array.png" /></p>
<p>And we need to perform two types of operations. The first operation will be an <code>update(i, v)</code>, this function will take the index of the element we want to change, and the new value, and replace it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663179351065/v2wpD_QJA.gif" alt="seg_tree_optimized.gif" /></p>
<p>The second operation is going to calculate to sum in a segment a.k.a range in the array from [ L to R) Note that in the request for the sum we take the left border [ L inclusive, and the right border R ) exclusive. In this post, we will follow this inclusive exclusive standard for all segments. Here are some examples of the <code>sum(l, r)</code> in action:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663185161909/Ee6RoelwJ.gif" alt="seg_tree_query_optimized.gif" /></p>
<p>A Segment tree is a data structure that will allow us to perform both of the operations in <strong>log(n)</strong> time complexity, we will look more in detail at how this works, but before we continue, let's see how we could solve this problem only using iteration. </p>
<h2 id="heading-iterative-solution">Iterative Solution</h2>
<p>Let's think of the most basic solution that does not involve a segment tree first.
In the code cell below, we define a vector globally for commodity reasons, and we receive the input <strong>N</strong>, then we resize the vector to the given size and store the data from the terminal. </p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;bits/stdc++.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">int</span> n;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; arr;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; n;
  arr.resize(n);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &amp;e : arr) <span class="hljs-built_in">cin</span> &gt;&gt; e;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-define-sum-procedure">Define <code>sum()</code> Procedure</h3>
<p>As you can see from the code cell below, this method is very simple, we simply iterate the array using a for loop, starting from <strong>a</strong> to <strong>b-1</strong>, notice how we don't have to subtract 1 to <strong>b</strong> because we use "&lt;" instead of "&lt;=", and sum all the values to the <code>result</code> variable.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">sum</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
  <span class="hljs-keyword">int</span> result = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = a; i &lt; b; i++) result += arr[i];
  <span class="hljs-keyword">return</span> result;
}
</code></pre>
<h3 id="heading-define-update-procedure">Define <code>update()</code> Procedure</h3>
<p>This function is the easiest to implement because we only need the following line of code:</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> index, <span class="hljs-keyword">int</span> new_value)</span> </span>{ arr[index] = new_value; }
</code></pre>
<p>The <code>Update</code> method does not return anything, that's why we use <code>void()</code>, and we don't need to pass the array as a parameter because it's defined globally. </p>
<h3 id="heading-testing-solution">Testing Solution</h3>
<p>Feel free to copy the code locally on your machine and test it out!</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-built_in">cin</span> &gt;&gt; n;
  arr.resize(n);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &amp;e : arr) <span class="hljs-built_in">cin</span> &gt;&gt; e;

  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">7</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  update(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>);
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">7</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Expected output:</p>
<pre><code><span class="hljs-number">29</span> <span class="hljs-number">5</span> <span class="hljs-number">20</span> <span class="hljs-number">34</span> <span class="hljs-number">10</span> <span class="hljs-number">20</span>
</code></pre><h3 id="heading-time-space-complexity">Time - Space Complexity</h3>
<p>After coding the iterative solution, you must be thinking: "Hey!, this was easy to code, why don't we just use this approach?", and yes! that solution is simple and easy, but is it efficient? for example what happens if you have the following limits?:</p>
<ul>
<li>(1≤N≤10^5, 1≤M≤10^5) where N is the number of elements, and M is the number of operations that are going to be performed. </li>
</ul>
<h4 id="heading-update-time-complexity"><code>Update()</code> Time Complexity</h4>
<p>Surprisingly, the <code>update</code> procedure takes <code>O(1)</code> constant time, which means it's super efficient! </p>
<h4 id="heading-sum-time-complexity"><code>Sum()</code> Time Complexity</h4>
<p>However, this procedure has a worst-case scenario of <code>O(N)</code> this is the case if we ask for a range from 0 to N, the problem is that there can be up to 10^5 of this type of function calls</p>
<pre><code class="lang-cpp">sum(<span class="hljs-number">0</span>, <span class="hljs-number">1E5</span>)
sum(<span class="hljs-number">0</span>, <span class="hljs-number">1E5</span>)
sum(<span class="hljs-number">0</span>, <span class="hljs-number">1E5</span>)
sum(<span class="hljs-number">0</span>, <span class="hljs-number">1E5</span>)
sum(<span class="hljs-number">0</span>, <span class="hljs-number">1E5</span>)
... <span class="hljs-number">10</span>^<span class="hljs-number">5</span> more times
</code></pre>
<p>and for every call, we have to iterate the entire array even tho the array stays the same. Because of this, this procedure has a complexity of <code>O(N*M)</code> and because in this case N and M can be the same worst-case value, we say that this solution has a complexity of <code>O(N²)</code> which is not efficient at all!</p>
<h2 id="heading-segment-tree-solution">Segment Tree Solution</h2>
<h3 id="heading-structure-of-the-segment-tree">Structure of the segment tree</h3>
<p>Starting from the previous example array, let's see what a segment tree would look like for this particular array.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663274740602/w435il_UH.png" alt="Slide 16_9 - 1.png" /></p>
<p>This is a binary tree, in the leaves of which there are elements of the original array, and each internal node contains the sum of the numbers in its children.</p>
<p>notice how we added a 0 at the end of the original array because we need to create a Binary Tree, and for the tree to be created perfectly we need the length of the array to be a power of two. If the length of the array is not a power of two, you can extend the array with a neutral value, in this case, a 0, notice how the length of the array will increase no more than twice, so the asymptotic time complexity of the operations will not change.</p>
<p>Now let's see how the operations will look on this tree.</p>
<h3 id="heading-update-operation"><code>Update()</code> Operation</h3>
<p>When an element of the array changes, what we need to do is traverse the tree until we reach the corresponding leave of the tree, then update the value, and recalculate all the values higher up the tree from the modified leaf. When performing such an operation, we need to recalculate one node on each layer of the tree.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663358982769/eWvRqg_uG.gif" alt="Seg_Tree_update.gif" /></p>
<p>In the animation shown above, you can see the <code>Update(i, v)</code> in action.</p>
<h3 id="heading-sum-operation"><code>Sum()</code> Operation</h3>
<p>Now let's see what the <code>Sum()</code> operation would look like on our segment tree. Notice how we already have all the values that we need to be stored in the nodes of our tree. In this case, the values are the sum of the segments in the original array.
Observe how the root already has the answer for a query from 0 to 8 which would be a perfect query, however, what happens if we have a nonperfect query like [2, 7)?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663450783222/ZMNVW53q8.gif" alt="Seg_Tree_sum.gif" /></p>
<p>The algorithm will be a recursive traversal of the tree that will be interrupted by two cases.</p>
<ul>
<li>The segment corresponding to the current node is outside of the query, if this happens it means that all the children are outside of the desired query and we can stop the recursion.</li>
<li>The segment corresponding to the current node is completely inside of the query, this means that all the children are inside of the range and we need to sum the value of the current node to our result and stop the recursion. </li>
</ul>
<p>If the current node segment is partially inside the range query, then we simply continue traversing its children until one of both break cases happens. </p>
<h3 id="heading-time-space-complexity">Time - Space Complexity</h3>
<p>Altho we haven't touched any of the code for this solution, you might already be thinking about if this solution is actually better than the iterative one, after all, it seems like there are a lot of more elements in our structure, and in the sum operation example, it might seem like there was more traversing and was slower than the other one, but is this really the case?</p>
<h4 id="heading-segment-tree-space-complexity">Segment Tree Space Complexity</h4>
<p>if the array size <strong>N</strong> is a power of 2, then we have exactly <strong>n-1</strong> internal nodes, summing up to <strong>2n-1</strong> total nodes. But not always do we have n as the power of 2, so we basically need the smallest power of 2 which is greater than n. For good measure, it's normally said that a Segment Tree has a space complexity of <code>O(4n)</code> which is manageable. If you want to dig a bit more about this topic I'll recommend you to check out this <a target="_blank" href="https://codeforces.com/blog/entry/49939">link</a></p>
<h4 id="heading-update-time-complexity"><code>Update()</code> Time Complexity</h4>
<p>When performing the update operation, we need to recalculate one node on each layer of the tree. We have only <code>logn</code> layers, so the operation time will be <code>O(logn)</code>.</p>
<h4 id="heading-sum-time-complexity"><code>Sum()</code> Time Complexity</h4>
<p>When performing the <code>Sum()</code> operation, we don't need to visit all the elements of the tree, thus the general asymptotic time of this procedure will be <code>O(logn)</code>, way more efficient compared to the iterative solution.</p>
<h2 id="heading-when-to-use-a-segment-tree">When to use a segment tree?</h2>
<p>Segment Trees are useful whenever you're frequently working with ranges of numerical data. We can use a segment tree if the function <em>f</em> is associative and the answer of an interval [l,r] can be derived from the data array.
Here are some common examples:</p>
<ul>
<li>Find the sum of all values in a range</li>
<li>Find the smallest value in a range</li>
<li>Find the Max value in a rage</li>
<li>Find the Product of all values in a Range (Multiplication)</li>
<li>Bitwise operations <strong><code>|</code></strong> <strong><code>&amp;</code></strong> <strong><code>^</code></strong></li>
</ul>
<h2 id="heading-implementing-a-segment-tree-with-c">Implementing a Segment Tree with C++</h2>
<p>In this section, we will look at how to implement the solution for the original sum problem using a genius Segment tree Array representation starting from the code template below.</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n;
  <span class="hljs-built_in">cin</span> &gt;&gt; n;
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">arr</span><span class="hljs-params">(n)</span></span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &amp;e : arr) <span class="hljs-built_in">cin</span> &gt;&gt; e;

  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<h3 id="heading-step-1-initializing-segment-tree">Step 1 - Initializing Segment Tree</h3>
<p>As you can see from the code cell below, we initialize two global variables, the segment tree size, and the base size.</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">int</span> seg_tree_size, base_size;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span>&gt; segment_tree;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663541784624/7_EsyTFgY.png" alt="base and tree size.png" /></p>
<p>We also create our segment_tree that, as we mentioned earlier, it's going to be represented with an array, in this case, <strong>long long</strong> is the data type we use because we are going to be managing sums.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(<span class="hljs-keyword">const</span> <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&amp; a)</span> </span>{
  <span class="hljs-keyword">int</span> arr_size = a.size();
  base_size = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">while</span> (base_size &lt; arr_size) base_size *= <span class="hljs-number">2</span>;
  seg_tree_size = base_size * <span class="hljs-number">2</span> - <span class="hljs-number">1</span>;
  segment_tree.resize(seg_tree_size, <span class="hljs-number">0</span>);  <span class="hljs-comment">// neutral value;</span>
</code></pre>
<p>In the code cell above, you can see how we use a while loop, to find the smallest power of 2 which is greater than n in order to have a perfect binary tree. Now it's time to fill the tree leaves with the values of the original array.</p>
<pre><code class="lang-cpp">  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = seg_tree_size / <span class="hljs-number">2</span>, j = <span class="hljs-number">0</span>; i &lt; seg_tree_size &amp;&amp; j &lt; arr_size;
       i++, j++) {
    segment_tree[i] = a[j];
  }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663546072300/ZFWJ39rvQ.gif" alt="Seg_Tree_Fill_Leaves.gif" />
Notice how we are representing the Tree as an array where each node has its index, and the furthest left leaf is always going to be the segment tree size divided by two. </p>
<p>Now that we filled all the leaves it's time to fill the rest of the tree</p>
<pre><code class="lang-cpp">  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = seg_tree_size / <span class="hljs-number">2</span> - <span class="hljs-number">1</span>; i &gt;= <span class="hljs-number">0</span>; i--) {
    segment_tree[i] = segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>] + segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>];
  }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663547696335/mixGVvyj0.gif" alt="Seg_Tree_Fill_Rest.gif" /></p>
<p>Notice how we start from the element in the <code>(seg_tree_size / 2 - 1)</code> position in this case the node at index 6,  and thanks to the perfect binary tree that we have, we can easily check for both of its children with <code>i * 2 + 1</code> and <code>i * 2 + 2</code>, In this particular case, we are making the node value to be the sum of both its children, this is normally what is adjusted for other associative properties.</p>
<h3 id="heading-define-update-procedure">Define <code>update()</code> Procedure</h3>
<p>In case you forgot, this function is going to receive an index and a value, and update our array in the index to the new value. Thanks to our Array representation method we don't have to traverse the tree until we reach the desired node, instead, we just directly access the element with <code>i += st_size / 2</code></p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> v)</span> </span>{
  i += seg_tree_size / <span class="hljs-number">2</span>;
  segment_tree[i] = v;
  <span class="hljs-keyword">while</span> (i &gt; <span class="hljs-number">0</span>) {
    i = (i - <span class="hljs-number">1</span>) / <span class="hljs-number">2</span>;
    segment_tree[i] = segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>] + segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>];
  }
}
</code></pre>
<p>Remember that once the value is updated, all the parent nodes to that leave have to be updated. </p>
<h3 id="heading-define-sum-procedure">Define <code>sum()</code> Procedure</h3>
<p>This recursive function shall take the query that is, [L and R), a helper left and right "searching" range and the index to the current node in the tree.</p>
<pre><code class="lang-cpp"><span class="hljs-function"><span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> <span class="hljs-title">sum</span><span class="hljs-params">(<span class="hljs-keyword">int</span> L, <span class="hljs-keyword">int</span> R, <span class="hljs-keyword">int</span> sl = <span class="hljs-number">0</span>, <span class="hljs-keyword">int</span> sr = base_size, <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>)</span> </span>{
  <span class="hljs-keyword">if</span> (sl &gt;= R || sr &lt;= L) <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;                <span class="hljs-comment">// Outside of range</span>
  <span class="hljs-keyword">if</span> (sl &gt;= L &amp;&amp; sr &lt;= R) <span class="hljs-keyword">return</span> segment_tree[i];  <span class="hljs-comment">// Inside of range</span>
  <span class="hljs-keyword">int</span> mid = (sl + sr) / <span class="hljs-number">2</span>;
  <span class="hljs-keyword">return</span> sum(L, R, sl, mid, i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>) + sum(L, R, mid, sr, i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>);
}
</code></pre>
<p>Let's see what is happening here, in the first iteration we try to "search" the entire array, that's why <code>sl</code> is set to 0, and <code>sr</code> is set to the <code>base_size</code>, and we start on the root node, a.k.a the node at index 0.</p>
<p>The function will check if the searching range is outside of the query, if it is, we return 0, if instead, the searching range is completely inside of the query, we return the value of the segment tree node, else, it means that we are partially inside of the query, and because this is a binary tree, we can simply trim the search range in 2 with <code>int mid = (sl + sr) / 2;</code> and send the recursive function again to BOTH children.</p>
<h3 id="heading-testing-solution-full-code">Testing Solution + Full Code</h3>
<pre><code class="lang-cpp"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">int</span> seg_tree_size, base_size;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span>&gt; segment_tree;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(<span class="hljs-keyword">const</span> <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt;&amp; a)</span> </span>{
  <span class="hljs-keyword">int</span> arr_size = a.size();
  base_size = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">while</span> (base_size &lt; arr_size) base_size *= <span class="hljs-number">2</span>;
  seg_tree_size = base_size * <span class="hljs-number">2</span> - <span class="hljs-number">1</span>;
  segment_tree.resize(seg_tree_size, <span class="hljs-number">0</span>);  <span class="hljs-comment">// valor neutro;</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = seg_tree_size / <span class="hljs-number">2</span>, j = <span class="hljs-number">0</span>; i &lt; seg_tree_size &amp;&amp; j &lt; arr_size;
       i++, j++) {
    segment_tree[i] = a[j];
  }
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = seg_tree_size / <span class="hljs-number">2</span> - <span class="hljs-number">1</span>; i &gt;= <span class="hljs-number">0</span>; i--) {
    segment_tree[i] = segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>] + segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>];
  }
}

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i, <span class="hljs-keyword">int</span> v)</span> </span>{
  i += seg_tree_size / <span class="hljs-number">2</span>;
  segment_tree[i] = v;
  <span class="hljs-keyword">while</span> (i &gt; <span class="hljs-number">0</span>) {
    i = (i - <span class="hljs-number">1</span>) / <span class="hljs-number">2</span>;
    segment_tree[i] = segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>] + segment_tree[i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>];
  }
}

<span class="hljs-function"><span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span> <span class="hljs-title">sum</span><span class="hljs-params">(<span class="hljs-keyword">int</span> L, <span class="hljs-keyword">int</span> R, <span class="hljs-keyword">int</span> sl = <span class="hljs-number">0</span>, <span class="hljs-keyword">int</span> sr = base_size, <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>)</span> </span>{
  <span class="hljs-keyword">if</span> (sl &gt;= R || sr &lt;= L) <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;                <span class="hljs-comment">// Outside of range</span>
  <span class="hljs-keyword">if</span> (sl &gt;= L &amp;&amp; sr &lt;= R) <span class="hljs-keyword">return</span> segment_tree[i];  <span class="hljs-comment">// Inside of range</span>
  <span class="hljs-keyword">int</span> mid = (sl + sr) / <span class="hljs-number">2</span>;
  <span class="hljs-keyword">return</span> sum(L, R, sl, mid, i * <span class="hljs-number">2</span> + <span class="hljs-number">1</span>) + sum(L, R, mid, sr, i * <span class="hljs-number">2</span> + <span class="hljs-number">2</span>);
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">int</span> n;
  <span class="hljs-built_in">cin</span> &gt;&gt; n;
  <span class="hljs-function"><span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">arr</span><span class="hljs-params">(n)</span></span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span>&amp; e : arr) <span class="hljs-built_in">cin</span> &gt;&gt; e;
  init(arr);  <span class="hljs-comment">// &lt;- DON'T FORGET TO CREATE THE SEGMENT TREE!</span>
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">7</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  update(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>);
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">7</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-built_in">cout</span> &lt;&lt; sum(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Expected output:</p>
<pre><code><span class="hljs-number">29</span> <span class="hljs-number">5</span> <span class="hljs-number">20</span> <span class="hljs-number">34</span> <span class="hljs-number">10</span> <span class="hljs-number">20</span>
</code></pre><h2 id="heading-farewell-conclusion">Farewell - Conclusion</h2>
<p>You've reached the end of this lesson on the Segment tree data structure, remember that this is a skill that takes a lifetime to master so don't feel frustrated if you don't get it right away because this isn't easy, but I really hope some of the guidelines we saw today were helpful and the basic foundations on this topic were well understood, remember, there is still a lot to learn and we definitively didn't cover everything on Segment Trees, but I hope this was a good beginner overview and that you grasped the concepts and feel more confident on your programming journey.</p>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. See you in the next post, stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Stacks and Queues a Beginners Overview]]></title><description><![CDATA[Introduction
Hello everyone, welcome back!, today I wanted to give a beginners overview of stacks and queues in Python, we will take a good look at what are they? what are they for? and we will look through some examples together.
What is a stack?
Th...]]></description><link>https://blog.garybricks.com/stacks-and-queues-a-beginners-overview</link><guid isPermaLink="true">https://blog.garybricks.com/stacks-and-queues-a-beginners-overview</guid><category><![CDATA[python beginner]]></category><category><![CDATA[data structures]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[algorithms]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Tue, 06 Sep 2022 17:53:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662486624285/o54o-sMSp.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, welcome back!, today I wanted to give a beginners overview of stacks and queues in Python, we will take a good look at what are they? what are they for? and we will look through some examples together.</p>
<h2 id="heading-what-is-a-stack">What is a stack?</h2>
<p>The first time I ever heard about stacks, I couldn't help but imagine a stack of Legos or a stack of boxes, and in programming, a stack is a linear list-based data structure that behaves very similar to a stack of boxes in real life.</p>
<p>The main idea is that you can keep putting elements on top, and you have easy quick access to remove or look at the top element. And just like a stack of boxes in real life, if you want access to the bottom element you can't get to it easily, you will need to take the top box over and over again until you reach the box that you want.</p>
<blockquote>
<p>In computer science, a stack is an abstract data type that serves as a collection of elements, with two main principal operations:</p>
<ul>
<li>Push, which adds an element to the collection, and</li>
<li><p>Pop, which removes the most recently added element that was not yet removed.</p>
<p>https://en.wikipedia.org/wiki/Stack_(abstract_data_type)</p>
</li>
</ul>
</blockquote>
<h2 id="heading-pros-of-using-stacks">Pros of using stacks</h2>
<p>Stacks can be extremely useful and efficient when you only care about the most recent elements or the order in which you see and save elements matters.</p>
<p>For example, if you made a news page, you'll need to access the more recent elements first and more quickly but you may want to show all of the elements when the user scrolls down.</p>
<p>When talking about stacks, it's important to know some specific terminology. When you add an element to a stack, the operation is called "Push" instead of "Insert", and when you take out an element off the stack the operation is called "Pop" instead of "remove", and remember that we always push and pop at the top of the stack. L.I.F.O(Last In, First Out) as the image below illustrates.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1648791137216/AK-bJxBqC.jpg" alt="stack_illustration.jpg" /></p>
<p>Hopefully, you can see that because all you need to do is work with the top of the stack, both operations should take constant time O(1) which can be a really good reason to implement a stack. </p>
<h2 id="heading-implementing-a-stack">Implementing a Stack</h2>
<p>Because a stack it's a pretty abstract concept you can actually implement it in two different ways, with an array, or with a Linked list.</p>
<h3 id="heading-implementing-a-stack-using-an-array">Implementing a Stack using an array</h3>
<p>A stack has some things in common with an array in the sense that we have a collection of elements and an order to them. One difference with an array is that if we wanted, we could actually access an element in the middle of the array or at the beginning of the array which wouldn't actually be a Stack. Remember that with a stack, we can only access one end, the top. </p>
<p>So how do we implement a stack using an array? well, one way we could look at it is if we rotate an array sideways, we could use it as the container for the stack, then, we could restrict the ways we can interact with this container so that we get the behavior we expect from a Stack, in practical terms, we are going to create a Stack class that has a <code>push</code> and <code>pop</code> methods.</p>
<h3 id="heading-step-1-create-the-stack-class">Step 1 - Create the Stack class</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span> <span class="hljs-comment"># defining stack</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span> <span class="hljs-comment"># initializing list</span>
        self.items = []

myStack = Stack() <span class="hljs-comment"># creating stack</span>
</code></pre>
<p>From the code above you can see our <code>Stack</code> class and in the <code>__init__</code> method we initialize our list that will contain all the items of our stack.</p>
<h3 id="heading-step-2-create-the-push-method">Step 2 - Create the <code>push</code> method</h3>
<p>The behavior of this method is very straightforward, simply push a new element into the top of the stack. Python makes this task especially easy thanks to the built-in <code>append</code> method that adds a new element to the end of a list which in this case it's going to be considered the head of our stack. The <code>append</code> method also takes care of the size of the array, so we won't ever have a stack overflow problem. </p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span> <span class="hljs-comment"># defining stack</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span> <span class="hljs-comment"># initializing list</span>
        self.items = []
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, element</span>):</span> <span class="hljs-comment"># push method</span>
        self.items.append(element) <span class="hljs-comment"># append method to add an element to the end of the list.</span>

myStack = Stack() <span class="hljs-comment"># creating stack</span>
print(myStack.items) <span class="hljs-comment"># [ ]</span>
myStack.push(<span class="hljs-string">"element1"</span>)
print(myStack.items) <span class="hljs-comment"># ["element1"]</span>
myStack.push(<span class="hljs-string">"element 2"</span>) 
print(myStack.items) <span class="hljs-comment"># ["element1", "element2"] # the head will be considered the end of the list</span>
</code></pre>
<p>If you wish to print the stack to get a better understanding of what the stack looks like, you can use <code>print(myStack.items)</code>.</p>
<h3 id="heading-step-3-create-the-pop-method">Step 3 - Create the <code>pop</code> method</h3>
<p>As we mentioned earlier, the purpose of this method is to remove the element at the top of the stack, in this case, the last element of the list. Just as we used the <code>append</code> method for adding elements to our stack, python provides us with a built-in <code>pop</code> method that removes the last element of an array, precisely what we need.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, element</span>):</span>
        self.items.append(element)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        self.items.pop()

myStack = Stack() <span class="hljs-comment"># creating stack</span>
print(myStack.items) <span class="hljs-comment"># [ ]</span>
myStack.push(<span class="hljs-string">"element1"</span>) 
print(myStack.items) <span class="hljs-comment"># ["element1"]</span>
myStack.push(<span class="hljs-string">"element2"</span>) 
print(myStack.items) <span class="hljs-comment"># ["element1", "element2"]</span>
myStack.pop()
print(myStack.items) <span class="hljs-comment"># ["element1"]</span>
myStack.pop()
print(myStack.items) <span class="hljs-comment"># []</span>
myStack.pop() <span class="hljs-comment"># IndexError: pop from empty list</span>
print(myStack.items)
</code></pre>
<p>The pop method takes no arguments, we only pass the <code>self</code> attribute and using <code>self.items.pop()</code> we can easily achieve the desired behavior, but there's a problem, If we call the pop method on an empty array, we are going to get the following error:</p>
<blockquote>
<p>IndexError: pop from empty list.</p>
</blockquote>
<p>To prevent this error from happening, we are going to check the size of the array first, and if it's not empty, run the <code>pop</code> method like we already have. To check the size of the array we can use the built-in <code>len()</code> method.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, element</span>):</span>
        self.items.append(element)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> len(self.items) &gt; <span class="hljs-number">0</span>:  <span class="hljs-comment"># checking if not empty</span>
            self.items.pop()


myStack = Stack()  <span class="hljs-comment"># creating stack</span>
print(myStack.items)  <span class="hljs-comment"># [ ]</span>
myStack.push(<span class="hljs-string">"element1"</span>)
print(myStack.items)  <span class="hljs-comment"># ["element1"]</span>
myStack.push(<span class="hljs-string">"element2"</span>)
print(myStack.items)  <span class="hljs-comment"># ["element1", "element2"]</span>
myStack.pop()
print(myStack.items)  <span class="hljs-comment"># ["element1"]</span>
myStack.pop()
print(myStack.items)  <span class="hljs-comment"># []</span>
myStack.pop()
print(myStack.items)  <span class="hljs-comment"># []</span>
</code></pre>
<p>Lastly, we want our pop() method to return the "popped" element and we are done!</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>  <span class="hljs-comment"># initializing stack</span>
        self.items = []

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, element</span>):</span>
        self.items.append(element)  <span class="hljs-comment"># adding new element</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> len(self.items) &gt; <span class="hljs-number">0</span>:  <span class="hljs-comment"># checking if not empty</span>
            <span class="hljs-keyword">return</span> self.items.pop()  <span class="hljs-comment"># removing and returning the head</span>


myStack = Stack()  <span class="hljs-comment"># creating stack</span>
print(myStack.items)  <span class="hljs-comment"># []</span>
myStack.push(<span class="hljs-string">"element1"</span>)
print(myStack.items)  <span class="hljs-comment"># ["element1"]</span>
myStack.push(<span class="hljs-string">"element2"</span>)
print(myStack.items)  <span class="hljs-comment"># ["element1", "element2"]</span>
print(myStack.pop())  <span class="hljs-comment"># element2</span>
print(myStack.pop())  <span class="hljs-comment"># element1</span>
print(myStack.pop())  <span class="hljs-comment"># None</span>
</code></pre>
<h3 id="heading-implementing-a-stack-using-a-linked-list">Implementing a Stack using a linked list</h3>
<p>Previously, we looked at how to implement a stack using an array. While that approach works great in python because the append and pop method takes O(1) constant time, in other languages where there is no such efficiency when working with arrays it might be a good idea to implement a stack using a linked list.</p>
<p>If this is the first time you've heard about a linked list, check out my post titled <a target="_blank" href="https://blog.garybricks.com/a-beginners-overview-of-linked-lists-in-python">A Beginners Overview of Linked Lists in Python</a> where I explain what they are, what they are used for, and how to implement one using python. After you've read that article come back and continue from here.</p>
<h3 id="heading-step-1-create-the-stack-class">Step 1 - Create the Stack class</h3>
<p>As you can see from the code below, we initialize our Stack class with the <code>__init__</code> method, and we add two attributes: the <code>head</code> which by default it's going to be None since there are no elements in our linked list yet, and we set the <code>num_elements</code> variable to zero for the same reason.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>
        self.num_elements = <span class="hljs-number">0</span>
</code></pre>
<h3 id="heading-step-2-create-a-node-class">Step 2 - Create a Node class</h3>
<p>Because we are going to be implementing a linked list we are going to need a <code>Node</code> class that it's going to be an "element" with a value property and a pointer to the next node in the linked list.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656530276990/Q39EEcqiX.jpg" alt="linked_list.jpg" /></p>
<h3 id="heading-step-3-add-push-method">Step 3 - Add <code>Push</code> Method</h3>
<p>Next, we will be adding the <code>push</code> method to the Stack class. As we mentioned earlier, the purpose of this method is to remove the element at the top of the stack, in this case, the top of the stack is going to be the <strong>head </strong>of the linked list.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>  <span class="hljs-comment"># No items in the stack, so head should be None</span>
        self.num_elements = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        new_node = Node(value)
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = new_node
        <span class="hljs-keyword">else</span>:
            new_node.next = self.head
            self.head = new_node
        self.num_elements += <span class="hljs-number">1</span>
</code></pre>
<p>From the code above, you can see that once the push method is called, we create a new element "Node" with the value passed and we check if the linked list is empty with <code>if self.head is None:</code> if that is the case, we make the head equal to the newly created node. If not, that means that the linked list is not empty, and the <code>next</code> node is now the old head, and the new head will be the <code>new_node</code>, lastly, we increment the number of elements by 1.</p>
<h3 id="heading-step-4-add-pop-method">Step 4 - Add <code>Pop</code> Method</h3>
<p>First, this method needs to check if the stack is empty, then get the value of the head, which is the top of the stack, and store it in a local variable, then change the head to the next node, and in doing so, removing the top of the stack, finally subtract 1 to the number of elements variable in the stack and return the "popped" value.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>
        self.num_elements = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        new_node = Node(value)
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = new_node
        <span class="hljs-keyword">else</span>:
            new_node.next = self.head
            self.head = new_node
        self.num_elements += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.num_elements == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>
        <span class="hljs-keyword">else</span>:
            value = self.head.value
            self.head = self.head.next
            self.num_elements -= <span class="hljs-number">1</span>
            <span class="hljs-keyword">return</span> value
</code></pre>
<p>We are done! now it's time to test it out and see if it works as expected</p>
<pre><code class="lang-python">myStack = Stack()
myStack.push(<span class="hljs-string">"e1"</span>)
myStack.push(<span class="hljs-string">"e2"</span>)
myStack.push(<span class="hljs-string">"e3"</span>)
myStack.push(<span class="hljs-string">"e4"</span>)
print(myStack.num_elements)  <span class="hljs-comment"># 4</span>
print(myStack.pop())  <span class="hljs-comment"># e4</span>
print(myStack.num_elements)  <span class="hljs-comment"># 3</span>
print(myStack.pop())  <span class="hljs-comment"># e3</span>
</code></pre>
<h2 id="heading-stack-practice-parentheses-exercise">Stack Practice - Parentheses Exercise</h2>
<p>In this section, you are going to apply what you learned about stacks with a real-world problem. We will be using stacks to make sure the parentheses are balanced in mathematical expressions such as:  ((32+8)∗(5/2))/(2+6). </p>
<p>Take a string as an input and return True if its parentheses are balanced or False if it is not.</p>
<h3 id="heading-step-1-get-input-and-create-stack">Step 1 - Get input and Create Stack</h3>
<p>For this problem, you can choose to implement the stack with an array or a Linked list, it's completely up to you.</p>
<pre><code class="lang-python">myStack = Stack()
equation = input()
</code></pre>
<h3 id="heading-step-2-iterate-over-the-equation-string">Step 2 - Iterate over the equation string</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solve</span>(<span class="hljs-params">equation</span>):</span>
    <span class="hljs-keyword">for</span> char <span class="hljs-keyword">in</span> equation:
</code></pre>
<h3 id="heading-step-3-check-for-an-opening-parenthesis">Step 3 - Check for an opening parenthesis</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solve</span>(<span class="hljs-params">equation</span>):</span>
    <span class="hljs-keyword">for</span> char <span class="hljs-keyword">in</span> equation:
        <span class="hljs-keyword">if</span> char == <span class="hljs-string">"("</span>:
            myStack.push(char)
</code></pre>
<p>As you can see from the code above, if there is an opening parenthesis, we can add that character to the stack.</p>
<h3 id="heading-step-4-check-for-a-closing-parenthesis">Step 4 - Check for a closing parenthesis</h3>
<p>If we detect a closing character, we must check if the stack is empty, if it is, we will immediately know that the equation is unbalanced and if is not empty then we remove an element from the stack with the pop method.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solve</span>(<span class="hljs-params">equation</span>):</span>
    <span class="hljs-keyword">for</span> char <span class="hljs-keyword">in</span> equation:
        <span class="hljs-keyword">if</span> char == <span class="hljs-string">"("</span>:
            myStack.push(char)
        <span class="hljs-keyword">elif</span> char == <span class="hljs-string">")"</span>:
            <span class="hljs-keyword">if</span> myStack.num_elements &gt; <span class="hljs-number">0</span>:
                myStack.pop()
            <span class="hljs-keyword">else</span>:
                <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<h3 id="heading-step-5-check-for-leftovers">Step 5 - Check for leftovers</h3>
<p>At this point, if the program finishes iterating over the equation it means that the equation is balanced or that there are leftover elements in the stack if this is the case the equation is unbalanced.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solve</span>(<span class="hljs-params">equation</span>):</span>
    <span class="hljs-keyword">for</span> char <span class="hljs-keyword">in</span> equation:
        <span class="hljs-keyword">if</span> char == <span class="hljs-string">"("</span>:
            myStack.push(char)
        <span class="hljs-keyword">elif</span> char == <span class="hljs-string">")"</span>:
            <span class="hljs-keyword">if</span> myStack.num_elements &gt; <span class="hljs-number">0</span>:
                myStack.pop()
            <span class="hljs-keyword">else</span>:
                <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

    <span class="hljs-keyword">if</span> myStack.num_elements &gt; <span class="hljs-number">0</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>We are done! now it's time to test it out and see if it works as expected.</p>
<pre><code>((<span class="hljs-number">3</span><span class="hljs-operator">^</span><span class="hljs-number">2</span> <span class="hljs-operator">+</span> <span class="hljs-number">8</span>)<span class="hljs-operator">*</span>(<span class="hljs-number">5</span><span class="hljs-operator">/</span><span class="hljs-number">2</span>))<span class="hljs-operator">/</span>(<span class="hljs-number">2</span><span class="hljs-operator">+</span><span class="hljs-number">6</span>)) False
((<span class="hljs-number">3</span><span class="hljs-operator">^</span><span class="hljs-number">2</span> <span class="hljs-operator">+</span> <span class="hljs-number">8</span>)<span class="hljs-operator">*</span>(<span class="hljs-number">5</span><span class="hljs-operator">/</span><span class="hljs-number">2</span>))<span class="hljs-operator">/</span>(<span class="hljs-number">2</span><span class="hljs-operator">+</span><span class="hljs-number">6</span>)  True
</code></pre><h2 id="heading-what-is-a-queue">What is a Queue?</h2>
<p>Just like with Stacks, queues have a very descriptive name and behave very similar to a queue in real life, you can imagine a queue of people that are waiting to get their hands on the best ice cream in town. The way this works is that the person who is at the front of the queue is the first one to receive the ice cream and leave. People can always join at the back of the queue but can only receive the ice cream and leave at the front of the queue. This is called a First In, First out structure, remember that a Stack is a Last In, First out structure very similar but kind of the opposite.</p>
<p>When working with queues it's important to know some queue-related terminology like:</p>
<ul>
<li>Head - First (oldest) element added to the queue</li>
<li>Tail - Last (Newest) element added to the queue</li>
<li>Enqueue - add an element to the back/tail of the queue</li>
<li>Deque - A double-ended queue and pronounced "Deck"</li>
<li>Dequeue - Remove the element at the front of the queue</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1656974512885/7oqfru36G.jpg" alt="Queue2.jpg" /></p>
<p>In this section, we'll look at one way to implement a <code>Queue</code> with an array by creating a Stack class that has the following methods:</p>
<ul>
<li>Push() - inserts an element at the back/tail of the queue.</li>
<li>Pop() - removes an element from the front of the queue.</li>
<li>Front() - returns the first element/Head of the queue.</li>
<li>Back() - returns the tail of the queue.</li>
<li>Size() - returns the number of elements in the queue</li>
<li>Empty() - returns boolean <code>True</code> if the queue is empty.</li>
</ul>
<h2 id="heading-implement-a-queue-using-an-array">Implement a Queue using an Array</h2>
<h3 id="heading-step-1-create-the-queue-class">Step 1 - Create the <code>Queue</code> class</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []
        self.size = <span class="hljs-number">0</span>
</code></pre>
<p>As you can see from the code above, the initialization of our <code>Queue</code> class is basically the same as we did with the <code>Stack</code>, we have an items array and a variable to keep track of the size of the <code>Queue</code>.</p>
<h3 id="heading-step-2-add-the-push-method">Step 2 - Add the <code>push()</code> method</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []
        self.size = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        self.items.append(value)
        self.size += <span class="hljs-number">1</span>
</code></pre>
<p>The <code>push</code> method it's the same as the one with the Stack, we are going to handle the end of the array as the tail of the <code>Queue</code>, and with just 2 lines of code, we already added the Enqueue behavior. </p>
<h3 id="heading-step-3-add-the-pop-method">Step 3 - Add the <code>pop()</code> method</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.arr = []
        self.size = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        self.arr.append(value)
        self.size += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            self.items.pop(<span class="hljs-number">0</span>)
            self.size -= <span class="hljs-number">1</span>
</code></pre>
<p>The pop method may look very similar to the Stack method, BUT remember that the stack took out the last element of the array, and with a queue, we must take the first element of the array aka the front/head, that's why instead of doing <code>pop()</code> we do <code>pop(0)</code> where 0 it's the index of the array.</p>
<h3 id="heading-step-4-add-the-front-method">Step 4 - Add the <code>front()</code> method</h3>
<p>This method simply returns the element that's at the Front/Head of the Queue, this method should not remove the element.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []
        self.size = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        self.items.append(value)
        self.size += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            self.items.pop(<span class="hljs-number">0</span>)
            self.size -= <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">front</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.items[<span class="hljs-number">0</span>]
</code></pre>
<h3 id="heading-step-5-add-the-back-method">Step 5 - Add the <code>back()</code> method</h3>
<p>This method behaves very similarly to the <code>front()</code> method but instead of returning the front, this method should return the last element.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []
        self.size = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        self.items.append(value)
        self.size += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            self.items.pop(<span class="hljs-number">0</span>)
            self.size -= <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">front</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.items[<span class="hljs-number">0</span>]

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">back</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> self.items[self.size - <span class="hljs-number">1</span>] <span class="hljs-comment"># -1 because indexing starts at 0</span>
</code></pre>
<p>As you can see from the code above, the back method first checks that the Queue is not empty, this is important because if we don't check, we are going to get an index out of range error.</p>
<h3 id="heading-step-6-add-empty-method">Step 6 - add <code>empty()</code> method</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.items = []
        self.size = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        self.items.append(value)
        self.size += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            self.items.pop(<span class="hljs-number">0</span>)
            self.size -= <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">front</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.items[<span class="hljs-number">0</span>]

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">back</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> self.items[self.size - <span class="hljs-number">1</span>]

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">empty</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.size &gt; <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<h3 id="heading-testing-queue">Testing Queue</h3>
<pre><code class="lang-python">myQueue = Queue()
myQueue.push(<span class="hljs-number">1</span>)
myQueue.push(<span class="hljs-number">2</span>)
myQueue.push(<span class="hljs-number">3</span>)
myQueue.push(<span class="hljs-number">4</span>)
print(myQueue.items)
print(myQueue.size)
print(myQueue.front())
print(myQueue.back())
myQueue.pop()
myQueue.pop()
print(myQueue.items)
print(myQueue.size)
print(myQueue.front())
print(myQueue.back())
</code></pre>
<h2 id="heading-implement-a-queue-using-a-linked-list">Implement a Queue using a Linked List</h2>
<p>By now, you may be noticing a pattern. Earlier, we implemented a stack using an array and a linked list. Here, we're doing the same thing with queues.</p>
<h3 id="heading-step-1-create-the-queue-class">Step 1 - Create the <code>Queue</code> class</h3>
<p>in the cell below, you can see the Queue class initialization with the head and tail set to None and the num_elements variable set to cero. </p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>
        self.tail = <span class="hljs-literal">None</span>
        self.num_elements = <span class="hljs-number">0</span>
</code></pre>
<h3 id="heading-step-2-create-node-class">Step 2 - Create <code>Node</code> class</h3>
<p>This is exactly the same code we did previously. </p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>
</code></pre>
<h3 id="heading-step-3-add-the-push-method">Step 3 - Add the <code>push()</code> method</h3>
<p>In the method from the cell below, we create a new node with the passed value, and we check if the linked list is empty with <code>if self.head == None:</code>, if it is, we make the head of our linked list to be the newly created node, as well as the tail. if the linked list is not empty, we simply set the next node of the tail to the new node and we shift the tail to make sure it's always at the end. Lastly, we increment the number of elements in the linked list.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Queue</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>
        self.tail = <span class="hljs-literal">None</span>
        self.num_elements = <span class="hljs-number">0</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, value</span>):</span>
        new_node = Node(value)
        <span class="hljs-keyword">if</span> self.head == <span class="hljs-literal">None</span>:
            self.head = new_node
            self.tail = self.head
        <span class="hljs-keyword">else</span>:
            self.tail.next = new_node
            self.tail = self.tail.next
        self.num_elements += <span class="hljs-number">1</span>
</code></pre>
<h3 id="heading-step-4-add-the-pop-method">Step 4 - Add the <code>pop()</code> method</h3>
<p>The first step is to check if the linked list is not empty with <code>if self.num_elements &gt; 0:</code> and if so, we shift the head to the next node removing it from the list, lastly, we subtract 1 to the <code>num_elements</code> counter.</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.num_elements &gt; <span class="hljs-number">0</span>:
            self.head = self.head.next
            self.num_elements -= <span class="hljs-number">1</span>
</code></pre>
<h3 id="heading-step-5-add-the-front-method">Step 5 - Add the <code>front()</code> method.</h3>
<p>This method is very easy thanks to the way we keep track of the head on the linked list.</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">front</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.num_elements &gt; <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> self.head.value
</code></pre>
<h3 id="heading-step-6-add-the-back-method">Step 6 - Add the <code>back()</code> method.</h3>
<p>Likewise, creating this method is a breeze thanks to the tail attribute of the linked list.</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">back</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.num_elements &gt; <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> self.tail.value
</code></pre>
<h3 id="heading-step-7-add-the-size-method">Step 7 - Add the <code>size()</code> method</h3>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">size</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.num_elements
</code></pre>
<h3 id="heading-step-8-add-a-print-method">Step 8 - Add a <code>print()</code> method</h3>
<p>In the first method, we could simply print the array, but here, we need to traverse the linked list and print each of the elements' values. </p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_items</span>(<span class="hljs-params">self</span>):</span>
        current = self.head
        <span class="hljs-keyword">while</span> current:
            print(current.value, <span class="hljs-string">"=&gt;"</span>, end=<span class="hljs-string">" "</span>) <span class="hljs-comment"># prints in a single line</span>
            current = current.next
        print(<span class="hljs-string">""</span>)  <span class="hljs-comment"># just to add the end line at the end</span>
</code></pre>
<h3 id="heading-step-9-testing-queue">Step 9 - Testing Queue</h3>
<pre><code class="lang-python">myQueue = Queue()
myQueue.push(<span class="hljs-number">1</span>)
myQueue.push(<span class="hljs-number">2</span>)
myQueue.push(<span class="hljs-number">3</span>)
myQueue.push(<span class="hljs-number">4</span>)
myQueue.print_items()
print(myQueue.size())
print(myQueue.front())
print(myQueue.back())
myQueue.pop()
myQueue.pop()
myQueue.print_items()
print(myQueue.size())
print(myQueue.front())
print(myQueue.back())
</code></pre>
<p>Output:</p>
<pre><code><span class="hljs-number">1</span> <span class="hljs-string">=&gt;</span> <span class="hljs-number">2</span> <span class="hljs-string">=&gt;</span> <span class="hljs-number">3</span> <span class="hljs-string">=&gt;</span> <span class="hljs-number">4</span> <span class="hljs-string">=&gt;</span> 
<span class="hljs-number">4</span>
<span class="hljs-number">1</span>
<span class="hljs-number">4</span>
<span class="hljs-number">3</span> <span class="hljs-string">=&gt;</span> <span class="hljs-number">4</span> <span class="hljs-string">=&gt;</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
<span class="hljs-number">4</span>
</code></pre><h2 id="heading-conclution-farewell">Conclution - Farewell</h2>
<p>You've reached the end of this lesson on Stacks and Queues, I really hope you liked it and learned something new today, if you have any questions or suggestions, feel free to comment in the section below, remember, there is still a lot to learn and we definitively didn't cover everything on this topic, especially on the applications of the queue like in a BFS algorithm for example, but that's a topic for another day. See you in the next post, stay tuned! 👋</p>
]]></content:encoded></item><item><title><![CDATA[Efficiency and Big-O Notation Overview with Python Examples]]></title><description><![CDATA[Introduction
Hello everyone, welcome back! today, I wanted to talk about the importance of efficiency with data structure and algorithms and how to use Big-O notation to measure the Time and Space complexity of an algorithm.
Efficiency
In my last pos...]]></description><link>https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples</link><guid isPermaLink="true">https://blog.garybricks.com/efficiency-and-big-o-notation-overview-with-python-examples</guid><category><![CDATA[data structures]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[programmer]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Wed, 08 Dec 2021 21:53:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638645213436/NmAcGOfVU.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, welcome back! today, I wanted to talk about the importance of efficiency with data structure and algorithms and how to use Big-O notation to measure the Time and Space complexity of an algorithm.</p>
<h2 id="heading-efficiency">Efficiency</h2>
<p>In my last post, we talked about how to solve computational problems with python but we didn't dive into whether our solution was efficient or not. That's what we will be looking at in this section.</p>
<h3 id="heading-space-and-time">Space and Time</h3>
<p>When we refer to the efficiency of a program, we don't only look at the time it takes to run, but at the space required in the computer's memory as well. Often, there will be a trade-off between the two, where you can design a program that runs faster by selecting a data structure that takes up more space—or vice versa.</p>
<p>In order to quantify the time and space an algorithm takes, let's first understand what an algorithm is.</p>
<blockquote>
<h3 id="heading-algorithm">Algorithm</h3>
<p>An algorithm is a series of well-defined steps for solving a problem. Usually, an algorithm takes some kind of input (such as a list) and then produces the desired output (such as a reversed list).</p>
</blockquote>
<p>For any problem, there is likely more than one algorithm that can solve the problem, but there are some algorithms that are more efficient than others. However, computers are so fast! that in some problems, we can't tell the difference, so how can we know what algorithm is more efficient than another? and if we can't tell the difference, why try to make our code efficient?</p>
<p>Well, those are some great questions, and in some cases it's true, one version of a program may take 5 times longer than another, but they both still run so quickly that it has no real impact. However, in other cases, a very small change can make the difference between a program that takes milliseconds to run and a program that takes hours!.</p>
<h3 id="heading-quantifying-efficiency">Quantifying efficiency</h3>
<p>Sometimes, you will hear programmers say: </p>
<blockquote>
<p>"This algorithm is better than that algorithm"</p>
</blockquote>
<p>But how can we be more specific than that? How do we quantify efficiency?.</p>
<p>Let's take a look at some code examples.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add200</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>):
        n += <span class="hljs-number">100</span>
    <span class="hljs-keyword">return</span> n
</code></pre>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add200_2</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">100</span>):
        n += <span class="hljs-number">2</span>
    <span class="hljs-keyword">return</span> n
</code></pre>
<p>Both of the functions above have no real-world use, they are just dummy functions that will help us understand efficiency. Both of them add 200 to whatever the input(n) is. Take a good look at them and tell me, which one is more efficient?</p>
<p>The answer is the <code>add200</code> function. Why?</p>
<p>Although both functions output the exact same result, the <code>add200_2</code> function makes too many iterations, while the <code>add200()</code> function only iterates twice.</p>
<h3 id="heading-counting-lines">Counting Lines</h3>
<p>With the example above, what we basically did was to estimate which code had more lines to run, let's take a look again at both functions</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add200</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>):
        n += <span class="hljs-number">100</span>
    <span class="hljs-keyword">return</span> n

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add200_2</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">100</span>):
        n += <span class="hljs-number">2</span>
    <span class="hljs-keyword">return</span> n
</code></pre>
<p>The first function has a total of 4 lines but because of the for loop that gets called twice, there is a total of 5 lines (the for loop line doesn't get counted).</p>
<p>Now, let's take a look at the second function. the total of lines is 4 but the for loop gets called 100 times! so running this code will involve running 103 lines of code!.</p>
<p>Counting lines it's not a perfect way of quantifying the efficiency of a program but it's an easy way for us to <strong>approximate</strong> the difference in efficiency between two solutions.</p>
<h2 id="heading-input-size-and-how-it-affects-efficiency">Input Size and How it Affects Efficiency</h2>
<p>In both examples above, no matter what number we passed as an argument, the number of lines executed will remain the same.</p>
<p>Here's a new code example:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_to_num</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n+<span class="hljs-number">1</span>):  <span class="hljs-comment"># +1 because python counts from 0</span>
        print(i)

print_to_num(<span class="hljs-number">10</span>)
</code></pre>
<p>The code above prints all numbers from 0 to N, meaning the bigger the input N is, the number of lines executed will increase, and that means a longer time to run.</p>
<p>The highlighted idea it's that:</p>
<blockquote>
<p>As the input to an algorithm increases, the time required to run the algorithm <strong>may</strong> also increase.</p>
</blockquote>
<p>This <strong>may</strong> happen in some cases, in the last example it does increase the time, but in the first two, it does not.</p>
<h3 id="heading-rate-of-increase">Rate of increase</h3>
<p>Let's keep working with the last function and let's try several function calls examples to see the number of lines each one gets to run.</p>
<pre><code class="lang-python">print_to_num(<span class="hljs-number">2</span>) <span class="hljs-comment"># 4 lines</span>
print_to_num(<span class="hljs-number">3</span>) <span class="hljs-comment"># 5 lines</span>
print_to_num(<span class="hljs-number">4</span>) <span class="hljs-comment"># 6 lines</span>
print_to_num(<span class="hljs-number">5</span>) <span class="hljs-comment"># 7 lines</span>
</code></pre>
<p>As you can see, when N goes up by 1 the number of lines will also go up by 1. We can also say that the number of lines executed increases by a <strong>proportional</strong> amount. This type of relationship is called a <strong>Linear relationship</strong> if we graph the relationship we can see why it's called that.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638671544303/XljFaS3HL.png" alt="linear relationship.png" /></p>
<p>The x-axis represents the input size, in this case, a number, and the y-axis represents the number of operations that will be performed in this case we're thinking of an "operation" as a line of Python code which is not the most accurate but will do for now.</p>
<p>Let's take a look at another function example where the operations increase at a <strong>none</strong> constant rate.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_square</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):
        <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):
            print(<span class="hljs-string">"*"</span>, end=<span class="hljs-string">"  "</span>) <span class="hljs-comment"># end=" " for printing all "*" in a single line separated by two white spaces</span>
        print(<span class="hljs-string">""</span>) <span class="hljs-comment"># this is used to mimic an "enter"</span>

print_square(<span class="hljs-number">5</span>)
</code></pre>
<p>This code prints a square made out of "*" that it's exactly N x N in size</p>
<pre><code>output: 
<span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>
<span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>
<span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>
<span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>
<span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>  <span class="hljs-operator">*</span>
</code></pre><p>Notice that this function has a <strong>nested</strong> loop, that means, a loop inside a loop, and take a good look at the fact that both loops have a linear rate of increase but they are <strong>nested</strong> that makes the rate of increase <strong>quadratic</strong> that means that when the input goes up by a certain amount, the number of operations goes up by the <strong>square</strong> of that amount.</p>
<pre><code class="lang-python">print_square(<span class="hljs-number">1</span>) <span class="hljs-comment"># 1 line</span>
print_square(<span class="hljs-number">2</span>) <span class="hljs-comment"># 4 lines</span>
print_square(<span class="hljs-number">3</span>) <span class="hljs-comment"># 9 lines</span>
</code></pre>
<p>Let's add the quadratic rate of increase to our graph:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638676259964/k5dXdn98e.png" alt="quadratic relationship.png" /></p>
<p>Our <code>print_square</code> function exhibits a quadratic rate of increase which as you can see is a much faster rate of increase, this means that as we pass larger numbers, the number of operations the computer has to perform shoots up very quickly making the program far less efficient
These are only two examples of the rate of increase but there are many more. Here are the most common:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638728617558/fIxVdrg17.png" alt="complexity chart.png" /></p>
<p>Note. when people refer to the rate of increase, they will often use the term "order". For example, instead of saying: "This algorithm has a linear rate of increase" they will say: "The order of this algorithm is linear" </p>
<h2 id="heading-big-o-notation">Big-O notation</h2>
<h3 id="heading-what-is-it">What is it?</h3>
<p>Big-O notation is a "simplified analysis of an algorithm's efficiency". Big-O gives us an algorithm's complexity in terms of the input size (N) and it's independent of the machine we run the algorithms on. Big-O can give us the time but also space complexity of an algorithm</p>
<h3 id="heading-types-of-measurement">Types of Measurement</h3>
<p>There are three types of ways we can look at an algorithm's efficiency.</p>
<ol>
<li>Worst-case</li>
<li>Best-case</li>
<li>Average-case</li>
</ol>
<p>Normally, when talking about Big-O notation we will typically look at the worst-case scenario, this doesn't mean the others are not used, but normally we want to know what the worst case is.</p>
<h3 id="heading-general-rules-of-big-o">General Rules of Big-O</h3>
<ol>
<li><p>Big-O notation ignores constants. Example:
let's say you have a function that has a running time of O(5n), in this case, we say that it runs on the order of O(n) because as N gets larger, the 5 no longer matters.</p>
</li>
<li><p>Terms priority.
This means that if a function has a part that has an O(1) order but another part of that same function has an order of O(n) we will say that the whole function has an order of O(n). This includes sections that might not run, for example, in an if-else statement.</p>
</li>
</ol>
<p><code>O(1) &lt; O(logn) &lt; O(n) &lt; O(nlogn) &lt; O(n2) &lt; O(2n) &lt; O(n!)</code>
(see graph above)</p>
<h2 id="heading-code-examples">Code Examples</h2>
<p>In this section, we will take a look at example lines of code and see how O(n) is used.</p>
<h3 id="heading-constant-time-o1">Constant Time <code>O(1)</code></h3>
<p>Take a look at the line below</p>
<pre><code class="lang-python">print((<span class="hljs-number">5</span>*<span class="hljs-number">10</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment"># outputs 25</span>
</code></pre>
<p>As you can see, this code simply computes a simple math operation and it's not dependent on any input. This is an example of O(1) order or constant time.</p>
<p>What if we have not one but three simple math operations.</p>
<pre><code class="lang-python">n = <span class="hljs-number">5</span> + <span class="hljs-number">2</span> <span class="hljs-comment"># O(1)</span>
y = <span class="hljs-number">3</span> * <span class="hljs-number">5</span> <span class="hljs-comment"># O(1)</span>
x = n + y <span class="hljs-comment"># O(1)</span>
</code></pre>
<p>Well, in this case, each line of code has an O(1) order, so what we need to do is add all of them like this: <code>O(1)+O(1)+O(1)</code> BUT let's remember the first rule and ignore constants, making the final result be <code>O(1)</code></p>
<h3 id="heading-linear-time-on">Linear Time <code>O(n)</code></h3>
<p>Let's try another example:</p>
<pre><code class="lang-python"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n): <span class="hljs-comment"># n * O(1) = O(n)</span>
    print(i) <span class="hljs-comment"># O(1)</span>
</code></pre>
<p>The clearest example of Linear time code, it's a simple for loop that iterates from 0 to N. In the code shown above, the print statement has an order of <code>O(1)</code> but because it's inside a loop, we need to multiply <code>O(1) * N</code> which would give us a result of <code>O(N)</code></p>
<p>If, for example, we had both examples above together like this:</p>
<pre><code class="lang-python">n = <span class="hljs-number">5</span> + <span class="hljs-number">2</span> <span class="hljs-comment"># O(1)</span>
y = <span class="hljs-number">3</span> * <span class="hljs-number">5</span> <span class="hljs-comment"># O(1)</span>
x = n + y <span class="hljs-comment"># O(1)</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n): <span class="hljs-comment"># n * O(1) = O(n)</span>
    print(i) <span class="hljs-comment"># O(1)</span>
</code></pre>
<p>We would have the <code>O(1)</code> of the simple math and print lines, and <code>O(n)</code> of the for loop, so, to calculate the total time we need to add both of them BUT let's remember our second rule of terms priority and make <code>O(N)</code> the final result for this code</p>
<h3 id="heading-quadratic-time-on">Quadratic Time <code>O(n²)</code></h3>
<p>The easiest way to get a code to have a Quadratic order it's to simply have a nested loop with both of them iterating from 0 to N.
Let's see the code example that we saw earlier:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_square</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):
        <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):
            print(<span class="hljs-string">"*"</span>, end=<span class="hljs-string">"  "</span>) <span class="hljs-comment"># end=" " for printing all "*" in a single line separated by two white spaces</span>
        print(<span class="hljs-string">""</span>) <span class="hljs-comment"># this is used to mimic an "enter"</span>

print_square(<span class="hljs-number">5</span>)
</code></pre>
<p>The first for loop has a time complexity of <code>O(N)</code>, the second for loop also has a time complexity of <code>O(N)</code>, and finally, the print statements have a complexity of <code>O(1)</code>. And hopefully, you can see pretty clearly that the print statement will be executed <code>N * N</code> times,  making this whole code have a time complexity of <code>O(N²)</code></p>
<p>If, we put all previous codes together like this:</p>
<pre><code class="lang-python">n = <span class="hljs-number">5</span> + <span class="hljs-number">2</span> <span class="hljs-comment"># O(1)</span>
y = <span class="hljs-number">3</span> * <span class="hljs-number">5</span> <span class="hljs-comment"># O(1)</span>
x = n + y <span class="hljs-comment"># O(1)</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n): <span class="hljs-comment"># n * O(1) = O(n)</span>
    print(i) <span class="hljs-comment"># O(1)</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>): <span class="hljs-comment"># O(n) * O(n) = O(n²)</span>
    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):
        print(<span class="hljs-string">"*"</span>, end=<span class="hljs-string">"  "</span>)
    print(<span class="hljs-string">""</span>) <span class="hljs-comment"># this is used to mimic an "enter"</span>
</code></pre>
<p>we know the first code has a complexity of <code>O(1)</code> the second code has a complexity of <code>O(n)</code> and the third code has a complexity of <code>O(n²)</code> and because of our second rule, the complexity of the whole code it's <code>O(n²)</code> </p>
<h3 id="heading-logarithmic-time-olog-n">Logarithmic Time <code>O(log n)</code></h3>
<p>An algorithm with a Logarithmic run time, it's that code that reduces the size of the input data in each step (it doesn't need to look at all values of the input data), a great example of this, is a <strong>Binary Search</strong>.  Binary Search is a searching algorithm for finding an element's position in a sorted array.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">binary_search</span>(<span class="hljs-params">arr, element</span>):</span>
    left = <span class="hljs-number">0</span>
    right = len(arr)<span class="hljs-number">-1</span>
    <span class="hljs-keyword">while</span>(left &lt;= right):
        mid = (left + right)//<span class="hljs-number">2</span>
        <span class="hljs-keyword">if</span> arr[mid] == element:
            <span class="hljs-keyword">return</span> mid
        <span class="hljs-keyword">if</span> arr[mid] &lt; element:
            left = mid +<span class="hljs-number">1</span>
        <span class="hljs-keyword">else</span>:
            right = mid <span class="hljs-number">-1</span>
    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>

print(binary_search([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>], <span class="hljs-number">8</span>))
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663265143123/8j5iYIO5X.gif" alt="binary_search.gif" /></p>
<h3 id="heading-log-linear-time-on-log-n">Log-Linear Time <code>(O(n log n))</code></h3>
<p>An algorithm is said to have a log-linear time complexity when each operation in the input data has a <code>logarithm</code> time complexity. It is commonly seen in sorting algorithms</p>
<pre><code class="lang-python">codes = set()
<span class="hljs-keyword">for</span> phone <span class="hljs-keyword">in</span> phones_arr:
    codes.add(phone[:<span class="hljs-number">4</span>])
print(<span class="hljs-string">'\n'</span>.join(sorted(codes))) <span class="hljs-comment"># &lt;== O(n log n)</span>
</code></pre>
<p>The code above iterates through an array of phone numbers and adds the first four digits of each phone to a "codes" set(a set doesn't allow duplicates) and finally the code prints the codes but are sorted.</p>
<h3 id="heading-exponential-time-o2">Exponential Time <code>O(2ⁿ)</code></h3>
<p>Algorithms have an exponential time complexity when the growth doubles with each addition to the input data set. This kind of time complexity is usually seen in brute-force algorithms. </p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n &lt;= <span class="hljs-number">1</span>:
        <span class="hljs-keyword">return</span> n
    <span class="hljs-keyword">return</span> fibonacci(n<span class="hljs-number">-1</span>) + fibonacci(n<span class="hljs-number">-2</span>)

print(fibonacci(<span class="hljs-number">8</span>)) <span class="hljs-comment"># outputs 21</span>
</code></pre>
<p>A great example of an exponential time algorithm is the recursive calculation of Fibonacci numbers, the code above receives a number and prints the N number in the Fibonacci sequence:
<code>0, 1, 1, 2, 3, 5, 8, 13, 21</code></p>
<h3 id="heading-factorial-time">Factorial Time</h3>
<p>An algorithm where the operational execution complexity increases factorially with the increase in the input size. As you can see from the graph above, this is the most inefficient order that an algorithm can have.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">factorial</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n == <span class="hljs-number">1</span>:
        <span class="hljs-keyword">return</span> n
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> n * factorial(n<span class="hljs-number">-1</span>)

print(factorial(<span class="hljs-number">4</span>))
</code></pre>
<p>The function above receives a number and uses recursion to print the result of multiplying all numbers from 1 to N
<code>4*3*2*1 = 24</code></p>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>You've reached the end of this post on complexity and Big-O notation to quantify time efficiency, I really hope some of the concepts we saw today have helped you and hopefully you will be thinking not only about solving a problem but to think weather your code is efficient or not. If you liked this post, make sure to share it with another person that might find this interesting, and let me know in the comments your thoughts, suggestions, and what you will like to see next.</p>
<p>See you in the next post, stay tuned for more!</p>
]]></content:encoded></item><item><title><![CDATA[A Beginners Overview of Linked Lists in Python]]></title><description><![CDATA[Introduction
Hello everyone, welcome back!, today I wanted to give a beginners overview of Linked Lists, we will take a good look at what are they? what are they for? and we will look through some examples together.
What is a Linked List?
A linked li...]]></description><link>https://blog.garybricks.com/a-beginners-overview-of-linked-lists-in-python</link><guid isPermaLink="true">https://blog.garybricks.com/a-beginners-overview-of-linked-lists-in-python</guid><category><![CDATA[data structures]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[Competitive programming]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Tue, 07 Dec 2021 19:09:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1637607859343/44ZQ7xDEH.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, welcome back!, today I wanted to give a beginners overview of Linked Lists, we will take a good look at what are they? what are they for? and we will look through some examples together.</p>
<h2 id="heading-what-is-a-linked-list">What is a Linked List?</h2>
<p>A linked list is an extension of a list but it's definitely NOT an array. By definition a linked list is a:</p>
<blockquote>
<p>Dynamic data structure where each element (called a node) is made up of two items: the data and a reference (or pointer), which points to the next node. A linked list is a collection of nodes where each node is connected to the next node through a pointer.</p>
</blockquote>
<p>Here it's an image to give a better understanding of a linked list</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1637603328903/E1PjE0gz9.jpeg" alt="linked_vs_array.jpg" /></p>
<p>With a linked list, there are still some things that have order but there are no indices. Instead, a linked list is characterized by its <code>Links</code>. Each element has a notion of what the next element is since it's connected to it, but not necessarily how long the list is or where it is in the list.
An array's different. There is nothing in one element of the array that says "here's your next element" like a linked list would, instead an array knows what the next element is by what the next <code>index</code> is.</p>
<h2 id="heading-differences-between-an-array-and-a-linked-list">Differences between an array and a linked list</h2>
<p>Let's walk through the differences together.</p>
<h3 id="heading-array">Array</h3>
<ul>
<li>A data structure consisting of a collection of elements each identified by the array index.</li>
<li>Supports random access, the programmer can directly access an element in the array using an index</li>
<li>Elements are stored in contiguous memory locations</li>
<li>Programmer has to specify the size of the array when declaring the array</li>
<li>Elements are independent of each other</li>
</ul>
<h3 id="heading-linked-list">Linked list</h3>
<ul>
<li>A linear collection of data elements whose order is not given by their location in memory. </li>
<li>Supports sequential access, the programmer has to go sequentially through each element until reaching the searched element</li>
<li>Elements can be stored anywhere in memory</li>
<li>There is no need in specifying the length of the linked list</li>
<li>An element has to point to the next or previous element</li>
</ul>
<p>When talking about linked lists you will often hear "Node" instead of "Element"</p>
<h2 id="heading-why-linked-lists">Why linked lists?</h2>
<p>When I was studying linked lists I was already pretty familiar with arrays and felt pretty comfortable using them, and if you are a beginner you are probably feeling the same way and are wondering "Hey, arrays are easy to access, have a set length, the elements are independent of each other, why make my life harder with this new linked list stuff?", if you thought of that, congratulations! you are on your way to becoming a great programmer since you have to always ask yourself the why of things.</p>
<p>The answer to the question "Why use linked lists?" can be a complex one, but for now, the simple and short answer is Efficiency. Turns out, that adding or removing an element from a linked list is so much easier in comparison to an array. And I want to give a quick reminder that we are working with python here.</p>
<h2 id="heading-implementing-a-linked-list">Implementing a Linked List</h2>
<p>Let's learn more about linked lists while we work through some examples and start writing some code.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1637692001097/BF--Qq4bQ.jpeg" alt="implementing_basic_linked_list.jpg" /></p>
<p>Because of the definition we saw earlier, we are going to approach this, by creating a <code>Node</code>, a node it's going to have, two attributes, the value, and the <code>next</code> attribute that's going to be a pointer pointing to the next node. From the image above, we can see how each node points to the next one until the list it's finished and the last node points to <code>None</code>. this collection of nodes pointing to the next one is going to be the Linked List.</p>
<h3 id="heading-step-1-create-a-node-class-with-value-and-next-attributes">Step - 1 Create a Node class with value and next attributes</h3>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>
</code></pre>
<p>this node has a "value" property that can be passed as an argument, and a "next" attribute that points to the next <code>Node</code>, in this case, it's pointing to None by default.</p>
<h3 id="heading-step-2-creating-a-head-node">Step - 2 Creating a Head Node</h3>
<p>Using our newly created Node class, it's time to create our <code>Head</code>, the "Head" it's basically the first Node.</p>
<pre><code class="lang-python">head = Node(<span class="hljs-number">8</span>)
</code></pre>
<p>Creating a new Node with the value of 8 and saving it in a new head variable.</p>
<h3 id="heading-step-3-creating-second-node-and-linking-it">Step - 3 Creating Second Node and Linking it</h3>
<p>Like we saw in the previous step, to create a new Node simply code <code>Node(value)</code>, and to link it to the head what we need to code is:</p>
<pre><code class="lang-python">head.next = Node(<span class="hljs-number">4</span>)
</code></pre>
<p>In the code above, <code>head.next</code> had the value of None, but now we are replacing that with a new Node with the value of 4.</p>
<h3 id="heading-step-4-printing-out-the-values">Step - 4 Printing Out The Values</h3>
<p>Right now, we have a linked list that has a Head with the value of 8 then the next node with the value of 4 like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1637694869025/9bhT0bd7B.png" alt="linked_list_progress1.png" /></p>
<p>Here's our progress:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>

head = Node(<span class="hljs-number">2</span>)
head.next = Node(<span class="hljs-number">1</span>)
</code></pre>
<p>To print out the values in the linked list we have to code:</p>
<pre><code class="lang-python">print(head.value)
print(head.next.value)
</code></pre>
<pre><code><span class="hljs-attr">Output:</span>
<span class="hljs-number">8</span>
<span class="hljs-number">4</span>
</code></pre><h3 id="heading-step-5-extending-our-linked-list">Step - 5 Extending our linked list</h3>
<p>Let's remember that this is what we want to accomplish:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1637697908154/Xo8-HkIR4.jpeg" alt="current_vs_goal.jpg" /></p>
<p>To do this, we need to create three more nodes, and we need to attach each one to the next attribute of the node that comes before it. Notice that we don't have a direct reference to any of the nodes other than the head.</p>
<pre><code class="lang-python">head.next.next = Node(<span class="hljs-number">2</span>)
head.next.next.next = Node(<span class="hljs-number">5</span>)
</code></pre>
<p>Let's print all the values:</p>
<pre><code class="lang-python">print(head.value)
print(head.next.value)
print(head.next.next.value)
print(head.next.next.next.value)
</code></pre>
<h3 id="heading-step-6-traversing-list">Step - 6 Traversing List</h3>
<p>This process isn't very efficient, let's write a function that receives the head and traverses the linked list to print out all of the values.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_linked</span>(<span class="hljs-params">head</span>):</span>
    current = head  <span class="hljs-comment"># current node set to the head</span>
    <span class="hljs-keyword">while</span> current: <span class="hljs-comment"># loop that will run as long as current exists</span>
        print(current.value) <span class="hljs-comment"># printing the current node value</span>
        current = current.next <span class="hljs-comment"># moving to the next node</span>

print_linked(head)
</code></pre>
<p>Ahh, so much better, now, no matter how long the linked list is, with <code>print_linked(head)</code> we no longer need to code <code>print(head.next.next.next.next)</code> you get the point.</p>
<h3 id="heading-step-7-creating-linkedlist-class">Step - 7 Creating Linked_List class</h3>
<p>Up until now, we have to create a variable with the head and pass that to our functions in order to interact with it, but an alternative it's to create a Linked_List class and code methods to it. Let's take a look at some code to understand what I mean.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Linked_List class with a default head value of None meaning empty list</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Linked_List</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>
</code></pre>
<p>Let's add our print function as a method to this class.</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_linked</span>(<span class="hljs-params">self</span>):</span>
        current = self.head
        <span class="hljs-keyword">while</span> current:
            print(current.value)
            current = current.next
</code></pre>
<p>In the code above, we made tiny changes to fit in as a method, in this case instead of receiving the head, we receive the <code>self</code> attribute, and instead of setting current to the head, we set it to the <code>self.head</code>, other than that, everything stays the same.</p>
<p>Now, we have our Linked list class with a print method and we have to create the actual object like this:</p>
<pre><code class="lang-python">my_linked_list = Linked_List()
</code></pre>
<p>and if we wanted to print the values of that linked list, all we have to do is:</p>
<pre><code class="lang-python">my_linked_list.print_linked()
</code></pre>
<p>If you tested the lines above you should have seen no output since the linked list is completely empty, let's change that by adding a method that allows us to append items into the list.</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">append</span>(<span class="hljs-params">self, value</span>):</span>

        <span class="hljs-comment"># checking if the linked list is empty</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-comment"># If so, set the head to a new node with the passed value</span>
            self.head = Node(value)
            <span class="hljs-keyword">return</span>

        <span class="hljs-comment"># Traverse the linked list until reaching the end of the list</span>
        current = self.head
        <span class="hljs-keyword">while</span> current.next:
            current = current.next

        <span class="hljs-comment"># Append the new node with the passed value</span>
        current.next = Node(value)
</code></pre>
<p>Here's the full code:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Linked_List</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_linked</span>(<span class="hljs-params">self</span>):</span>
        current = self.head
        <span class="hljs-keyword">while</span> current:
            print(current.value)
            current = current.next

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">append</span>(<span class="hljs-params">self, value</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = Node(value)
            <span class="hljs-keyword">return</span>

        current = self.head
        <span class="hljs-keyword">while</span> current.next:
            current = current.next

        current.next = Node(value)


my_linked_list = Linked_List()  <span class="hljs-comment"># this is creating a Linked_List object</span>
my_linked_list.append(<span class="hljs-number">8</span>)  <span class="hljs-comment"># appending 8 to the list</span>
my_linked_list.append(<span class="hljs-number">4</span>)  <span class="hljs-comment"># appending 4 to the list</span>
my_linked_list.append(<span class="hljs-number">2</span>)  <span class="hljs-comment"># appending 2 to the list</span>
my_linked_list.append(<span class="hljs-number">5</span>)  <span class="hljs-comment"># appending 5 to the list</span>
my_linked_list.print_linked()  <span class="hljs-comment"># printing the list</span>
</code></pre>
<p>If you test the code above you shall now see an output of <code>8 4 2 5</code> like the image below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638213481627/xigRLdw9l.png" alt="result_list.png" /></p>
<h2 id="heading-adding-more-methods">Adding more methods</h2>
<p>I hope you're getting the hang of this, let's try adding more methods that will make working with linked lists better.</p>
<p>Below you will find the exercises for this section, I highly encourage you to try to code them yourself before watching the solutions that can be found at the end of this section. And I also recommend you try each of the methods individually first before trying to use multiple of them together.</p>
<h3 id="heading-add-a-tolist-method">Add a <code>to_list()</code> method</h3>
<p>When the method is called on the linked list it should convert the linked list back into a normal python list.</p>
<pre><code><span class="hljs-attr">output:</span> 
[<span class="hljs-number">8</span>,<span class="hljs-number">4</span>,<span class="hljs-number">2</span>,<span class="hljs-number">5</span>]
</code></pre><h3 id="heading-add-a-prepend-method">Add a <code>prepend()</code> method</h3>
<p>Method similar to the <code>append()</code> method but instead of appending at the end of the linked list it will append at the beginning of the list</p>
<pre><code class="lang-python">my_linked_list.prepend(<span class="hljs-number">7</span>)
my_linked_list.print_linked()
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">7</span>
<span class="hljs-number">8</span>
<span class="hljs-number">4</span>
<span class="hljs-number">2</span>
<span class="hljs-number">5</span>
</code></pre><h3 id="heading-add-a-search-method">Add a <code>search()</code> method</h3>
<p><code>print(my_linked_list.search(4))</code> will return the Node if there is one with a matching value, if not, it will return a ValueError indicating that the searched value is not found in the list. Because it returns the searched Node you can access its value like this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># if there is a node with the value of 4, 4 will be printed</span>
print(my_linked_list.search(<span class="hljs-number">4</span>).value)
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">4</span>
</code></pre><h3 id="heading-add-a-remove-method">Add a <code>remove()</code> method</h3>
<p>Method traverses the linked list and removes the Node with the passed value</p>
<pre><code class="lang-python">my_linked_list.remove(<span class="hljs-number">4</span>)
my_linked_list.print_linked()
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">7</span>
<span class="hljs-number">8</span>
<span class="hljs-number">2</span>
<span class="hljs-number">5</span>
</code></pre><h3 id="heading-add-a-pop-method">Add a <code>pop()</code> method</h3>
<p>Method that removes the first node of the linked list</p>
<pre><code class="lang-python">my_linked_list.pop()
my_linked_list.print_linked()
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">8</span>
<span class="hljs-number">2</span>
<span class="hljs-number">5</span>
</code></pre><h3 id="heading-add-a-insert-method">Add a <code>insert()</code> method</h3>
<p>This method receives a position and a value and inserts a new node with the passed value in the passed position</p>
<pre><code class="lang-python">my_linked_list.insert(<span class="hljs-number">10</span>,<span class="hljs-number">1</span>)
my_linked_list.print_linked()
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">8</span>
<span class="hljs-number">10</span>
<span class="hljs-number">2</span>
<span class="hljs-number">5</span>
</code></pre><h3 id="heading-add-a-size-method">Add a <code>size()</code> method</h3>
<p>This method shall return the length of the linked list like the method <code>len()</code> would on a normal python list</p>
<pre><code class="lang-python">print(my_linked_list.size())
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">4</span>
</code></pre><h3 id="heading-add-a-reverse-method">Add a <code>reverse()</code> method</h3>
<p>Reversing a linked list is a really common interview problem and I highly recommend that you put extra effort into understanding this method. This method shall, like the name suggests, reverse the linked list nodes order.</p>
<pre><code class="lang-python">my_linked_list.reverse()
my_linked_list.print_linked()
</code></pre>
<pre><code><span class="hljs-attr">output:</span> 
<span class="hljs-number">5</span>
<span class="hljs-number">2</span>
<span class="hljs-number">10</span>
<span class="hljs-number">8</span>
</code></pre><h2 id="heading-full-code">Full Code</h2>
<p>Feel free to test out combinations of the methods and try each one individually and do your best in understanding them. You can also try adding your own methods, and remember that the solutions shown below are not the only correct ways of coding them.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Linked_List</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.head = <span class="hljs-literal">None</span>

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">print_linked</span>(<span class="hljs-params">self</span>):</span>
        current = self.head
        <span class="hljs-keyword">while</span> current:
            print(current.value)
            current = current.next

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">append</span>(<span class="hljs-params">self, value</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = Node(value)
            <span class="hljs-keyword">return</span>

        current = self.head
        <span class="hljs-keyword">while</span> current.next:
            current = current.next

        current.next = Node(value)

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">to_list</span>(<span class="hljs-params">self</span>):</span>
        out = []
        node = self.head
        <span class="hljs-keyword">while</span> node:
            out.append(node.value)
            node = node.next
        <span class="hljs-keyword">return</span> out

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">prepend</span>(<span class="hljs-params">self, value</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = Node(value)
            <span class="hljs-keyword">return</span>

        new_head = Node(value)
        new_head.next = self.head
        self.head = new_head

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">search</span>(<span class="hljs-params">self, value</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

        node = self.head
        <span class="hljs-keyword">while</span> node:
            <span class="hljs-keyword">if</span> node.value == value:
                <span class="hljs-keyword">return</span> node
            node = node.next

        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Value not found in the list."</span>)

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">remove</span>(<span class="hljs-params">self, value</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-keyword">return</span>

        <span class="hljs-keyword">if</span> self.head.value == value:
            self.head = self.head.next
            <span class="hljs-keyword">return</span>

        node = self.head
        <span class="hljs-keyword">while</span> node.next:
            <span class="hljs-keyword">if</span> node.next.value == value:
                node.next = node.next.next
                <span class="hljs-keyword">return</span>
            node = node.next

        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Value not found in the list."</span>)

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

        node = self.head
        self.head = self.head.next

        <span class="hljs-keyword">return</span> node.value

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">insert</span>(<span class="hljs-params">self, value, pos</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            self.head = Node(value)
            <span class="hljs-keyword">return</span>

        <span class="hljs-keyword">if</span> pos == <span class="hljs-number">0</span>:
            self.prepend(value)
            <span class="hljs-keyword">return</span>

        index = <span class="hljs-number">0</span>
        node = self.head
        <span class="hljs-keyword">while</span> node.next <span class="hljs-keyword">and</span> index &lt;= pos:
            <span class="hljs-keyword">if</span> (pos - <span class="hljs-number">1</span>) == index:
                new_node = Node(value)
                new_node.next = node.next
                node.next = new_node
                <span class="hljs-keyword">return</span>

            index += <span class="hljs-number">1</span>
            node = node.next
        <span class="hljs-keyword">else</span>:
            self.append(value)

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">size</span>(<span class="hljs-params">self</span>):</span>
        size = <span class="hljs-number">0</span>
        node = self.head
        <span class="hljs-keyword">while</span> node:
            size += <span class="hljs-number">1</span>
            node = node.next

        <span class="hljs-keyword">return</span> size

    <span class="hljs-comment"># ------------------------------------------ #</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reverse</span>(<span class="hljs-params">self</span>):</span>
        previous = <span class="hljs-literal">None</span>
        current = self.head
        <span class="hljs-keyword">while</span> current:
            next = current.next
            current.next = previous
            previous = current
            current = next
        self.head = previous

    <span class="hljs-comment"># ------------------------------------------ #</span>


my_linked_list = Linked_List()  <span class="hljs-comment"># creating linked list obj</span>

my_linked_list.append(<span class="hljs-number">8</span>)  <span class="hljs-comment"># appending 8</span>
my_linked_list.append(<span class="hljs-number">4</span>)  <span class="hljs-comment"># appending 4</span>
my_linked_list.append(<span class="hljs-number">2</span>)  <span class="hljs-comment"># appending 2</span>
my_linked_list.append(<span class="hljs-number">5</span>)  <span class="hljs-comment"># appending 5</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 8 4 2 5</span>

print(my_linked_list.to_list())  <span class="hljs-comment"># output: [8,4,2,5]</span>

my_linked_list.prepend(<span class="hljs-number">7</span>)  <span class="hljs-comment"># appending 7 to the start of the linked list</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 7 8 4 2 5</span>

print(my_linked_list.search(<span class="hljs-number">4</span>).value)  <span class="hljs-comment"># output: 4</span>

my_linked_list.remove(<span class="hljs-number">4</span>)  <span class="hljs-comment"># remove the node with value 4 from the list</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 7 8 2 5</span>

my_linked_list.pop()  <span class="hljs-comment"># remove the first node</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 8 2 5</span>

my_linked_list.insert(<span class="hljs-number">10</span>, <span class="hljs-number">1</span>)  <span class="hljs-comment"># insert node with value 10 in position 1</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 8 10 2 5</span>

print(my_linked_list.size())  <span class="hljs-comment"># output: 4</span>

my_linked_list.reverse()  <span class="hljs-comment"># reverse the order of the nodes</span>
my_linked_list.print_linked()  <span class="hljs-comment"># output: 5 2 10 8</span>
</code></pre>
<h2 id="heading-types-of-linked-lists">Types of Linked Lists</h2>
<h3 id="heading-singly-linked-list">Singly Linked List</h3>
<p>Up until this point, we have been working with a type of linked list called: "singly linked list", in this kind of linked list, each node is connected only to the next node in the list.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638307507807/g1QmuRVfF.png" alt="result_list.png" /></p>
<p>This connection is typically implemented by setting the <code>next</code> attribute on a node object itself. But there are more types of linked lists.</p>
<h3 id="heading-doubly-linked-list">Doubly Linked List</h3>
<p>This type of list is the exact same as the singly linked list with the addition of also having a connection backward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638388293420/YLFN0ZQP8.png" alt="Doubly linked list.png" /></p>
<p>To implement a Doubly linked list simply change your node to have a previous property like this:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DoubleNode</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, value</span>):</span>
        self.value = value
        self.next = <span class="hljs-literal">None</span>
        self.previous = <span class="hljs-literal">None</span> <span class="hljs-comment"># new property</span>
</code></pre>
<h4 id="heading-why-use-doubly-linked-lists">Why use Doubly linked lists?</h4>
<p>using doubly linked lists can give us advantages that a singly linked list can't, for example, now that we track the tail, we can do things like appending a node to a list's tail in constant time.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">append</span>(<span class="hljs-params">self, value</span>):</span>
    <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        self.head = DoubleNode(value)
        self.tail = self.head
        <span class="hljs-keyword">return</span>

    self.tail.next = DoubleNode(value)
    self.tail.next.previous = self.tail
    self.tail = self.tail.next
    <span class="hljs-keyword">return</span>
</code></pre>
<h3 id="heading-circular-linked-lists">Circular Linked Lists</h3>
<p>Linked circular lists occur when the chain of nodes links to itself somewhere. For example, NodeA -&gt; NodeB -&gt; NodeC -&gt; NodeD -&gt; NodeB is a circular list because NodeD points to NodeB creating a NodeB -&gt; NodeC -&gt; NodeD -&gt; NodeB loop.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638411442140/yPlrkcgfI.png" alt="circular linked list.png" /></p>
<p>A circular linked list in simple words, it's a singly or doubly list where all nodes are connected to form a loop or "circle" meaning there is no NULL at the end, this can be a problem since if we try to iterate through it we will never find the end. We usually want to detect if there's a loop in our linked list to avoid an infinite iteration.</p>
<h2 id="heading-detecting-loops-in-linked-lists">Detecting Loops in Linked Lists</h2>
<p> In this section, we'll see a way we can detect loops in a linked list with python. The way we'll do this is by using two pointers called "runners", both of them will traverse through the linked list but one of them it's going to iterate twice as fast, meaning it will advance two nodes at a time.
If a loop exists, the fast runner will eventually catch up with the slow runner and both pointers will be pointing at the same node at the same time, if this happens you will know for sure there's a loop, see the image below to understand this technique.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638588946123/wkoDuzPwP.gif" alt="linked List Loop Detection.gif" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638414846551/K9WLgxaHV.png" alt="loop in linked list.png" /></p>
<h3 id="heading-exercise-9-add-a-hasloop-method">Exercise - 9 Add a <code>hasLoop()</code> method</h3>
<p>I'm confident you can do this on your own, see the image above thoroughly to understand the algorithm you're about to code, and also take another look at the past exercises, you should find everything you need in this post. Make your best effort! and don't worry if you don't get it right away we'll see the solution below.</p>
<h3 id="heading-solution-hasloop-method">Solution <code>hasLoop()</code> method</h3>
<p>The first thing we need to do is to define our <code>hasLoop()</code> method:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hasLoop</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-comment"># your code goes here</span>
</code></pre>
<p>Next, we'll check if the list is empty, in the case that the condition is True we'll return False meaning there is no loop</p>
<pre><code class="lang-python">    <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<p>Then, we need to create our two pointers as we talked about earlier</p>
<pre><code class="lang-python">    slow = self.head
    fast = self.head
</code></pre>
<p>Now the fun part! while the fast node and the fast.next node exists, let's advance the slow node by one and the fast by two</p>
<pre><code class="lang-python">    <span class="hljs-keyword">while</span> fast <span class="hljs-keyword">and</span> fast.next:
        slow = slow.next
        fast = fast.next.next
</code></pre>
<p>and for each iteration, we need to check if the slow node is the same as the fast one, if that is the case then we just found a loop and the code should return True, if the while loops finishes, it means there was an end to the list and the code should return False.</p>
<pre><code class="lang-python">        <span class="hljs-keyword">if</span> slow == fast:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<p>Full code:</p>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hasLoop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">if</span> self.head <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>: <span class="hljs-comment"># check if the linked list is empty</span>
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span> <span class="hljs-comment"># return False, meaning there is no loop</span>

        slow = self.head <span class="hljs-comment"># create the slow node</span>
        fast = self.head <span class="hljs-comment"># create the fast node</span>

        <span class="hljs-keyword">while</span> fast <span class="hljs-keyword">and</span> fast.next: <span class="hljs-comment"># while fast and fast.next exist:</span>
            slow = slow.next <span class="hljs-comment"># advance the slow node by one</span>
            fast = fast.next.next <span class="hljs-comment"># advance the fast node by two</span>

            <span class="hljs-keyword">if</span> slow == fast: <span class="hljs-comment"># if the nodes are the same</span>
                <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span> <span class="hljs-comment"># return True, meaning there is a loop</span>

        <span class="hljs-comment"># if the loop finishes, that means there was an end to the list</span>
        <span class="hljs-comment"># and there was no loop</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<h2 id="heading-flatten-a-nested-linked-list">Flatten a Nested Linked List</h2>
<p>Let's suppose we have a <strong>nested</strong> linked list, this means that the value of each node in the linked list is another ordered linked list. The image below illustrates this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638497197984/dFk0NBTts.png" alt="oredered nested linked list.png" /></p>
<p>In this section, we'll <strong>flatten</strong> this linked list, which means to combine all nested lists into one <strong>ordered</strong> single linked list like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638497146402/P8U_ysIIR.png" alt="goal nested linked list.png" /></p>
<h3 id="heading-step-1-define-a-nestedlinkedlist-class">Step - 1 Define a <code>NestedLinkedList</code> class</h3>
<p>This class should inherit the Linked_List class and inside of the new class let's add our flatten method.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NestedLinkedList</span>(<span class="hljs-params">Linked_List</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">flatten</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-comment"># code goes here</span>
</code></pre>
<h3 id="heading-step-2-define-a-merge-helper-function">Step - 2 Define a <code>merge()</code> Helper Function</h3>
<p>This function will be useful for merging two linked lists and having them into a single <strong>ordered</strong> linked list, this function it's not going to be a <code>NestedLinkedList</code> method and should return an instance of LinkedList.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">merge</span>(<span class="hljs-params">list1, list2</span>):</span>
    <span class="hljs-comment"># your code goes here</span>
    <span class="hljs-keyword">return</span>
</code></pre>
<h3 id="heading-merge-walkthrough"><code>merge()</code> walkthrough</h3>
<p>Note, this solution expects the passed lists to be ordered.</p>
<p>First, we need to create a new LinkedList object, that will be named <code>merged</code></p>
<pre><code class="lang-python">    merged = Linked_List()
</code></pre>
<p>Next, let's check whether any of the passed lists are None. If list1 is None, immediately return list2, if list2 is None, immediately return list1.</p>
<pre><code class="lang-python">    <span class="hljs-keyword">if</span> list1 <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> list2
    <span class="hljs-keyword">if</span> list2 <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> list1
</code></pre>
<p>Then, we'll create two traversers, one called list1_node and the second one called list2_node. And using both of them, we'll traverse both lists while they exist.</p>
<pre><code class="lang-python">    list1_node = list1.head
    list2_node = list2.head
    <span class="hljs-keyword">while</span> list1_node <span class="hljs-keyword">or</span> list2_node: <span class="hljs-comment"># pay attention to the OR</span>
</code></pre>
<p>If the first node does not exist, meaning the first list is traversed, append the list2_node to the "result list"(merged) and advance the list2_node to the next node in that list.</p>
<pre><code class="lang-python">        <span class="hljs-keyword">if</span> list1_node <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>: <span class="hljs-comment"># if list1 is traversed</span>
            merged.append(list2_node.value) <span class="hljs-comment"># append the second list node to the "result"</span>
            list2_node = list2_node.next <span class="hljs-comment"># and advance the second node to the next one</span>
</code></pre>
<p>Repeat the step above but with the list2</p>
<pre><code class="lang-python">        <span class="hljs-keyword">elif</span> list2_node <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>: <span class="hljs-comment"># if list2 is traversed</span>
            merged.append(list1_node.value) <span class="hljs-comment"># append the first node to the "result"</span>
            list1_node = list1_node.next <span class="hljs-comment"># advance the first node to the next one</span>
</code></pre>
<p>Now we can work in the cases that none of the lists are done traversing. Which would always be the first iteration.</p>
<p>Because we want the output to be an <mark>ordered</mark> linked list but with both lists merged, we need to check which node has the smallest value and append it.</p>
<pre><code class="lang-python">        <span class="hljs-comment"># if the first node value is smaller than the second node value</span>
        <span class="hljs-keyword">elif</span> list1_node.value &lt;= list2_node.value:
            merged.append(list1_node.value) <span class="hljs-comment"># append the first node</span>
            list1_node = list1_node.next <span class="hljs-comment"># and advance to the next node</span>
        <span class="hljs-keyword">else</span>: 
            merged.append(list2_node.value) <span class="hljs-comment"># append the second node</span>
            list2_node = list2_node.next <span class="hljs-comment"># advance to the next node</span>
</code></pre>
<p>Finally, after the while loop exits indicating that both lists have been traversed, return the result, (merge) linked list.</p>
<pre><code class="lang-python">    <span class="hljs-keyword">return</span> merged
</code></pre>
<p>Here's the full <code>merge()</code> procedure:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">merge</span>(<span class="hljs-params">list1, list2</span>):</span>

    merged = Linked_List()

    <span class="hljs-keyword">if</span> list1 <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> list2
    <span class="hljs-keyword">if</span> list2 <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> list1

    list1_node = list1.head  <span class="hljs-comment"># [5,6,7] list one</span>
    list2_node = list2.head  <span class="hljs-comment"># [1,2,3] list two</span>
    <span class="hljs-keyword">while</span> list1_node <span class="hljs-keyword">or</span> list2_node:  <span class="hljs-comment"># 5 - 1</span>
        <span class="hljs-keyword">if</span> list1_node <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:  <span class="hljs-comment"># if list1 is traversed</span>
            <span class="hljs-comment"># append the second list node to the "result"</span>
            merged.append(list2_node.value)
            list2_node = list2_node.next  <span class="hljs-comment"># and advance the second node to the next one</span>
        <span class="hljs-keyword">elif</span> list2_node <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:  <span class="hljs-comment"># if list2 is traversed</span>
            <span class="hljs-comment"># append the first node to the "result"</span>
            merged.append(list1_node.value)
            list1_node = list1_node.next  <span class="hljs-comment"># advance the first node to the next one</span>
        <span class="hljs-comment"># if the first node value is smaller than the second node value</span>
        <span class="hljs-keyword">elif</span> list1_node.value &lt;= list2_node.value:
            merged.append(list1_node.value)  <span class="hljs-comment"># append the first node</span>
            list1_node = list1_node.next  <span class="hljs-comment"># and advance to the next node</span>
        <span class="hljs-keyword">else</span>:
            merged.append(list2_node.value)  <span class="hljs-comment"># append the second node</span>
            list2_node = list2_node.next  <span class="hljs-comment"># advance to the next node</span>
    <span class="hljs-keyword">return</span> merged
</code></pre>
<h3 id="heading-finishing-flatten-method">Finishing <code>Flatten()</code> Method</h3>
<p>With the help of our <code>merge()</code> helper function, there is an easy solution to finish our <code>Flatten()</code> method by using <strong>recursion</strong>.</p>
<p>We won't talk about recursion in detail in this post, but for those that are not familiar with the concept, recursion is basically invoking a function inside itself, here's a code example that returns the factorial of any number.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">factorial</span>(<span class="hljs-params">x</span>):</span> <span class="hljs-comment"># function definition</span>
    <span class="hljs-keyword">if</span> x == <span class="hljs-number">1</span>: <span class="hljs-comment"># break point, important to exit the "loop"</span>
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> (x*factorial(x<span class="hljs-number">-1</span>)) <span class="hljs-comment"># invoking itself</span>


print(factorial(<span class="hljs-number">4</span>))  <span class="hljs-comment"># 4 * 3 * 2 * 1 = 24</span>
</code></pre>
<p>As you can see from the code above, the <code>factorial()</code> function it's being invoked inside of itself, that's a recursive function.</p>
<p>Back to our <code>Flatten()</code> method. Let's apply recursion!</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NestedLinkedList</span>(<span class="hljs-params">Linked_List</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">flatten</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self._flatten(self.head)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_flatten</span>(<span class="hljs-params">self, node</span>):</span>  <span class="hljs-comment"># a recursive function</span>

        <span class="hljs-comment"># A termination condition</span>
        <span class="hljs-keyword">if</span> node.next <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            <span class="hljs-comment"># if there is no next node in the list</span>
            <span class="hljs-comment"># merge the last, current node</span>
            <span class="hljs-keyword">return</span> merge(node.value, <span class="hljs-literal">None</span>)

        <span class="hljs-comment"># _flatten() is calling itself untill a termination condition is achieved</span>
        <span class="hljs-comment"># &lt;-- Both arguments are a simple LinkedList each</span>
        <span class="hljs-keyword">return</span> merge(node.value, self._flatten(node.next))
</code></pre>
<h3 id="heading-testing-flatten-function">Testing <code>flatten()</code> Function</h3>
<p>First, let's create three simple, normal,ordered, linked lists.</p>
<pre><code class="lang-python"><span class="hljs-string">''' Create a simple LinkedList'''</span>
linked_list = Linked_List()
linked_list.append(<span class="hljs-number">0</span>)
linked_list.append(<span class="hljs-number">4</span>)
linked_list.append(<span class="hljs-number">8</span>)
linked_list.print_linked()
<span class="hljs-comment"># 0 =&gt; 4 =&gt; 8</span>

<span class="hljs-string">''' Create another simple LinkedList'''</span>
second_linked_list = Linked_List()
second_linked_list.append(<span class="hljs-number">1</span>)
second_linked_list.append(<span class="hljs-number">2</span>)
second_linked_list.append(<span class="hljs-number">3</span>)
second_linked_list.print_linked()
<span class="hljs-comment"># 1 =&gt; 2 =&gt; 3</span>

<span class="hljs-string">''' Create another simple LinkedList'''</span>
third_linked_list = Linked_List()
third_linked_list.append(<span class="hljs-number">6</span>)
third_linked_list.append(<span class="hljs-number">7</span>)
third_linked_list.append(<span class="hljs-number">9</span>)
third_linked_list.print_linked()
<span class="hljs-comment"># 6 =&gt; 7 =&gt; 9</span>
</code></pre>
<p>Next, let's create a <strong>nested</strong> linked list object using our class</p>
<pre><code class="lang-python">nested_linked_list = NestedLinkedList()
</code></pre>
<p>Something really cool, it's that when we defined the <code>NestedLinkedList</code>class, we <mark>inherited</mark> the <code>Linked_List</code> class, which means that all of the previous methods we wrote for the <code>Linked_list</code> class are going to be available to use in the <code>NestedLinkedList</code> class.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Here we inherited the Linked_List class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NestedLinkedList</span>(<span class="hljs-params">Linked_List</span>):</span>  <span class="hljs-comment"># making all of its methods available here too!</span>
</code></pre>
<p>Now, let's append the three simple linked lists into this <code>nested_linked_list</code> using the <code>append()</code> method.</p>
<pre><code class="lang-python">nested_linked_list.append(linked_list)
nested_linked_list.append(second_linked_list)
nested_linked_list.append(third_linked_list)
</code></pre>
<p>Lastly, create the flattened list like this:</p>
<pre><code class="lang-python">flattened = nested_linked_list.flatten()
</code></pre>
<p>and print it out!</p>
<pre><code class="lang-python">flattened.print_linked()
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>You've reached the end of this lesson on Linked Lists, we saw what are they? how do they differentiate from a normal python list? what are some pros and cons? and we also saw code examples of the most common ways to interact with Linked lists.</p>
<p>I really hope some of the guidelines we saw today were helpful and the basic foundations on this topic were well understood, remember, there is still a lot to learn and we definitively didn't cover everything on linked lists, but I hope this was a good beginner overview and that you grasped the concepts and feel more confident on your programming journey.</p>
<p>Let me know in the comments what you thought about this post and let me know what you will like to see next. See you in the next post, stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Programmers Guide to Solving Computational Problems]]></title><description><![CDATA[Introduction
Hello everyone, welcome back! today I want to talk about a very important topic: how to solve problems?. Learning how to solve problems is one of the most important skills you can learn, and improving as a problem solver is a lifelong ch...]]></description><link>https://blog.garybricks.com/programmers-guide-to-solving-computational-problems</link><guid isPermaLink="true">https://blog.garybricks.com/programmers-guide-to-solving-computational-problems</guid><category><![CDATA[Python 3]]></category><category><![CDATA[Programming Tips]]></category><category><![CDATA[data structures]]></category><category><![CDATA[Competitive programming]]></category><category><![CDATA[problem solving skills]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Sat, 06 Nov 2021 20:26:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636227978922/E9sAOrxPQ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hello everyone, welcome back! today I want to talk about a very important topic: how to solve problems?. Learning how to solve problems is one of the most important skills you can learn, and improving as a problem solver is a lifelong challenge that cannot be learned through this short lesson, however, I want to show you important tips on how to tackle more complex programming problems, and hopefully, this post will teach you the essentials to problem-solving.</p>
<h2 id="heading-what-problems">What Problems?</h2>
<p>In this post, we will tackle a specific problem, and talk about how I would go about solving it, and the goal of this exercise is not just to solve the problem but to draw general ideas on how to solve any type of programming problem.</p>
<h3 id="heading-days-between-dates">Days Between Dates</h3>
<blockquote>
<p>Given your birthday and the current date, calculate your age in days. Compensate for leap years. Assume that the birthday and current date are correct (no time travel).</p>
</blockquote>
<h2 id="heading-understanding-a-problem">Understanding a Problem</h2>
<p>It's often tempting to start writing code early, the problem with this is that we are likely to write the wrong code and get frustrated, it's also likely that you think that you "solved the problem" but in reality, you might end up doing something completely different to what it was asked.</p>
<h3 id="heading-so-what-does-it-mean-to-understand-a-problem">So what does it mean to understand a problem?.</h3>
<p>We need to emphasize that we are working on a <code>computational problem</code>, and what all computational problems have in common is that they have inputs and desired outputs, so, a problem is defined by the set of possible inputs (this is usually an infinite set) and the relationships between those inputs and the desired outputs. And a solution is a procedure that can take any input in that set and produces the desired output that satisfies the relationship, in this case, the relationship we want is that the output is the number of days between the birthday and the current date.</p>
<p>So, the first step to understanding a problem is to understand what the possible inputs are.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635880990506/u4Cn-HP3U.png" alt="understand input.png" /></p>
<h2 id="heading-step-1-what-are-the-inputs">Step - 1 What are the inputs?</h2>
<p>If we take another look at the problem we realized that it's clearly stated that we're given two dates as inputs.</p>
<blockquote>
<p><mark>Given your birthday and the current date</mark>, calculate your age in days. Compensate for leap years. Assume that the birthday and current date are correct (no time travel).</p>
</blockquote>
<h3 id="heading-what-is-the-set-of-valid-inputs">What is the set of valid inputs?</h3>
<p>We always need to ask ourselves this question, for the moment we know the type of the inputs, but if we take another look at our problem we can find a good clue on what to expect.</p>
<blockquote>
<p>Given your birthday and the current date, calculate your age in days. Compensate for leap years. <mark>Assume that the birthday and current date are correct (no time travel).</mark></p>
</blockquote>
<p>Thanks to that statement we know that the second date needs to be after the first one. Assumptions like this one make life easier for programmers since our code has to work for fewer possible inputs, however, we are going to be good defensive programmers and check if the second date is after the first date in our code. Checking if the requirement is correct is a good practice since other people or even ourselves can make mistakes.</p>
<p>The other assumption we might need to think about is the range of dates. Calendars are very complicated and they've changed over history, so, we are going to require that the dates are valid dates in the Gregorian calendar, which started in October 1582.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635886958157/PDyAljbAt.png" alt="what are the inputs.png" /></p>
<h3 id="heading-how-are-inputs-represented">How are inputs represented?</h3>
<p>For most real-world problems, it's up to you to figure out how to encode the inputs and this is one of the most important decisions that you can make in solving a problem. In this case, the problem template below indicates how the inputs are represented</p>
<pre><code class="lang-python"><span class="hljs-comment"># function that returns the dates difference in days</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysBetweenDates</span>(<span class="hljs-params"> year1, month1, day1, year2, month2, day2 </span>):</span>
    <span class="hljs-comment"># You're code goes here</span>
</code></pre>
<p>As we can see there are six parameters to the daysBetweenDates procedure, which means we're going to be passing in six different values to represent those two dates. Some of you might see that there are better ways to pass the date, as an object for example but for the sake of clarity we're going to be passing those six values.</p>
<h2 id="heading-step-2-what-are-the-outputs">Step - 2 What are the outputs?</h2>
<p>The statement of the question gives us some idea of what the output should be in the calculate your age part.</p>
<blockquote>
<p>Given your birthday and the current date, <mark>calculate your age in days.</mark> Compensate for leap years. Assume that the birthday and current date are correct (no time travel).</p>
</blockquote>
<p>But it doesn't specify really explicitly what we want the output to be</p>
<h3 id="heading-how-should-we-specify-the-output">How should we specify the output?</h3>
<p>In this case, after reading the problem, it's clear that the output should be a <strong>number </strong> representing the days of the difference between date1 and date2 assuming date1 is before date2.</p>
<h2 id="heading-step-3-understanding-the-relationship">Step - 3 Understanding the relationship</h2>
<p>Now that we know what the inputs are and what the outputs are it's time to understand the relationship between the two by working out some examples.</p>
<p>Take a good look at the problems below and try to figure out what the output for each call should be.</p>
<pre><code class="lang-python">daysBetweenDates(<span class="hljs-number">2020</span>,<span class="hljs-number">11</span>,<span class="hljs-number">7</span>, <span class="hljs-number">2020</span>,<span class="hljs-number">11</span>,<span class="hljs-number">7</span>)

daysBetweenDates(<span class="hljs-number">2015</span>,<span class="hljs-number">12</span>,<span class="hljs-number">7</span>, <span class="hljs-number">2015</span>,<span class="hljs-number">12</span>,<span class="hljs-number">8</span>)

daysBetweenDates(<span class="hljs-number">2010</span>,<span class="hljs-number">12</span>,<span class="hljs-number">8</span>, <span class="hljs-number">2010</span>,<span class="hljs-number">12</span>,<span class="hljs-number">7</span>)

daysBetweenDates(<span class="hljs-number">2019</span>,<span class="hljs-number">5</span>,<span class="hljs-number">15</span>, <span class="hljs-number">2021</span>,<span class="hljs-number">5</span>,<span class="hljs-number">15</span>)

daysBetweenDates(<span class="hljs-number">2012</span>,<span class="hljs-number">6</span>,<span class="hljs-number">29</span>,<span class="hljs-number">2013</span>,<span class="hljs-number">6</span>,<span class="hljs-number">31</span>)
</code></pre>
<p>For problem one, the output should be 0 since both dates are the same. For problem two the output should be 1 since there is only a one-day difference. Output for problem three should be an error since the second date is before the first date. Problem four was hard since, there was a two-year difference and 2020 is a leap year, so, the output should be 731. The last one was tricky since there is no day 31 in June!, so we would like to have an error indicating the invalid input.</p>
<p>At this point, you might be ready to start coding, but if the problem is challenging one you're probably not.</p>
<h2 id="heading-step-4-solving-the-problem-as-a-human">Step - 4 Solving the problem as a human</h2>
<p>The first step to solving a problem as a human is to look at an example and in this case let's say we wanted to find the difference between the dates (2013,01,24) and (2013,06,29), as a human the first thing that we might do is to look at a calendar and find the first date, then see how many days are left for that month, in this case, that is 7 days, we would probably grab a piece of paper and write that number down. Then we would count how many days has every month until we reach the second date.
<code>7+28+31+30+31+29 = 156</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635968662441/-b5vj4Y1q.png" alt="calendar.png" /></p>
<p>We now have a starting point and it's time to write down an algorithm that systematizes how we solve it, in this case, we're going to write this as <code>Pseudocode</code> meaning we aren't focusing on coding real python code but the ideas instead. </p>
<pre><code class="lang-python"><span class="hljs-comment"># find the days between the dates (2013,01,24) and (2013,06,29)</span>
<span class="hljs-comment">#(year1,month1,day1,year2,month2,day2)</span>

days = <span class="hljs-comment"># days in month1(31) - starting day(24) = 7</span>
<span class="hljs-keyword">while</span> month1 &lt; month2:
    days += <span class="hljs-comment"># days in current month1</span>
    month1 += <span class="hljs-number">1</span> <span class="hljs-comment"># moving to the next month</span>
days += day2 <span class="hljs-comment"># add the remaining days from the second date month(29)</span>
<span class="hljs-comment"># add the years days</span>
<span class="hljs-keyword">while</span> year1 &lt; year2:
    days += <span class="hljs-comment"># days in year1</span>
</code></pre>
<h3 id="heading-should-we-implement-this-algorithm">Should we implement this algorithm?</h3>
<p>In this case, I don't think we should, there are several cases that this code does not consider, like:</p>
<ul>
<li>input dates in same month <code>(2013,06,24 and 2013,06,29) # valid input</code></li>
<li>month2 &lt; month1 <code>(2012,07,24 and 2013,06,29) # valid input</code></li>
<li>year2 &lt; year1 <code>(2013,01,24 and 2012,06,29) # invalid input</code></li>
<li>accounting for leap years.</li>
</ul>
<h3 id="heading-different-approach">Different approach</h3>
<p>Let's think of a more simple mechanical algorithm. As humans, it's very inefficient to manually count day by day, but not for computers, and I want to emphasize optimization, don't optimize prematurely! focus on solving the problem first.</p>
<pre><code class="lang-python">days = <span class="hljs-number">0</span>
<span class="hljs-keyword">while</span> date1 &lt; date2:
    date1 += <span class="hljs-comment"># advance to next day</span>
    days += <span class="hljs-number">1</span>
<span class="hljs-keyword">return</span> days
</code></pre>
<p>This is the most simple approach possible, it's adding 1 day until we reach the second date.</p>
<h2 id="heading-step-5-coding-nextday-procedure">Step - 5 Coding nextDay procedure</h2>
<p>I want to take a look at line three.</p>
<pre><code>date1 += <span class="hljs-comment"># advance to next day</span>
</code></pre><p>This is clearly the most important part, and because of it, we should start by coding a <code>nextDay(year,month,day)</code> procedure. The function should receive a year, month, and day and return the year, month, and day of the next day.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">nextDay</span>(<span class="hljs-params">year, month, day</span>):</span>
    <span class="hljs-string">"""
    For simplicity, assume every month has 30 days.
    """</span>
    <span class="hljs-keyword">if</span> day &lt; <span class="hljs-number">30</span>:
        <span class="hljs-keyword">return</span> year, month, day + <span class="hljs-number">1</span>
    <span class="hljs-keyword">elif</span> month &lt; <span class="hljs-number">12</span>:
        <span class="hljs-keyword">return</span> year, month + <span class="hljs-number">1</span>, <span class="hljs-number">1</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> year + <span class="hljs-number">1</span>, <span class="hljs-number">1</span> ,<span class="hljs-number">1</span>

print(nextDay(<span class="hljs-number">2021</span>,<span class="hljs-number">3</span>,<span class="hljs-number">11</span>)) <span class="hljs-comment"># expected output: 2021,3,12</span>
print(nextDay(<span class="hljs-number">2021</span>,<span class="hljs-number">3</span>,<span class="hljs-number">29</span>)) <span class="hljs-comment"># expected output: 2021,3,30</span>
print(nextDay(<span class="hljs-number">2021</span>,<span class="hljs-number">3</span>,<span class="hljs-number">30</span>)) <span class="hljs-comment"># expected output: 2021,4,1</span>
print(nextDay(<span class="hljs-number">2021</span>,<span class="hljs-number">11</span>,<span class="hljs-number">30</span>)) <span class="hljs-comment"># expected output: 2021,12,1</span>
print(nextDay(<span class="hljs-number">2021</span>,<span class="hljs-number">12</span>,<span class="hljs-number">30</span>)) <span class="hljs-comment"># expected output: 2022,1,1</span>
</code></pre>
<p>As we can see, the code above accounts for the case that it's the end of the month and for the end of the year, the only problem with it it's that it's assuming all months have 30 days, so, what should we do next?</p>
<h2 id="heading-step-6-coding-daysbetweendates-procedure">Step - 6 Coding daysBetweenDates procedure</h2>
<p>In this case, we can make the <code>nextDay</code> procedure to work with real months but we can actually do that later and start coding the <code>daysBetweenDates</code> procedure first, the advantage is that we'll be more confident if we're on the right track and most importantly, we'll be closer to having an answer, then we can correct the <code>nextDay</code> procedure since that will be a significantly smaller detail that shouldn't affect our <code>daysBetweenDates</code> procedure.</p>
<h3 id="heading-step-1-look-at-the-pseudocode">Step - 1 look at the pseudocode</h3>
<pre><code class="lang-python">days = <span class="hljs-number">0</span>
<span class="hljs-keyword">while</span> date1 &lt; date2:
    date1 += <span class="hljs-comment"># advance to next day</span>
    days += <span class="hljs-number">1</span>
<span class="hljs-keyword">return</span> days
</code></pre>
<p>with our new <code>nextDay</code> procedure we can now code this right? well, not quite, if you have already tried you realized what the problem is. The comparison between dates.</p>
<pre><code class="lang-python"><span class="hljs-keyword">while</span> date1 &lt; date2:
</code></pre>
<h3 id="heading-step-2-helper-function">Step - 2 Helper Function</h3>
<p>Let's understand exactly what the helper function shall do, in this case, we only need to return a boolean, True if the first date is before the second, and False if it is not. Let's code it!. </p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">date1BeforeDate2</span>(<span class="hljs-params">year1,month1,day1,year2,month2,day2</span>):</span>
    <span class="hljs-string">"""
    returns True if the first date is before the second date
    """</span>
    <span class="hljs-keyword">if</span> year1 &lt; year2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">if</span> month1 &lt; month2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">if</span> day1 &lt; day2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<p>The solution for this helper function was really easy, we only needed to compare if the year1 was before year2, if that condition it's True, simply return True, then repeat the condition with the months and days, if none of the conditions were True simply return False.</p>
<h3 id="heading-step-3-daysbetweendates">Step - 3 daysBetweenDates</h3>
<p>Now that we have our helper function, it's time to try to code the pseudocode again with our newly created function.</p>
<p>Pseudocode:</p>
<pre><code class="lang-python">days = <span class="hljs-number">0</span>
<span class="hljs-keyword">while</span> date1 &lt; date2:
    date1 += <span class="hljs-comment"># advance to next day</span>
    days += <span class="hljs-number">1</span>
<span class="hljs-keyword">return</span> days
</code></pre>
<p>DaysBetweenDates procedure:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysBetweenDates</span>(<span class="hljs-params">year1, month1, day1, year2, month2, day2</span>):</span>
    <span class="hljs-string">"""
    returns the difference of two dates in days
    """</span>
    days = <span class="hljs-number">0</span>
    <span class="hljs-keyword">while</span> date1BeforeDate2(year1, month1, day1, year2, month2, day2):
        year1, month1, day1 = nextDay(year1, month1, day1)
        days += <span class="hljs-number">1</span>
    <span class="hljs-keyword">return</span> days

print(daysBetweenDates(<span class="hljs-number">2019</span>, <span class="hljs-number">5</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2021</span>, <span class="hljs-number">5</span>, <span class="hljs-number">15</span>)) <span class="hljs-comment"># output should have been 731</span>
print(daysBetweenDates(<span class="hljs-number">2023</span>, <span class="hljs-number">5</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2020</span>, <span class="hljs-number">5</span>, <span class="hljs-number">15</span>))  <span class="hljs-comment"># invalid inputs</span>
</code></pre>
<p>So much progress! however, if you run the code above you will realize that the output is 720 when it should have been 731, why?. Let's not forget that the <code>nextDay</code> procedure is incorrectly assuming all months have 30 days!!. However, it's very clear that we're on the right track. For the second print, we purposely passed invalid inputs to see what happens, in this case, the code output 0, but that is not really what we want.</p>
<h3 id="heading-step-4-test-for-invalid-inputs">Step - 4 Test for invalid inputs</h3>
<p>Like we talked about before, we are going to follow a good defensive programming practice and check for invalid inputs inside our <code>daysBetweenDates</code> procedure.</p>
<p>Python <code>assert()</code> is perfect for what we want. <code>assert()</code> allows us to perform comparisons. If the expression contained within it is False, an exception will be thrown, specifically an <code>AssertionError</code>.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-keyword">assert</span>(<span class="hljs-number">5</span> &lt; <span class="hljs-number">3</span>) <span class="hljs-comment"># False, an AssertionError will be shown</span>
<span class="hljs-keyword">assert</span>(<span class="hljs-number">2</span> &lt; <span class="hljs-number">4</span>) <span class="hljs-comment"># True, nothing will happen</span>
</code></pre>
<p>This fits perfectly for what we want, that is, checking if the first date is before the second date. Here is my implementation:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysBetweenDates</span>(<span class="hljs-params">year1, month1, day1, year2, month2, day2</span>):</span>
    <span class="hljs-string">"""
    returns the difference of two dates in days
    """</span>
    <span class="hljs-keyword">assert</span>(date1BeforeDate2(year1, month1, day1, year2, month2, day2))

    days = <span class="hljs-number">0</span>
    <span class="hljs-keyword">while</span> date1BeforeDate2(year1, month1, day1, year2, month2, day2):
        year1, month1, day1 = nextDay(year1, month1, day1)
        days += <span class="hljs-number">1</span>
    <span class="hljs-keyword">return</span> days
</code></pre>
<p>Now if we test an invalid case where the second date is before the first date we should see an <code>AssertionError</code> pop up in the terminal like the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636074389545/ZqHxCjbrI.png" alt="AssertionError.png" /></p>
<h2 id="heading-step-7-finishing-daysbetweendates-procedure">Step - 7 Finishing daysBetweenDates procedure</h2>
<p>Right now, we're 70% of the way, some of the things left to do are to make sure that the <code>daysBetweenDates</code> procedure accounts for leap years and months with the correct amount of days.</p>
<h3 id="heading-step-1-coding-daysinmonths-procedure">Step - 1 Coding daysInMonths procedure</h3>
<p>The way I'm going to approach this is that I'm going to write a <code>daysInMonth(year,month)</code> procedure that returns the correct number of days of the specified month. </p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysInMonth</span>(<span class="hljs-params">year, month</span>):</span>
    <span class="hljs-keyword">return</span>  <span class="hljs-comment"># the number of days of the specified month</span>
</code></pre>
<p>First things first, I'm going to do some googling to figure out what months have 31 days.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636080194957/XEZz_qWEu.png" alt="months with days.png" /></p>
<p>After a quick search, I found that the months with 31 days are months: 01, 03, 05, 07, 08, 10, and 12. With this information we can now add a condition in our code, like this:</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> month <span class="hljs-keyword">in</span> (<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">10</span>, <span class="hljs-number">12</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-number">31</span>
</code></pre>
<p>Let's repeat the process with the month of February, normally it has 28 days except on leap years where February has 29. For this first stage, we are going to check if the month is the number two and return 28 without accounting for leap years yet.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysInMonth</span>(<span class="hljs-params">year, month</span>):</span>
    <span class="hljs-string">"""
    Function that receives a month and a year
    and based on that, it will return the number
    of days the specific month has.

    WARNING: This code does not account for leap years yet
    """</span>
    <span class="hljs-keyword">if</span> month <span class="hljs-keyword">in</span> (<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">10</span>, <span class="hljs-number">12</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-number">31</span>
    <span class="hljs-keyword">elif</span> month == <span class="hljs-number">2</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">28</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">30</span>
</code></pre>
<p>As you can see from the code above, in the case that none of the conditions are true, it will return the normal 30 days.</p>
<h3 id="heading-step-2-integrating-daysinmonth-procedure">Step - 2 Integrating daysInMonth procedure</h3>
<p>Let's go back to our <code>nextDay</code> procedure and change it so that it now uses the correct number of days.</p>
<p>Before:</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> day &lt; <span class="hljs-number">30</span>:
</code></pre>
<p>After:</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> day &lt; daysInMonth(year, month):
</code></pre>
<h3 id="heading-step-3-coding-isleapyear-procedure">Step - 3 Coding isLeapYear procedure</h3>
<p>Just as we coded our <code>daysInMonth</code> helper procedure, we should also create a procedure to check if a specified year is a leap year, but before we code, we should understand what a leap year is.</p>
<blockquote>
<p></p><h3>Leap year</h3>
a year, occurring once every four years, that has 366 days including February 29 as an intercalary day. - https://en.wikipedia.org/wiki/Leap_year<p></p>
</blockquote>
<p>If you scroll below the Wikipedia article, you will find an algorithm section that is incredibly useful for programmers. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636143194735/550b9yIGg.png" alt="algorithm.png" /></p>
<p>Here is my implementation of the algorithm:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">isLeapYear</span>(<span class="hljs-params">year</span>):</span>
    <span class="hljs-string">"""
    Function that receives a year and returns
    a boolean, True if the year is a leap year
    and False if it's not
    """</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">4</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">elif</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">100</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">elif</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">400</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>After we are done writing our function it's important to test it to make sure it works, in this case, the code is giving the expected output so now it's time to integrate it in our <code>daysInMonth</code> procedure.</p>
<h3 id="heading-step-4-finishing-daysinmonth-procedure">Step - 4 Finishing daysInMonth procedure</h3>
<p>For the moment, the <code>daysInMonth</code> procedure does not account for leap years and it's returning 28 days if the month is February, let's change that with our newly created <code>isLeapYear</code> procedure.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysInMonth</span>(<span class="hljs-params">year, month</span>):</span>
    <span class="hljs-string">"""
    Function that receives a month and a year
    and based on that, it will return the number
    of days the specific month has, accounting for
    leap years.
    """</span>
    <span class="hljs-keyword">if</span> month <span class="hljs-keyword">in</span> (<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">10</span>, <span class="hljs-number">12</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-number">31</span>
    <span class="hljs-keyword">elif</span> month == <span class="hljs-number">2</span>:
        <span class="hljs-keyword">if</span> isLeapYear(year):
            <span class="hljs-keyword">return</span> <span class="hljs-number">29</span>
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-number">28</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">30</span>
</code></pre>
<p>Now, if the month is February, the code will check if the year is a leap year, if that it's true it will return 29 days, and if it's not it will return the normal 28 days. 
At this point, it looks like we are done, now it's time to test the full code with several examples.</p>
<p>After testing we realized that everything looks to be working except for the case where the dates are the same.
<code>print(daysBetweenDates(2021, 8, 24, 2021, 8, 24))</code> 
If you run this test case you will see an AssertionError when the output should be 0, to fix this I'm going to simply change the assertion line in the <code>daysBetweenDates</code> procedure.</p>
<p>Before:</p>
<pre><code class="lang-python"><span class="hljs-keyword">assert</span>(date1BeforeDate2(year1, month1, day1, year2, month2, day2))
</code></pre>
<p>After:</p>
<pre><code class="lang-python"><span class="hljs-keyword">assert</span> <span class="hljs-keyword">not</span> (date1BeforeDate2(year2, month2, day2, year1, month1, day1))
</code></pre>
<p>Now everything looks to be finished, it's time to do final testing to be confident our code it's working as expected, and in this case, it looks like we can consider our code done!.</p>
<h2 id="heading-finished-result">Finished Result</h2>
<p>Full python code:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">isLeapYear</span>(<span class="hljs-params">year</span>):</span>
    <span class="hljs-string">"""
    Function that receives a year and returns
    a boolean, True if the year is a leap year
    and False if it's not
    """</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">4</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">elif</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">100</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">elif</span> <span class="hljs-keyword">not</span> (year % <span class="hljs-number">400</span> == <span class="hljs-number">0</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysInMonth</span>(<span class="hljs-params">year, month</span>):</span>
    <span class="hljs-string">"""
    Function that receives a month and a year
    and based on that, it will return the number
    of days the specific month has, accounting for
    leap years.
    """</span>
    <span class="hljs-keyword">if</span> month <span class="hljs-keyword">in</span> (<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">10</span>, <span class="hljs-number">12</span>):
        <span class="hljs-keyword">return</span> <span class="hljs-number">31</span>
    <span class="hljs-keyword">elif</span> month == <span class="hljs-number">2</span>:
        <span class="hljs-keyword">if</span> isLeapYear(year):
            <span class="hljs-keyword">return</span> <span class="hljs-number">29</span>
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-number">28</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">30</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">nextDay</span>(<span class="hljs-params">year, month, day</span>):</span>
    <span class="hljs-string">"""
    The function receives a year, month, and day and returns
    the year, month, and day of the next day.
    """</span>
    <span class="hljs-keyword">if</span> day &lt; daysInMonth(year, month):
        <span class="hljs-keyword">return</span> year, month, day + <span class="hljs-number">1</span>
    <span class="hljs-keyword">elif</span> month &lt; <span class="hljs-number">12</span>:
        <span class="hljs-keyword">return</span> year, month + <span class="hljs-number">1</span>, <span class="hljs-number">1</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> year + <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">date1BeforeDate2</span>(<span class="hljs-params">year1, month1, day1, year2, month2, day2</span>):</span>
    <span class="hljs-string">"""
    The function receives two dates and returns a boolean, True
    if the first date is before the second, and False if it is not.
    """</span>
    <span class="hljs-keyword">if</span> year1 &lt; year2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">if</span> month1 &lt; month2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">if</span> day1 &lt; day2:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">daysBetweenDates</span>(<span class="hljs-params">year1, month1, day1, year2, month2, day2</span>):</span>
    <span class="hljs-string">"""
    returns the difference between two dates in days accounting for 
    leap years and no time travel.
    """</span>
    <span class="hljs-keyword">assert</span> <span class="hljs-keyword">not</span> (date1BeforeDate2(year2, month2, day2, year1, month1, day1))

    days = <span class="hljs-number">0</span>
    <span class="hljs-keyword">while</span> date1BeforeDate2(year1, month1, day1, year2, month2, day2):
        year1, month1, day1 = nextDay(year1, month1, day1)
        days += <span class="hljs-number">1</span>
    <span class="hljs-keyword">return</span> days


print(daysBetweenDates(<span class="hljs-number">2019</span>, <span class="hljs-number">5</span>, <span class="hljs-number">24</span>, <span class="hljs-number">2020</span>, <span class="hljs-number">5</span>, <span class="hljs-number">24</span>))
</code></pre>
<h2 id="heading-conclusion-farewell">Conclusion - Farewell</h2>
<p>You've reached the end of this lesson on problem-solving for programmers, remember that this is a skill that takes a lifetime to master so don't feel frustrated if you don't get it right away because this isn't easy, but I hope that some of the guidelines I've shared today can help you with any problem you might encounter in the future.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1636230302008/OtrX4zc5p.png" alt="how to solve problems.png" /></p>
<p>That's all for today guys, I really hope this was helpful, and let me know in the comments any thoughts, suggestions and I will see you in the next post, stay tuned!.</p>
]]></content:encoded></item><item><title><![CDATA[How To Add New Fonts To Figma]]></title><description><![CDATA[Introduction
Hello everyone, today's post is going to be a bit shorter than usual but it's a very important topic non the less, I want to talk about adding Fonts to Figma.
My Experience
Okay, so, when I was making a cover design in Figma I came up wi...]]></description><link>https://blog.garybricks.com/how-to-add-new-fonts-to-figma</link><guid isPermaLink="true">https://blog.garybricks.com/how-to-add-new-fonts-to-figma</guid><category><![CDATA[General Advice]]></category><category><![CDATA[Design]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[fonts]]></category><category><![CDATA[design principles]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Wed, 27 Oct 2021 03:41:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636231186541/y1zlORhT_.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Hello everyone, today's post is going to be a bit shorter than usual but it's a very important topic non the less, I want to talk about adding Fonts to Figma.</p>
<h2 id="my-experience">My Experience</h2>
<p>Okay, so, when I was making a cover design in Figma I came up with the really common pain of not finding the right font for my project, normally you can find LOT's of fonts to try your design with, but I wasn't finding the font I wanted,  <code>Sans Pro Display</code>, I was really surprised this font didn't come included in the really big Figma library, and for the first time ever I had to add a font to Figma, in the end, it wasn't complicated but it took me way longer than it should have and that's why I wanted to share this with you.</p>
<h2 id="adding-font-to-figma">Adding Font To Figma</h2>
<h3 id="step-1-finding-a-font">Step 1 - Finding a Font</h3>
<p>The first step is going to find your wanted font, in my case, I simply googled "Sans Pro Display free Font Download" and easily found it here: https://www.cufonfonts.com/font/sf-pro-display, make sure you are downloading from a secure website.</p>
<h3 id="step-2-downloading-font">Step 2 - Downloading Font</h3>
<p>Download your font and you should get a zip file, extract the elements from the zip file and you should get a folder with OpenType Font files like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635303500753/adpRgJyOe.png" alt="font-files.png" /></p>
<h3 id="step-3-starting-figma">Step 3 - Starting Figma</h3>
<p>Open your Figma project and if you select your desired text and go to ==&gt; Design ==&gt; Text and search for your newly downloaded Font you will realize that it cannot be found in the library.</p>
<h3 id="step-4-installing-font">Step 4 - Installing Font</h3>
<p>The reason why you can't find the font it's because it's not installed in your system yet.
To install the font you can simply double click the OpenType Font file and a screen like the one shown below should appear then you simply click on the install button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635304196174/8SO_-rFY3p.png" alt="install font.png" /></p>
<h3 id="step-5-restarting-figma">Step 5 - Restarting Figma</h3>
<p>This step is SUPER IMPORTANT and I really hoped someone would have told me to RESTART Figma, I lost a lot of time trying to figure out why the font was still not appearing and the solution was really simple, simply close the app and open again.</p>
<p>After restarting the app you should be able to select any text element, go to ==&gt; Design ==&gt; Text and search for the name of your font, Figma will likely auto-complete the search, and now we are ready to start using our new font.</p>
<h2 id="result-farewell">Result - Farewell</h2>
<p>In today's post, we learned how to add any font to Figma, I want to mention that this method is for the Desktop version only, and I really hope this post helps anyone that was looking to expand their font library, here it's the cover design I was working on:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635305195010/_7XEBjlAJ.png" alt="cover design.png" /></p>
<p>Comment below any thoughts, suggestions, and i will see you in the next post.</p>
]]></content:encoded></item><item><title><![CDATA[Host A Static Website With Firebase Hosting Service]]></title><description><![CDATA[Introduction
Hello everyone, in today's post I wanted to show you how to use the google cloud hosting service. using that service, we can host static web pages easily, free, and securely.
Why use Firebase Hosting?
Firebase hosting will provide you im...]]></description><link>https://blog.garybricks.com/host-a-static-website-with-firebase-hosting-service</link><guid isPermaLink="true">https://blog.garybricks.com/host-a-static-website-with-firebase-hosting-service</guid><category><![CDATA[Firebase]]></category><category><![CDATA[Web Hosting]]></category><category><![CDATA[hosting]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[google cloud]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Tue, 26 Oct 2021 03:35:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1636231083443/zADzoIpd5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="introduction">Introduction</h1>
<p>Hello everyone, in today's post I wanted to show you how to use the google cloud hosting service. using that service, we can host static web pages easily, free, and securely.</p>
<h2 id="why-use-firebase-hosting">Why use Firebase Hosting?</h2>
<p>Firebase hosting will provide you impressive good speed without the need for separate CDN and it's FREE, easy to use, and provides the SSL certificate so that your website will be hosted securely with HTTPS.</p>
<h2 id="requirements">Requirements</h2>
<ol>
<li>Google account for Firebase setup in console</li>
<li>Domain: you can purchase a domain from any provider</li>
<li>Firebase-CLI (installation process showed later in this post)</li>
</ol>
<h2 id="hosting-a-static-website">Hosting a static website</h2>
<h3 id="step-1-configure-firebase-project-on-firebase-console">Step 1 - Configure Firebase project on Firebase console</h3>
<p>Open   <a target="_blank" href="https://firebase.google.com/">Firebase Console</a>  ==&gt; Sign in with your Google account ==&gt; Create project ==&gt; Add title ==&gt; Enable Google analyitics for your country.<br />See the images below for guidance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635016408274/KWjSKB_pk.png" alt="get started firebase.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635017132736/op3HqZgWU.png" alt="welcome to firebase.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635017866518/yz__QTeEN.png" alt="create project step 1.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635018585093/RNEvpNyVu.png" alt="create a project step 2.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635018710703/bX34I1Pbn.png" alt="create a project step 3.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635018896865/QOiJFs1E5.png" alt="loading.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635019184826/d18qu3WPd.png" alt="dashboard.png" /></p>
<h3 id="step-2-install-firebase-cli-on-your-machine">Step 2 - Install Firebase-CLI on your machine</h3>
<p>Simply execute the following command:</p>
<pre><code><span class="hljs-built_in">npm</span> install -g firebase-tools
</code></pre><p>or you can use:</p>
<pre><code>yarn <span class="hljs-keyword">global</span> <span class="hljs-keyword">add</span> firebase-tools
</code></pre><h3 id="step-3-configuration-of-firebase-cli-on-the-local-machine">Step 3 - Configuration of Firebase-CLI on the local machine</h3>
<ol>
<li>Create a new folder on your computer</li>
<li>Open a new CMD(command prompt) and cd into the newly created folder</li>
<li>Now execute the command: </li>
</ol>
<pre><code>firebase <span class="hljs-keyword">login</span>
</code></pre><p>This will redirect you to the sign-in page in the browser, where you just need to simply sign in.</p>
<p>After successfully given access, you should get the below message on the browser</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635020783689/Au_5P1Htj.png" alt="succes message.png" /></p>
<h3 id="step-4-initialize-project">Step 4 - Initialize project</h3>
<p>On your command prompt, simply execute the following command:</p>
<pre><code>firebase <span class="hljs-keyword">init</span>
</code></pre><p>After executing this command you should see the following screen:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635022452108/sSxE0jlwsb.png" alt="firebase init.png" /></p>
<p>After pressing enter to the question </p>
<blockquote>
<p>are you ready to proceed? </p>
</blockquote>
<p>you should select the option:</p>
<blockquote>
<p>Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys</p>
</blockquote>
<p>Use arrows to change selection and select using the <code>spacebar</code>, then press <code>enter</code>.</p>
<p>Once the Hosting option is selected, they'll provide the option to choose an existing project or create a new one. As we have already created a sample static project, you need to just choose the existing option and press <code>enter</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635023831534/-bcIzYGbN.png" alt="project setup.png" />
After pressing <code>enter</code> you should see your Firebase project, select it, and press <code>enter</code>.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635028167660/gzyrkTi1Y.png" alt="hosting setup.png" />
Then it will ask you for a name for the public directory, you can put the same name as your project, and after pressing <code>enter</code> the following question should appear</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635029082323/mVahrGvFd.png" alt="configure single page.png" /></p>
<p>If your page is a single page like mine you should answer yes.</p>
<h3 id="step-5-publish-website-on-localhost5000">Step 5 - Publish website on LocalHost:5000</h3>
<p>After we are done with the configuration we need to run the following command: </p>
<pre><code><span class="hljs-attribute">firebase</span> serve
</code></pre><p>If we followed all of the steps correctly, in the folder created at the beginning we will find another folder and inside an index.html file that will be shown on <code>localhost:5000</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635031109256/jnzesPhI1.png" alt="firebase serve.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635053217978/YvzkIUpER.png" alt="localhost5000.png" />
After watching the screen above without showing problems then we can exit with <code>Ctrl+C</code></p>
<h3 id="step-6-adding-our-files">Step 6 - Adding our files</h3>
<p>We're almost done!, now it's time to delete the index.html file and replace it with our wanted index.html, index.css, images, and icon files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635182349765/VgdQuvTX-.png" alt="files.png" />
Back at the CMD terminal we can repeat step 5 and now we should see our website on <code>localhost:5000</code>, it's likely that we see the old file instead of the new one so to fix that make sure to refresh the browser with <code>Ctrl+Shift+R</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635182963270/hBcfiUscr4.png" alt="localhost5000_kitchen_website.png" /></p>
<h3 id="step-7-deploy-on-the-firebase-server">Step 7 - Deploy on the Firebase server</h3>
<p>After making sure everything works properly on <code>localhost:5000</code>, we can now exit and proceed with the deploy</p>
<pre><code><span class="hljs-attribute">firebase</span> deploy
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635185267612/LnwY5HiAp.png" alt="firebase deploy.png" />
As we can see from the image above, after the deploy it's complete, we should get a Hosting URL, if we paste that into our web browser we should see our website.</p>
<p>We are Done!</p>
<h3 id="step-8-add-costume-domain">Step 8 - Add Costume Domain</h3>
<p>In the likely case that you don't want your website URL to look like this: https://sample-9f6cf.web.app/ and want to use a custom domain instead, we can do just that from the Project dashboard, just follow the images below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635195071212/YA7N7yfJI.png" alt="project dashboard.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635195895621/KFMI_Okr3.jpeg" alt="Inkedproject hosting_LI.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635196714243/WCSpUrhWp.png" alt="link domain steps.png" /></p>
<p>In my case, I already had a domain from https://domains.google/ and after following the three steps from the image above we should get a register type, host, and value (image below).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635198678244/tm7WmuC7-.png" alt="step 3.png" /></p>
<p>Now we need to go to Google Domains ==&gt; Select your domain ==&gt;DNS ==&gt; Manage custom records ==&gt; Create new record and enter the values there ==&gt; Save.
See the images below for guidance.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635217592586/E6biMoSxi.jpeg" alt="InkedgoogleDomains_LI.jpg" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635218133732/doVN8QcdN.png" alt="new record.png" /></p>
<p>Now we should wait some time, normally it's a few minutes, and after that, we are done hosting our website with firebase!.</p>
<h2 id="farewell">Farewell</h2>
<p>I really hope this post has taught you how to host your website with Firebase and if you have any suggestions or ideas, let me know in the comments below, see you in the next post!.</p>
]]></content:encoded></item><item><title><![CDATA[Control 16 servos with Raspberry Pi + PCA9685 Driver]]></title><description><![CDATA[Hello everyone, I recently wanted to build a cool robot, and to do so, I needed to control 8 servos using the PCA9685 driver and thought I shared my experience with anyone interested in this topic.
To do this you will need:

Raspberry Pi (mine is the...]]></description><link>https://blog.garybricks.com/control-16-servos-with-raspberry-pi-pca9685-driver</link><guid isPermaLink="true">https://blog.garybricks.com/control-16-servos-with-raspberry-pi-pca9685-driver</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python projects]]></category><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[robotics]]></category><dc:creator><![CDATA[Gary Vladimir Núñez López]]></dc:creator><pubDate>Thu, 07 Oct 2021 18:54:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1633632430551/OuzP28ycS.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone, I recently wanted to build a cool robot, and to do so, I needed to control 8 servos using the <code>PCA9685</code> driver and thought I shared my experience with anyone interested in this topic.</p>
<h2 id="to-do-this-you-will-need">To do this you will need:</h2>
<ol>
<li>Raspberry Pi (mine is the 3B+)</li>
<li>PCA9685 driver</li>
<li>Servos (the driver supports up to 16)</li>
<li>4 female to female jumper cables.</li>
<li>External 5v power for the driver</li>
<li>Python3</li>
</ol>
<h2 id="connection">Connection</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633556132613/Pev6mGSGX.png" alt="connection.png" />
5v-6v recommended power and you can connect as many servos as you like</p>
<h2 id="coding-with-python3">coding with python3</h2>
<p>Turn on your Raspberry Pi and open a new terminal, then run the following commands:</p>
<pre><code>sudo apt-get <span class="hljs-keyword">install</span> git <span class="hljs-keyword">build</span>-essential python-dev
git <span class="hljs-keyword">clone</span> https://github.com/adafruit/Adafruit_Python_PCA9685.git
cd Adafruit_Python_PCA9685
sudo python setup.py <span class="hljs-keyword">install</span>
cd examples
</code></pre><p>Inside the examples folder, you should find the <code>simplest.py</code> example code, to run it use the command </p>
<p><code>python3 simplest.py</code></p>
<p>However, if we execute this program we get an error</p>
<blockquote>
<p>No such file or directory: '/dev/i2c-1'</p>
</blockquote>
<p>To fix this we need to open the raspberry pi software configuration</p>
<p><code>sudo raspi-config</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633571528097/DYMdnvc84.png" alt="2021-10-06-194915_1024x768_scrot.png" /></p>
<p>Use the down arrow to select interfacing options and press enter, then select P5 I2C and enable the interface ==&gt; ok ==&gt; finish.</p>
<p>Now, if we execute the <code>simplest.py</code> file we shouldn't get any errors and our servo should start moving, Nice!, however the code it's unnecessarily complex for what I need. I would like to call a function that passes the target degree as a parameter and nothing else, this way the code would be easier to read and with fewer bugs, to accomplish this I'm going to use the Adafruit Servo Kit library for python</p>
<p>https://github.com/adafruit/Adafruit_CircuitPython_ServoKit</p>
<p>To use this library, open a new terminal on your Raspberry Pi and execute the following command:
<code>pip3 install adafruit-circuitpython-servokit</code></p>
<h2 id="usage-example">Usage example</h2>
<p>Here we can see a full example:</p>
<pre><code><span class="hljs-attribute">from</span> time import sleep
<span class="hljs-attribute">from</span> adafruit_servokit import ServoKit

<span class="hljs-comment"># Set channels to the number of servo channels on your kit.</span>
<span class="hljs-comment"># 8 for FeatherWing, 16 for Shield/HAT/Bonnet.</span>
<span class="hljs-attribute">kit</span> = ServoKit(channels=<span class="hljs-number">8</span>)

<span class="hljs-attribute">kit</span>.servo[<span class="hljs-number">0</span>].angle = <span class="hljs-number">175</span>
<span class="hljs-attribute">sleep</span>(<span class="hljs-number">1</span>)
<span class="hljs-attribute">kit</span>.servo[<span class="hljs-number">0</span>].angle = <span class="hljs-number">45</span>
<span class="hljs-attribute">sleep</span>(<span class="hljs-number">1</span>)
</code></pre><p>We can specify the servo in the<code>kit.servo[0-15].</code></p>
<h2 id="result">Result</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633632215738/cwBnDf2JL.jpeg" alt="resultServos.jpg" /></p>
<p>I really hope this post helped you out and feel free to share this with someone that might need it, see you next time!.</p>
]]></content:encoded></item></channel></rss>