{"id":187,"date":"2020-07-03T23:35:26","date_gmt":"2020-07-03T23:35:26","guid":{"rendered":"http:\/\/96.126.106.214\/?p=187"},"modified":"2023-11-26T01:01:43","modified_gmt":"2023-11-26T01:01:43","slug":"thinking-about-algorithmic-problems-ii","status":"publish","type":"post","link":"https:\/\/codingismycraft.blog\/index.php\/2020\/07\/03\/thinking-about-algorithmic-problems-ii\/","title":{"rendered":"Thinking about Algorithmic problems II"},"content":{"rendered":"<p>Solving a programming problem that requires a custom algorithm can be broken in several steps which can be summarized in the creation of testing data, the implementation of a brutal force solution and the deeper study of the particular case which might reveal a smart trick to achieve an efficient solution.<\/p>\n<p>In this posting we follow this approach applied to a problem that seems hard but after some thinking becomes very obvious and easy to solve.<\/p>\n<h2>The problem<\/h2>\n<p>Lets assume that we have an electronic device that in one unit of time can send a request and receive a response from a server; the possible responses are as follows:<\/p>\n<ul>\n<li>S: Success<\/li>\n<li>C: Corrupted data<\/li>\n<li>F: Failure to connect<\/li>\n<\/ul>\n<p>Assuming 2 units of time the sequence our possible responses are as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1626\" src=\"\/wp-content\/uploads\/2017\/04\/sig-1.gif\" alt=\"sig-1\" width=\"282\" height=\"135\" \/><\/p>\n<p>The software that controls our device will automatically stop in any one of the\u00a0 following conditions:<\/p>\n<ul>\n<li>Received two Failures at any time<\/li>\n<li>Received three consecutive corrupted data<\/li>\n<\/ul>\n<p>Based on this definition the sequence for 2 units of time the possible valid signals are 8 :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1629\" src=\"\/wp-content\/uploads\/2017\/04\/sig-2.gif\" alt=\"sig-2\" width=\"286\" height=\"144\" \/><\/p>\n<p>(Note that the FF sequence has been dropped)<\/p>\n<p>To make our requirement cleaner assuming 3 units of time the sequence of valid signals (19) will be the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1631\" src=\"\/wp-content\/uploads\/2017\/04\/sig-3.png\" alt=\"sig-3\" width=\"300\" height=\"315\" \/><\/p>\n<p>Note that the following 8 signals are dropped:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1633\" src=\"\/wp-content\/uploads\/2017\/04\/sig-4.png\" alt=\"sig-4\" width=\"290\" height=\"139\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Our problem is the following:<\/p>\n<p><em><strong>For a given number of units of time calculate the count of all possible valid sequences of signals<\/strong><\/em><\/p>\n<h2>The Brutal Solution<\/h2>\n<p>At this point you should pause and re-read the definition of the problem and try to digest it.<\/p>\n<p>We already have the following test data:<\/p>\n<table>\n<tbody>\n<tr>\n<th>Units of time<\/th>\n<th>Number of sequences<\/th>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">1<\/td>\n<td style=\"text-align: center;\">3<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">2<\/td>\n<td style=\"text-align: center;\">8<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">3<\/td>\n<td style=\"text-align: center;\">19<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Simply be noticing that each new sequence multiplies the existing signals by a factor of 3 for each Success, Failure and Corrupted message received we can easily code a brutal force solution which for each new time unit creates the new sequences and drops those ending with three corruptions or containing two failures at any point. Using our test data our brutal solution looks like the following:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\ndef count_sequences_brutal(units_of_time):\r\n    sequences = [&#039;S&#039;, &#039;F&#039;, &#039;C&#039;]\r\n    for i in range(1, units_of_time):\r\n        new_sequences = []\r\n        for sequence in sequences:\r\n            for c in &#039;SFC&#039;:\r\n                new_str = sequence + c\r\n                if &#039;CCC&#039; in new_str or new_str.count(&#039;F&#039;) &gt;= 2:\r\n                    continue\r\n                new_sequences.append(new_str)\r\n        sequences = new_sequences\r\n    return len(sequences)\r\n\r\n\r\nassert count_sequences_brutal(1) == 3\r\nassert count_sequences_brutal(2) == 8\r\nassert count_sequences_brutal(3) == 19\r\n<\/pre>\n<p>Now that we have a correct solution in place lets try to see how efficient it is in terms of performance as the number of time units is increasing:<\/p>\n<p>Running the following code:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nimport timeit\r\nimport functools\r\n\r\nfor time_units in [2, 3, 6, 10, 20, 25]:\r\n    print(\r\n        &#039;time_units:&#039;, time_units, &#039;duration:&#039;,\r\n        timeit.timeit(stmt=functools.partial(count_sequences_brutal, time_units), number=1)\r\n    )\r\n<\/pre>\n<p>We are getting the following output:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1644\" src=\"\/wp-content\/uploads\/2017\/04\/sig-5.png\" alt=\"sig-5\" width=\"537\" height=\"178\" \/><\/p>\n<p>Note how quickly the\u00a0 running time grows; for 10 unit times 0.006 seconds are required but for 25 we are reaching more than 89 seconds!<\/p>\n<p>Obviously our brutal force algorithm is terrible in terms in performance as it big O complexity is exponential. It still can be helpful for us since we create the following testing data that we will use later to test our efficient algorithm:<\/p>\n<table>\n<tbody>\n<tr>\n<th>Units of time<\/th>\n<th>Number of sequences<\/th>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">1<\/td>\n<td style=\"text-align: center;\">3<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">2<\/td>\n<td style=\"text-align: center;\">8<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">3<\/td>\n<td style=\"text-align: center;\">19<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">4<\/td>\n<td style=\"text-align: center;\">43<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">5<\/td>\n<td style=\"text-align: center;\">94<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">6<\/td>\n<td style=\"text-align: center;\">200<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">7<\/td>\n<td style=\"text-align: center;\">418<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">8<\/td>\n<td style=\"text-align: center;\">861<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">9<\/td>\n<td style=\"text-align: center;\">1753<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">10<\/td>\n<td style=\"text-align: center;\">3536<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Analyzing the problem<\/h2>\n<p>At this point we have enough data and understanding of our problem so we can analyze it further and try to discover some hidden tricks that might allow us to come up with a smart algorithm that will solve it efficiently.<\/p>\n<p>Thinking about our problem we can see that all of the following statements are all correct about a valid sequence:<\/p>\n<ul>\n<li>Ends with one of the letters <strong>S<\/strong> <strong>F<\/strong> <strong>C<\/strong> or <strong>CC<\/strong><\/li>\n<li>Contains none or a single failure <strong>F<\/strong><\/li>\n<li>Does not contain a <strong>CCC<\/strong> sub-sequence<\/li>\n<\/ul>\n<p>Each iteration goes through all of the previous sequences and for each of them creates three new sequences appending the <strong>S<\/strong> <strong>F<\/strong> <strong>C<\/strong> to its end; as this happens some of them will be rejected as invalid due to the rules we have defined above as can be seen in this picture:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1681\" src=\"\/wp-content\/uploads\/2017\/04\/sig-7.gif\" alt=\"sig-7\" width=\"617\" height=\"239\" \/><\/p>\n<p>Having said this, we can express the count of valid sequences at any point by adding up the following counters:<\/p>\n<table>\n<tbody>\n<tr>\n<th>Counter Name<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FS<\/strong><\/td>\n<td style=\"text-align: center;\">exactly one <strong>F<\/strong>, ending with <strong>S<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FC<\/strong><\/td>\n<td style=\"text-align: center;\">exactly one <strong>F<\/strong>, ending with <strong>C<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FCC<\/strong><\/td>\n<td style=\"text-align: center;\">exactly one <strong>F<\/strong>, ending with <strong>CC<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>S<\/strong><\/td>\n<td style=\"text-align: center;\">no <strong>F<\/strong>, ending with <strong>S<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>C<\/strong><\/td>\n<td style=\"text-align: center;\">no <strong>F<\/strong>, ending with <strong>C<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>CC<\/strong><\/td>\n<td style=\"text-align: center;\">no <strong>F<\/strong>, ending with <strong>CC<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>F<\/strong><\/td>\n<td style=\"text-align: center;\">ending with <strong>F<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>If we could calculate these counters for each iteration using their previous value our solution could have become very fast as only one pass would be sufficient to solve the problem and this exactly what we will try to do next.<\/p>\n<h2>The algorithmic solution<\/h2>\n<p>After the first time unit our sequences look as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1655\" src=\"\/wp-content\/uploads\/2017\/04\/sig-6.gif\" alt=\"sig-6\" width=\"140\" height=\"45\" \/><\/p>\n<p>with the following counters:<\/p>\n<table>\n<tbody>\n<tr>\n<th>Counter Name<\/th>\n<th>Count&gt;<\/th>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FS<\/strong><\/td>\n<td style=\"text-align: center;\">0<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FC<\/strong><\/td>\n<td style=\"text-align: center;\">0<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FCC<\/strong><\/td>\n<td style=\"text-align: center;\">0<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>S<\/strong><\/td>\n<td style=\"text-align: center;\">1<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>C<\/strong><\/td>\n<td style=\"text-align: center;\">1<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>CC<\/strong><\/td>\n<td style=\"text-align: center;\">0<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>F<\/strong><\/td>\n<td style=\"text-align: center;\">1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Adding all counters we get 3 which matches the valid signals we have so far.<\/p>\n<p>The second time unit will append each or the S F C to each of the existing sequences, creating 9 possible combinations.<\/p>\n<p>Since we already have broken down the existing sequences based on the rules of the problem, instead of creating all the combinations we can now use the known information to increase all the available counters for each of the S F C.<\/p>\n<p>The next received message will do the following:<\/p>\n<p><strong>Processing the S (success) case<\/strong><br \/>\nThe <strong>FS<\/strong> counter (has one Failure, ends with Success) becomes the total of the previous: FS, FC, FCC and F<br \/>\nThe <strong>S<\/strong> counter (has no Failure, ends with Success) becomes the total of the previous: S, C, CC<\/p>\n<p><strong>Processing the C (corrupted message) case<\/strong><\/p>\n<p>The <strong>FC<\/strong> counter (has one Failure, ends with C) becomes the total of the previous: FS and F<br \/>\nThe <strong>C<\/strong> counter (has no Failure, ends with C) becomes the previous: S<br \/>\nThe <strong>FCC<\/strong> counter (has no Failure, ends with C) becomes the previous: FC<br \/>\nThe <strong>CC<\/strong> counter (has no Failure, ends with C) becomes the previous: C<\/p>\n<p><strong>Processing the F (failure message) case<\/strong><br \/>\nThe <strong>F<\/strong> counter (ending with Failure) will become the previous: C, S, CC<\/p>\n<p>an easier to visualize view of what is said above is the following:<\/p>\n<table style=\"font-weight: bold;\">\n<tbody>\n<tr>\n<th>Counters sequence with length N<\/th>\n<th>Calculated based on previous sequence<\/th>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\"><strong>FS [n] <\/strong><\/td>\n<td style=\"text-align: center;\"><strong>FS [n-1] + FC [n-1] + FCC [n-1] + F [n-1] <\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">FC [n]<\/td>\n<td style=\"text-align: center;\">FS [n-1] + F [n-1]<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">FCC [n]<\/td>\n<td style=\"text-align: center;\">FC [n-1]<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">S [n]<\/td>\n<td style=\"text-align: center;\">S [n-1] + C [n-1] + CC [n-1]<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">C [n]<\/td>\n<td style=\"text-align: center;\">S [n-1]<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">CC [n]<\/td>\n<td style=\"text-align: center;\">C [n-1]<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">F [n]<\/td>\n<td style=\"text-align: center;\">C [n-1] + S [n-1] + CC [n-1]<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Manually applying these calculations for several iterations we are getting the following results:<\/p>\n<table>\n<thead>\n<tr>\n<th title=\"Field #1\">Counter<\/th>\n<th title=\"Field #2\">1<\/th>\n<th title=\"Field #3\">2<\/th>\n<th title=\"Field #4\">3<\/th>\n<th title=\"Field #5\">4<\/th>\n<th title=\"Field #6\">5<\/th>\n<th title=\"Field #7\">6<\/th>\n<th title=\"Field #8\">7<\/th>\n<th title=\"Field #9\">8<\/th>\n<th title=\"Field #10\">9<\/th>\n<th title=\"Field #11\">10<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>FS<\/strong><\/td>\n<td align=\"right\">0<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">4<\/td>\n<td align=\"right\">12<\/td>\n<td align=\"right\">30<\/td>\n<td align=\"right\">70<\/td>\n<td align=\"right\">156<\/td>\n<td align=\"right\">337<\/td>\n<td align=\"right\">712<\/td>\n<td align=\"right\">1479<\/td>\n<\/tr>\n<tr>\n<td><strong>FC<\/strong><\/td>\n<td align=\"right\">0<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">3<\/td>\n<td align=\"right\">8<\/td>\n<td align=\"right\">19<\/td>\n<td align=\"right\">43<\/td>\n<td align=\"right\">94<\/td>\n<td align=\"right\">200<\/td>\n<td align=\"right\">418<\/td>\n<td align=\"right\">861<\/td>\n<\/tr>\n<tr>\n<td><strong>FCC<\/strong><\/td>\n<td align=\"right\">0<\/td>\n<td align=\"right\">0<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">3<\/td>\n<td align=\"right\">8<\/td>\n<td align=\"right\">19<\/td>\n<td align=\"right\">43<\/td>\n<td align=\"right\">94<\/td>\n<td align=\"right\">200<\/td>\n<td align=\"right\">418<\/td>\n<\/tr>\n<tr>\n<td><strong>S<\/strong><\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">2<\/td>\n<td align=\"right\">4<\/td>\n<td align=\"right\">7<\/td>\n<td align=\"right\">13<\/td>\n<td align=\"right\">24<\/td>\n<td align=\"right\">44<\/td>\n<td align=\"right\">81<\/td>\n<td align=\"right\">149<\/td>\n<td align=\"right\">274<\/td>\n<\/tr>\n<tr>\n<td><strong>C<\/strong><\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">2<\/td>\n<td align=\"right\">4<\/td>\n<td align=\"right\">7<\/td>\n<td align=\"right\">13<\/td>\n<td align=\"right\">24<\/td>\n<td align=\"right\">44<\/td>\n<td align=\"right\">81<\/td>\n<td align=\"right\">149<\/td>\n<\/tr>\n<tr>\n<td><strong>CC<\/strong><\/td>\n<td align=\"right\">0<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">2<\/td>\n<td align=\"right\">4<\/td>\n<td align=\"right\">7<\/td>\n<td align=\"right\">13<\/td>\n<td align=\"right\">24<\/td>\n<td align=\"right\">44<\/td>\n<td align=\"right\">81<\/td>\n<\/tr>\n<tr>\n<td><strong>F<\/strong><\/td>\n<td align=\"right\">1<\/td>\n<td align=\"right\">2<\/td>\n<td align=\"right\">4<\/td>\n<td align=\"right\">7<\/td>\n<td align=\"right\">13<\/td>\n<td align=\"right\">24<\/td>\n<td align=\"right\">44<\/td>\n<td align=\"right\">81<\/td>\n<td align=\"right\">149<\/td>\n<td align=\"right\">274<\/td>\n<\/tr>\n<tr>\n<td><strong>Totals<\/strong><\/td>\n<td align=\"right\"><strong>3<\/strong><\/td>\n<td align=\"right\"><strong>8<\/strong><\/td>\n<td align=\"right\"><strong>19<\/strong><\/td>\n<td align=\"right\"><strong>43<\/strong><\/td>\n<td align=\"right\"><strong>94<\/strong><\/td>\n<td align=\"right\"><strong>200<\/strong><\/td>\n<td align=\"right\"><strong>418<\/strong><\/td>\n<td align=\"right\"><strong>861<\/strong><\/td>\n<td align=\"right\"><strong>1753<\/strong><\/td>\n<td align=\"right\"><strong>3536<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that the bottom line of the above table contains the totals for each iteration; comparing them with we have gotten from the brutal solution we happily see that the results are matching so our algorithm is correct.<\/p>\n<h2>The code<\/h2>\n<p>Now that we have figured out the algorithm the next (and easiest) step is to to express it in code as can be seen here:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\ndef count_sequences(N):\r\n    fs = 0\r\n    fc = 0\r\n    fcc = 0\r\n    s = 1\r\n    c = 1\r\n    cc = 0\r\n    f = 1\r\n\r\n    n = 1\r\n    while n &lt; N:\r\n        fs, fc, fcc, s, c, cc, f = (\r\n            fs + fc + fcc + f,\r\n            fs + f,\r\n            fc,\r\n            s + c + cc,\r\n            s,\r\n            c,\r\n            c + s + cc\r\n        )\r\n        n += 1\r\n\r\n    return fs + fc + fcc + s + c + cc + f\r\n<\/pre>\n<p>We can also use the brutal solution to validate our implementation:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfor i in range(1, 10):\r\n    assert count_sequences(i) == count_sequences_brutal(i)\r\n<\/pre>\n<p>Running the performance test as we did with the brutal solution previously:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfor time_units in [2, 3, 6, 10, 20, 25, 10000]:\r\n    print(\r\n        &#039;time_units:&#039;, time_units, &#039;duration:&#039;,\r\n        timeit.timeit(stmt=functools.partial(count_sequences, time_units), number=1)\r\n    )\r\n<\/pre>\n<p>gives us the following results:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1688\" src=\"\/wp-content\/uploads\/2017\/04\/sig-8.gif\" alt=\"sig-8\" width=\"393\" height=\"171\" \/><\/p>\n<p>Comparing this output with what we have gotten before proves that now we have an extremely much faster algorithm that can be used for a very large number of iteration without significant delays.<\/p>\n<p>To be more precise the time complexity of our algorithm is linear (O(n)) while its space complexity is O(1) as we do not allocate any additional memory to run it.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this posting we had to deal with a problem whose obvious solution was very time consuming but after thinking a bit and understanding it better we were able to discover a &#8220;smart&#8221; trick to solve it efficiently; the same approach is applicable to many similar problems where the best solution lies in discovering some &#8220;hidden&#8221; properties that are not apparent from the first glance.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Solving a programming problem that requires a custom algorithm can be broken in several steps which can be summarized in the creation of testing data,&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-187","post","type-post","status-publish","format-standard","hentry","category-programming"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":211,"url":"https:\/\/codingismycraft.blog\/index.php\/2020\/07\/01\/thinking-about-algorithmic-problems\/","url_meta":{"origin":187,"position":0},"title":"Thinking about Algorithmic problems","author":"john","date":"July 1, 2020","format":false,"excerpt":"In this posting we will discuss algorithmic thinking and try to propose a way of thinking that might become helpful when trying to solve a problem that does not have an obvious solution and some level of improvisation is required. Based on my experience the three most important qualities of\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/codingismycraft.blog\/index.php\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":204,"url":"https:\/\/codingismycraft.blog\/index.php\/2020\/07\/06\/buying-and-selling-stocks-with-maximum-profit\/","url_meta":{"origin":187,"position":1},"title":"Buying and Selling stocks with maximum profit","author":"john","date":"July 6, 2020","format":false,"excerpt":"Summary This posting continues the discussion about algorithmic thinking solving a well know problem that is known as\u00a0 Best Time to Buy and Sell Stock with maximum profit. The solution to this problem is hard and I do not believe that it makes a good interview question but it is\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/codingismycraft.blog\/index.php\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":46,"url":"https:\/\/codingismycraft.blog\/index.php\/2013\/05\/01\/be-extra-cautious-of-early-decisions-in-your-development-cycle\/","url_meta":{"origin":187,"position":2},"title":"Be extra cautious of early decisions in your development cycle","author":"john","date":"May 1, 2013","format":false,"excerpt":"I do not see how can anyone disagree with The McDonald Theory which states that initiating a process is more important than finding the ultimate solution at once. In deed this is how science and technology are progressing and naturally the same principle applies to any human activity which can\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/codingismycraft.blog\/index.php\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":348,"url":"https:\/\/codingismycraft.blog\/index.php\/2025\/03\/19\/stop-chasing-technology-how-to-build-ai-that-solves-genuine-problems\/","url_meta":{"origin":187,"position":3},"title":"Stop Chasing Technology: Finding the user\u2019s problem is the real problem!","author":"john","date":"March 19, 2025","format":false,"excerpt":"There\u2019s a common critique in the AI community: too often, AI solutions emerge from asking, \u201cWhat can we do?\u201d rather than, \u201cWhat problem do we need to solve?\u201d Developers frequently jump on the latest algorithm or innovative model and then search for a suitable use case. This approach tends to\u2026","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/codingismycraft.blog\/index.php\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":64,"url":"https:\/\/codingismycraft.blog\/index.php\/2015\/10\/07\/metrics-converted-to-goals-lose-their-focus\/","url_meta":{"origin":187,"position":4},"title":"Metrics converted to goals lose their focus","author":"john","date":"October 7, 2015","format":false,"excerpt":"One of the common discussions I have had with my colleagues over the last years was about the creation of metrics to express the productivity and the quality of an individual developer. At first glance, the idea of expressing the ability of a programmer, with a small set of easy\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/codingismycraft.blog\/index.php\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":40,"url":"https:\/\/codingismycraft.blog\/index.php\/2013\/03\/11\/abstractions-and-specializations\/","url_meta":{"origin":187,"position":5},"title":"Abstractions and Specializations","author":"john","date":"March 11, 2013","format":false,"excerpt":"Sometimes when developing a solution I stop my coding for a several minutes visualizing my work as a battle between abstractions and specializations. The contrast of these opposites is a major characteristic of any program developed ever and the talent, experience and determination of the developer are stamping the final\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/codingismycraft.blog\/index.php\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/posts\/187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/comments?post=187"}],"version-history":[{"count":16,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/posts\/187\/revisions"}],"predecessor-version":[{"id":203,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/posts\/187\/revisions\/203"}],"wp:attachment":[{"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/media?parent=187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/categories?post=187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codingismycraft.blog\/index.php\/wp-json\/wp\/v2\/tags?post=187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}