<?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[James Clark's Blog]]></title><description><![CDATA[Writer of code, words and things that live on the web. eTransportation, renewable energy, Mac user, JavaScript, Node.js, JAMStack enthusiast. Editor]]></description><link>https://blog.jeclark.co.uk</link><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Apr 2026 23:47:10 GMT</lastBuildDate><atom:link href="https://blog.jeclark.co.uk/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Problem-solving with ChatGPT]]></title><description><![CDATA[Every Monday morning, a new issue of rendezvous with cassidoo drops into my inbox in which the talented Cassidy Williams shares a brief roundup of what's new and cool in the world of web development. If you don't already receive it, I suggest taking ...]]></description><link>https://blog.jeclark.co.uk/problem-solving-with-chatgpt</link><guid isPermaLink="true">https://blog.jeclark.co.uk/problem-solving-with-chatgpt</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[chatgpt]]></category><dc:creator><![CDATA[James Clark]]></dc:creator><pubDate>Mon, 06 Mar 2023 03:06:49 GMT</pubDate><content:encoded><![CDATA[<p>Every Monday morning, a new issue of rendezvous with cassidoo drops into my inbox in which the talented <a target="_blank" href="https://cassidoo.co">Cassidy Williams</a> shares a brief roundup of what's new and cool in the world of web development. If you don't already receive it, I suggest <a target="_blank" href="https://cassidoo.co/newsletter/">taking a look here.</a> Cassidy also includes an interview question of the week which, time permitting, I like to complete.</p>
<p>This week's question was "<strong>Given a list of numbers, return all groups of repeating consecutive numbers."</strong> and was accompanied by a couple of examples:</p>
<pre><code class="lang-javascript">&gt; repeatedGroups([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>])
[[<span class="hljs-number">2</span>, <span class="hljs-number">2</span>]]

&gt; repeatedGroups([<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">8</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">9</span>, <span class="hljs-number">9</span>])
[[<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">4</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>], [<span class="hljs-number">9</span>, <span class="hljs-number">9</span>]]
</code></pre>
<p>Initially, I thought this is nice and easy. I'll use the array <code>reduce()</code> and <code>filter()</code> methods. However, my mind went blank and, after scratching my head for a few minutes, I needed to consider a different approach. Options included:</p>
<ul>
<li><p>Googling the question and finding something similar on Stack Overflow or Reddit</p>
</li>
<li><p>Changing tack and taking a different approach to finding a solution. Maybe I could refactor it to use the array methods later?</p>
</li>
<li><p>Asking ChatGPT to solve the problem</p>
</li>
</ul>
<p>Wanting to produce my own solution I started by changing tack, using a <code>for</code> loop and some <code>if</code> statements:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">repeatedGroups</span>(<span class="hljs-params">nums</span>) </span>{
  <span class="hljs-keyword">let</span> output = [];
  <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; nums.length; i++) {
    <span class="hljs-keyword">if</span> (nums[i] === nums[i + <span class="hljs-number">1</span>]) {
      count++;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">if</span> (count &gt; <span class="hljs-number">0</span>) {
        output.push(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(count + <span class="hljs-number">1</span>).fill(nums[i]));
        count = <span class="hljs-number">0</span>;
      }
    }
  }
  <span class="hljs-keyword">return</span> output;
}
</code></pre>
<p>It works but I wasn't 100% happy with it:</p>
<ul>
<li><p>For the final iteration of <code>i</code>, <code>i+1</code> doesn't exist. <code>nums[i] === nums[i + 1]</code> still resolves to <code>false</code> so it works but it feels a bit messy. It works accidentally rather than intentionally.</p>
</li>
<li><p>I read in a blog post once that it's not good practice to use <code>else</code>. I think this was mostly referring to long <code>if ... else if ...</code> chains but still, could it be improved?</p>
</li>
<li><p>While it's quite easy to understand and follow the code, it feels unnecessarily verbose.</p>
</li>
<li><p>It doesn't use the array <code>reduce()</code> and <code>filter()</code> methods I wanted to use.</p>
</li>
</ul>
<p>So I refactored a little:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">repeatedGroups</span>(<span class="hljs-params">nums</span>) </span>{
  <span class="hljs-keyword">let</span> output = [];
  <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
  nums.forEach(<span class="hljs-function">(<span class="hljs-params">num, i, fullArr</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (num === fullArr[i + <span class="hljs-number">1</span>]) {
      count++;
    }
    <span class="hljs-keyword">if</span> (count &gt; <span class="hljs-number">0</span> &amp;&amp; num !== fullArr[i + <span class="hljs-number">1</span>]) {
      output.push(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(count + <span class="hljs-number">1</span>).fill(nums[i]));
      count = <span class="hljs-number">0</span>;
    }
  });
  <span class="hljs-keyword">return</span> output;
}
</code></pre>
<p>This solution improved things a little:</p>
<ul>
<li><p>It still doesn't use the array <code>reduce()</code> and <code>filter()</code> methods but I have replaced the <code>for</code> loop with a <code>forEach()</code> array method.</p>
</li>
<li><p>I've removed the <code>else</code> statement. Is this an improvement? Yes, I do think it is. Not only does it lose the <code>if</code> nested within the <code>else</code>, but it makes the code more intentional. Rather than doing something that fails the first <code>if</code> statement, I'm explicitly doing these things if the two conditions are met.</p>
</li>
<li><p>In terms of self-documenting code, this is better than the first attempt.</p>
</li>
</ul>
<p>I noted that I was doing the same check, whether the current number was equal to the next number, twice. So thought about refactoring the code to do this only once:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">repeatedGroups</span>(<span class="hljs-params">nums</span>) </span>{
  <span class="hljs-keyword">let</span> output = [];
  <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
  nums.forEach(<span class="hljs-function">(<span class="hljs-params">num, i, fullArr</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (num === fullArr[i + <span class="hljs-number">1</span>]) {
      <span class="hljs-keyword">case</span> <span class="hljs-literal">true</span>:
        count++;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-literal">false</span>:
        <span class="hljs-keyword">if</span> (count &gt; <span class="hljs-number">0</span>) {
          output.push(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(count + <span class="hljs-number">1</span>).fill(nums[i]));
          count = <span class="hljs-number">0</span>;
        }
    }
  });
  <span class="hljs-keyword">return</span> output;
}
</code></pre>
<p>Again, it works, it only does the repeated number check once and is quite readable, but I don't feel it improves the previous solution. My second attempt was my preferred solution.</p>
<h2 id="heading-now-i-have-my-solution-what-does-chatgpt-say">Now I have my solution, what does ChatGPT say?</h2>
<p>Since ChatGPT rose to prominence I have been enjoying trying out its code-writing skills. So, once I've come up with my solution, I like to see how ChatGPT gets on with the same challenge. Here's the prompt I gave it:</p>
<blockquote>
<p>In JavaScript, write a function that given a list of numbers as an array, return all groups of repeating consecutive numbers.</p>
</blockquote>
<p>It's not great English but it has all the essential keywords to get a successful result. Here's what it wrote:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getConsecutiveGroups</span>(<span class="hljs-params">numbers</span>) </span>{
  <span class="hljs-keyword">let</span> groups = [];
  <span class="hljs-keyword">let</span> currentGroup = [];

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; numbers.length; i++) {
    <span class="hljs-keyword">if</span> (currentGroup.length === <span class="hljs-number">0</span> || numbers[i] === currentGroup[currentGroup.length - <span class="hljs-number">1</span>]) {
      currentGroup.push(numbers[i]);
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">if</span> (currentGroup.length &gt; <span class="hljs-number">1</span>) {
        groups.push(currentGroup);
      }
      currentGroup = [numbers[i]];
    }
  }

  <span class="hljs-keyword">if</span> (currentGroup.length &gt; <span class="hljs-number">1</span>) {
    groups.push(currentGroup);
  }

  <span class="hljs-keyword">return</span> groups;
}
</code></pre>
<p>It works and I was quite surprised. Not surprised that it worked, but that it came up with something similar to my original solution. I was expecting something clever, something that did the whole thing in two lines of code. However, it's using a <code>for</code> loop and nesting an <code>if</code> statement inside an <code>else</code> statement, as I did initially. Perhaps my solution wasn't so bad. ChatGPT has validated my initial attempt and shown me that my solution was perfectly valid.</p>
<p>In no time it had provided a working solution. I prefer my second solution but it shows the impressive capabilities of ChatGPT. However, I find the greatest value of ChatGPT, is when you know 90% where you want to go and can guide it towards that ultimate goal. So, I followed up with the following prompt:</p>
<blockquote>
<p>Can this be simplified with ES6 array functions?</p>
</blockquote>
<p>And sure enough, here's the code it came back with:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getConsecutiveGroups</span>(<span class="hljs-params">numbers</span>) </span>{
  <span class="hljs-keyword">return</span> numbers.reduce(<span class="hljs-function">(<span class="hljs-params">acc, cur, index, arr</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (index === <span class="hljs-number">0</span> || cur !== arr[index - <span class="hljs-number">1</span>]) {
      acc.push([]);
    }
    acc[acc.length - <span class="hljs-number">1</span>].push(cur);
    <span class="hljs-keyword">return</span> acc;
  }, [])
    .filter(<span class="hljs-function"><span class="hljs-params">group</span> =&gt;</span> group.length &gt; <span class="hljs-number">1</span>);
}
</code></pre>
<p>Bingo! Once again, the code works. Now we have the array <code>reduce()</code> and <code>filter()</code> methods I wanted to use from the start. With hindsight, it's so simple I don't know why my mind went blank and I didn't come up with it myself. I like using array methods so in my opinion this is the best solution and it is nice and readable to follow what it is doing.</p>
<p>So my top solution for this week's challenge, courtesy of ChatGPT, is:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">repeatedGroups</span>(<span class="hljs-params">nums</span>) </span>{
  <span class="hljs-keyword">return</span> nums
    .reduce(<span class="hljs-function">(<span class="hljs-params">acc, cur, ind, arr</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (ind === <span class="hljs-number">0</span> || cur !== arr[ind - <span class="hljs-number">1</span>]) acc.push([]);
      acc[acc.length - <span class="hljs-number">1</span>].push(cur);
      <span class="hljs-keyword">return</span> acc;
    }, [])
    .filter(<span class="hljs-function">(<span class="hljs-params">groups</span>) =&gt;</span> groups.length &gt; <span class="hljs-number">1</span>);
}
</code></pre>
<p>It's intentional, readable and spans just 9 lines. Rather than wasting time struggling to find the solution I was looking for, ChatGPT got me to the solution I wanted in very little time but along the way, it also showed me that my 14-line solution was perfectly valid.</p>
<p>This, I think, is one of ChatGPT's strengths. ChatGPT, whilst being totally confident in everything it says, is not totally correct. It would be dangerous for someone with no coding knowledge at all to use it to develop code for them. But for someone with some knowledge, you can work with ChatGPT to improve your productivity and quickly iterate to a good solution. ChatGPT definitely provided a quicker and more tailored answer to my question than I would have gotten by reading through posts on Stack Overflow and Reddit.</p>
]]></content:encoded></item></channel></rss>