<?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[Luiz Celso Pergentino]]></title><description><![CDATA[Just a guy who believes that the world can be changed through computer code.]]></description><link>https://luizcelso.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 15:15:02 GMT</lastBuildDate><atom:link href="https://luizcelso.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Frequency Counter Pattern]]></title><description><![CDATA[Frequency Counter is one of the most frequent patterns in programming - if not the most. You will certainly use it in your side projects and work.
Let's use the classic anagram problem.
Anagram is a word/phrase created by rearranging the letter of an...]]></description><link>https://luizcelso.com/frequency-counter-pattern</link><guid isPermaLink="true">https://luizcelso.com/frequency-counter-pattern</guid><category><![CDATA[anagram]]></category><category><![CDATA[frequency counter]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[datastructure]]></category><category><![CDATA[back2school]]></category><dc:creator><![CDATA[Luiz Celso Pergentino]]></dc:creator><pubDate>Tue, 26 Nov 2024 13:45:13 GMT</pubDate><content:encoded><![CDATA[<p>Frequency Counter is one of the most <em>frequent</em> patterns in programming - if not the most. You will certainly use it in your side projects and work.</p>
<p>Let's use the classic anagram problem.</p>
<p><em>Anagram is a word/phrase created by rearranging the letter of another word/phrase. E.g., cat becomes act.</em></p>
<p>Instinctively, many devs write something like the following:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAnagram</span>(<span class="hljs-params">str1, str2</span>) </span>{
  <span class="hljs-keyword">if</span> (str1.length !== str2.length) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; str1.length; i++) {
    <span class="hljs-keyword">let</span> found = <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j &lt; str2.length; j++) {
      <span class="hljs-keyword">if</span> (str1[i] === str2[j]) {
        found = <span class="hljs-literal">true</span>;
        <span class="hljs-keyword">break</span>;
      }
    }

    <span class="hljs-keyword">if</span> (!found) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>We have big problems here:</p>
<ul>
<li><p>Nested loops: quadratic complexity - O(n²).</p>
</li>
<li><p>The char frequency is not verified, making the solution inaccurate.</p>
</li>
</ul>
<p>Instead, we can use the frequency pattern to know the occurrences for each char by just using Objects.</p>
<p>Here's the solution:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAnagram</span>(<span class="hljs-params">str1, str2</span>) </span>{
    <span class="hljs-keyword">if</span> (str1.length !== str2.length) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-keyword">let</span> frequencyObject1 = {};
    <span class="hljs-keyword">let</span> frequencyObject2 = {};

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; str1.length; i++) {
        frequencyObject1[str1[i]] = (frequencyObject1[str1[i]] || <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>;
    }

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; str2.length; i++) {
        frequencyObject2[str2[i]] = (frequencyObject2[str2[i]] || <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>;
    }

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">in</span> frequencyObject1) {
        <span class="hljs-keyword">if</span> (!(key <span class="hljs-keyword">in</span> frequencyObject2)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        <span class="hljs-keyword">if</span> (frequencyObject1[key] !== frequencyObject2[key]) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>Now, we have a better solution with a linear complexity - O(n).</p>
]]></content:encoded></item><item><title><![CDATA[Multiple Pointers Pattern]]></title><description><![CDATA[Before delving into classic algorithms and data structures, we must learn or revisit some problem-solving patterns. The Multiple Pointers pattern will be our starting point.
The main idea here is to create multiple pointers attached to specific posit...]]></description><link>https://luizcelso.com/multiple-pointers-pattern</link><guid isPermaLink="true">https://luizcelso.com/multiple-pointers-pattern</guid><category><![CDATA[multiplepointers]]></category><category><![CDATA[back2school]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[datastructure]]></category><dc:creator><![CDATA[Luiz Celso Pergentino]]></dc:creator><pubDate>Mon, 18 Nov 2024 23:29:13 GMT</pubDate><content:encoded><![CDATA[<p>Before delving into classic algorithms and data structures, we must learn or revisit some problem-solving patterns. The Multiple Pointers pattern will be our starting point.</p>
<p>The main idea here is to create multiple pointers attached to specific positions and move them based on a particular condition.</p>
<p>You can find Multiple Pointers In countless algorithms, like:</p>
<ul>
<li><p>Binary Search</p>
</li>
<li><p>Quick Sort</p>
</li>
<li><p>Merge Sort</p>
</li>
<li><p>Etc.</p>
</li>
</ul>
<p>Let's imagine we need to write a function that finds the first pair where the sum is 0 from a given SORTED array. <code>E.g., [-5, -1, 0, 2, 5] //-5 + 5</code></p>
<p>Instinctively, we write something like the following:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pairSum</span>(<span class="hljs-params">arr</span>) </span>{
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; arr.length; i++) {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j &lt; arr.length; j++) {
            <span class="hljs-keyword">if</span> (arr[i] + arr[j] === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${arr[i]}</span> + <span class="hljs-subst">${arr[j]}</span>`</span>;
        }
    }
}
</code></pre>
<p>The big problem here is that our time complexity is quadratic O(n^2) because we walk through the array twice. But, we can solve it by using Multiple Pointers to walk through the array only once:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pairSum</span>(<span class="hljs-params">arr</span>) </span>{
  <span class="hljs-keyword">let</span> left = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> right = arr.length - <span class="hljs-number">1</span>;

  <span class="hljs-keyword">while</span> (left &lt; right) {
    <span class="hljs-keyword">const</span> sum = arr[left] + arr[right];
    <span class="hljs-keyword">if</span> (sum === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${arr[left]}</span> + <span class="hljs-subst">${arr[right]}</span>`</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (sum &lt; <span class="hljs-number">0</span>)   
 {
      left++;
    } <span class="hljs-keyword">else</span> {
      right--;
    }
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
</code></pre>
<p>Now, we have a linear time complexity O(n).</p>
<p>Let's get deeper into the above solution:</p>
<ul>
<li><p>We set up two pointers: <code>left</code> with the initial position and <code>right</code> with the last position.</p>
</li>
<li><p>The loop will be running until <code>left &lt; right</code>.</p>
</li>
<li><p>We store the first sum.</p>
</li>
<li><p>If <code>sum === 0</code>, we found our pair.</p>
</li>
<li><p>If not and <code>sum &lt; 0</code>, we will move our <code>left</code> pointer to the right by incrementing it.</p>
</li>
<li><p>If <code>sum &gt; 0</code>, move the <code>right</code> pointer to the left by decrementing it.</p>
</li>
<li><p>If nothing was found, return <code>null</code>.</p>
</li>
</ul>
<p>Let's suppose we have the following SORTED array:</p>
<p><code>[-6, -5, -1, 0, 2, 3, 4, 5, 10]</code></p>
<pre><code class="lang-jsx"><span class="hljs-number">1.</span>
[<span class="hljs-number">-6</span>, <span class="hljs-number">-5</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0</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">10</span>]
  ^                          ^
 left                      right

 sum = <span class="hljs-number">-6</span> + <span class="hljs-number">10</span> = <span class="hljs-number">4</span>

 As <span class="hljs-number">4</span> &gt; <span class="hljs-number">0</span>, we move our right pointer to the left

 [<span class="hljs-number">-6</span>, <span class="hljs-number">-5</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0</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">10</span>]
   ^                      ^
 left                   right

 sum = <span class="hljs-number">-6</span> + <span class="hljs-number">5</span> = <span class="hljs-number">-1</span>

 <span class="hljs-number">-1</span> &lt; <span class="hljs-number">0</span>, we move the left pointer to the right

 [<span class="hljs-number">-6</span>, <span class="hljs-number">-5</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0</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">10</span>]
       ^                  ^
      left              right

sum = <span class="hljs-number">-5</span> + <span class="hljs-number">5</span> = <span class="hljs-number">0</span>

Pair found: <span class="hljs-number">-5</span>, <span class="hljs-number">5.</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Recursion]]></title><description><![CDATA[Recursion is basically a process that calls itself until it reaches the finish condition.
Here's a factorial algorithm as an example:
function factorial(num) {
// End of the recursion
if (num === 1) return num;
// Calls itself decreasing the input by...]]></description><link>https://luizcelso.com/recursion</link><guid isPermaLink="true">https://luizcelso.com/recursion</guid><category><![CDATA[back2school]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[datastructure]]></category><category><![CDATA[Recursion]]></category><dc:creator><![CDATA[Luiz Celso Pergentino]]></dc:creator><pubDate>Tue, 24 Sep 2024 19:54:09 GMT</pubDate><content:encoded><![CDATA[<p>Recursion is basically a process that calls itself until it reaches the finish condition.</p>
<p>Here's a factorial algorithm as an example:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">factorial</span>(<span class="hljs-params">num</span>) </span>{
<span class="hljs-comment">// End of the recursion</span>
<span class="hljs-keyword">if</span> (num === <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> num;
<span class="hljs-comment">// Calls itself decreasing the input by 1</span>
<span class="hljs-keyword">return</span> num * factorial(num - <span class="hljs-number">1</span>);
}
</code></pre>
<p><em>\</em>You can generate a stack overflow here by just using any number smaller than 1*</p>
<p>The processes are stored in a structure called a call stack, which pushes the processes—calls—into the stack and pops them when they are finished.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727206741547/cf5bd08c-0c14-4ed7-9667-3ead28432c08.png" alt class="image--center mx-auto" /></p>
<p>All recursion algorithms should have the following:</p>
<ul>
<li><p>Return something to get out of the stack</p>
</li>
<li><p>A condition that ends the recursion (base case)</p>
</li>
<li><p>A code that changes the input (e.g., incrementing the input)</p>
</li>
</ul>
<p>Benefits:</p>
<ul>
<li><p>Readability of the code</p>
</li>
<li><p>Elegant solution</p>
</li>
<li><p>Breakdown the problem into smaller pieces (divide-and-conquer problem approach)</p>
</li>
</ul>
<p>Drawbacks:</p>
<ul>
<li><p>Performance problems with deeply nested calls</p>
</li>
<li><p>Stack overflow (no base case, no return or returning wrong thing)</p>
</li>
<li><p>In some cases, more inefficient than iterate solutions (loops)</p>
</li>
</ul>
<p>Where we find recursion in JS:</p>
<ul>
<li><p>JSON.parse() / JSON.stringfy()</p>
</li>
<li><p>DOM traversal algorithms</p>
</li>
<li><p>Object traversal algorithms</p>
</li>
</ul>
<p>More deeply into call stack:</p>
<ul>
<li><p>The maximum size depends on the system and browsers (Chrome around 10-20k calls, Node.js around 100k calls)</p>
</li>
<li><p>In node, you can set the maximum call stack size by calling <code>node --stack-size=Xmb</code></p>
</li>
<li><p>To calculate the approximate space consumed by a function call: <code>stack_size = sizeof(arguments) + sizeof(local_variables) + sizeof(return_value) + sizeof(context)</code></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Back2School Series]]></title><description><![CDATA[A few days ago, I was thinking about contributing to the community and decided to revisit some algorithms and data structure fundamentals and share my journey with you all. So, get ready for some short and to-the-point posts.]]></description><link>https://luizcelso.com/back2school-series</link><guid isPermaLink="true">https://luizcelso.com/back2school-series</guid><category><![CDATA[back2school]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[datastructure]]></category><dc:creator><![CDATA[Luiz Celso Pergentino]]></dc:creator><pubDate>Tue, 24 Sep 2024 19:17:22 GMT</pubDate><content:encoded><![CDATA[<p>A few days ago, I was thinking about contributing to the community and decided to revisit some algorithms and data structure fundamentals and share my journey with you all. So, get ready for some short and to-the-point posts.</p>
]]></content:encoded></item><item><title><![CDATA[A quick tip: Fix for ProductNotSupportedError: The client noticed that the server is not a supported distribution of Elasticsearch]]></title><description><![CDATA[In January 2021, Elastic, which owns Elasticsearch, changed its license to SSPL (Server Side Public License) due to a conflict with Cloud Services (mainly AWS).
Because of that, a lot of developers are facing the error message:
ProductNotSupportedErr...]]></description><link>https://luizcelso.com/a-quick-tip-fix-for-productnotsupportederror-the-client-noticed-that-the-server-is-not-a-supported-distribution-of-elasticsearch</link><guid isPermaLink="true">https://luizcelso.com/a-quick-tip-fix-for-productnotsupportederror-the-client-noticed-that-the-server-is-not-a-supported-distribution-of-elasticsearch</guid><category><![CDATA[Node.js]]></category><category><![CDATA[elasticsearch]]></category><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Luiz Celso Pergentino]]></dc:creator><pubDate>Wed, 05 Jan 2022 21:08:19 GMT</pubDate><content:encoded><![CDATA[<p>In January 2021, Elastic, which owns Elasticsearch, <a target="_blank" href="https://www.elastic.co/pt/blog/licensing-change">changed its license to SSPL</a> (Server Side Public License) due to a conflict with Cloud Services (mainly <a target="_blank" href="https://www.geekwire.com/2021/dispute-elastic-aws-highlights-ongoing-battle-open-source-business-model/">AWS</a>).</p>
<p>Because of that, a lot of developers are facing the error message:</p>
<pre><code class="lang-console">ProductNotSupportedError: The client noticed that the server is not a supported distribution of Elasticsearch
</code></pre>
<p>If you use the official Node.js client for Elasticsearch, <a target="_blank" href="https://github.com/elastic/elasticsearch-js">elasticsearch-js</a>, I recommend you downgrade the module version to version 7.12.0.</p>
<p>Example in a package.json file:</p>
<pre><code><span class="hljs-string">"@elastic/elasticsearch"</span>: <span class="hljs-string">"~7.12.0"</span>
</code></pre><p>Best,
Luiz Celso</p>
]]></content:encoded></item></channel></rss>