{"id":2265,"date":"2024-10-15T21:46:52","date_gmt":"2024-10-15T21:46:52","guid":{"rendered":"https:\/\/algocademy.com\/blog\/why-algorithmic-thinking-is-like-cooking-follow-a-recipe-then-experiment\/"},"modified":"2026-10-15T10:34:50","modified_gmt":"2026-10-15T10:34:50","slug":"why-algorithmic-thinking-is-like-cooking-follow-a-recipe-then-experiment","status":"publish","type":"post","link":"https:\/\/algocademy.com\/blog\/why-algorithmic-thinking-is-like-cooking-follow-a-recipe-then-experiment\/","title":{"rendered":"Algorithmic Thinking Is Like Cooking: Follow a Recipe, Then Experiment"},"content":{"rendered":"<p>A recipe is an algorithm: a fixed list of steps that turns inputs (ingredients) into an output (a dish). Learning algorithmic thinking follows the same path as learning to cook. You follow the recipe exactly, you work out why each step is there, and only then do you start changing things, one change at a time, tasting after each.<\/p>\n<p>This post walks through that path with one small problem, finding the largest number in a list, and then shows where the cooking comparison stops being useful.<\/p>\n<h2>Where the comparison holds<\/h2>\n<table>\n<thead>\n<tr>\n<th scope=\"col\">In the kitchen<\/th>\n<th scope=\"col\">In code<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Ingredients<\/td>\n<td>Input (the function&#8217;s arguments)<\/td>\n<\/tr>\n<tr>\n<td>The finished dish<\/td>\n<td>Output (the return value)<\/td>\n<\/tr>\n<tr>\n<td>Steps, in order<\/td>\n<td>Statements, run top to bottom<\/td>\n<\/tr>\n<tr>\n<td>&#8220;Stir until thick&#8221;<\/td>\n<td>A loop with a stopping condition<\/td>\n<\/tr>\n<tr>\n<td>&#8220;If the sauce is too thin, simmer longer&#8221;<\/td>\n<td>An <code>if<\/code> statement<\/td>\n<\/tr>\n<tr>\n<td>A technique you reuse (making a roux)<\/td>\n<td>A function<\/td>\n<\/tr>\n<tr>\n<td>Mise en place: chop everything before you start<\/td>\n<td>Reading the problem, listing inputs and edge cases before typing<\/td>\n<\/tr>\n<tr>\n<td>Tasting while you cook<\/td>\n<td>Running tests and printing intermediate values<\/td>\n<\/tr>\n<tr>\n<td>Cooking for 2 versus for 200<\/td>\n<td>Time complexity: how the work grows with the input<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>None of this is deep. It is useful because it describes how people actually learn both skills, and it points at the stage where most beginners get stuck: they want to experiment before they can follow the recipe.<\/p>\n<h2>Stage 1: follow the recipe exactly<\/h2>\n<p>A first-time cook who &#8220;improves&#8221; a recipe halfway through usually ends up with something inedible and no idea which change caused it. The coding version is copying a solution, changing a few lines you do not understand, and then being unable to say why it fails.<\/p>\n<p>Here is the recipe for the largest number in a list, written as plain steps:<\/p>\n<ol>\n<li>Take the first number and call it <em>best so far<\/em>.<\/li>\n<li>Look at each remaining number. If it is bigger than <em>best so far<\/em>, it becomes the new <em>best so far<\/em>.<\/li>\n<li>When the numbers run out, <em>best so far<\/em> is the answer.<\/li>\n<\/ol>\n<p>And the same recipe in Python:<\/p>\n<pre><code class=\"language-python\">def find_max(numbers):\n    best = numbers[0]\n    for n in numbers[1:]:\n        if n &gt; best:\n            best = n\n    return best\n\nprint(find_max([3, 9, 2, 9, 4]))   # 9\nprint(find_max([-7, -3, -12]))     # -3\nprint(find_max([5]))               # 5<\/code><\/pre>\n<p>Follow it by hand once with <code>[3, 9, 2, 9, 4]<\/code>: best starts at 3, becomes 9 at the second number, stays 9 for the rest. Doing this on paper is the equivalent of cooking along with the recipe open on the counter. Our post on <a href=\"https:\/\/algocademy.com\/blog\/how-to-dry-run-code-with-sample-test-cases-during-a-coding-interview\/\">dry-running code with sample test cases<\/a> covers the habit in more detail.<\/p>\n<h2>Stage 2: find out why each step is there<\/h2>\n<p>Good cooks know why you salt the pasta water and why the pan must be hot before the onions go in. For the recipe above, the questions are just as concrete.<\/p>\n<p><strong>Why start from the first number and not from 0?<\/strong> Try it:<\/p>\n<pre><code class=\"language-python\">def wrong_max(numbers):\n    best = 0\n    for n in numbers:\n        if n &gt; best:\n            best = n\n    return best\n\nprint(wrong_max([-7, -3, -12]))    # 0, which is not in the list<\/code><\/pre>\n<p>Starting at 0 only works if the list contains something at least 0. Starting from an actual element works for every non-empty list. That one detail is the difference between a recipe that works on your kitchen&#8217;s stove and one that works on any stove.<\/p>\n<p><strong>What happens with an empty list?<\/strong> <code>find_max([])<\/code> raises <code>IndexError: list index out of range<\/code>, because there is no first element to take. The recipe silently assumed at least one ingredient. Decide what you want: raise a clearer error, or return <code>None<\/code>. Either is fine as long as you chose it on purpose.<\/p>\n<p><strong>What happens with ties?<\/strong> In <code>[3, 9, 2, 9, 4]<\/code> the 9 appears twice. The <code>&gt;<\/code> comparison keeps the first one. Using <code>&gt;=<\/code> would keep the last one. For plain numbers it makes no difference, but if you were returning the position it would.<\/p>\n<h2>Stage 3: change one thing at a time<\/h2>\n<p>This is the experimenting part, and the rule is the same as in the kitchen: if you change salt, spice and cooking time together, you learn nothing. Change one step, run it, compare.<\/p>\n<p>Experiment 1: return the position as well as the value.<\/p>\n<pre><code class=\"language-python\">def find_max_with_index(numbers):\n    if not numbers:\n        raise ValueError(\"find_max_with_index needs at least one number\")\n    best_i = 0\n    for i in range(1, len(numbers)):\n        if numbers[i] &gt; numbers[best_i]:\n            best_i = i\n    return numbers[best_i], best_i\n\nprint(find_max_with_index([3, 9, 2, 9, 4]))   # (9, 1)<\/code><\/pre>\n<p>Experiment 2: flip the comparison to get the minimum. Experiment 3: keep the two largest values instead of one. Each is a small variation, and each teaches you what a line of the original was doing. Also try replacing the whole loop with Python&#8217;s built-in <code>max()<\/code>. It is shorter and you should use it in real code, but notice that it does the same three steps inside. In an interview, an interviewer who asks you to find the maximum wants to see the loop, not the call.<\/p>\n<p>When you invent a variation yourself, like &#8220;largest number that is also even&#8221;, you are no longer cooking from a recipe. You are writing one. Our post on <a href=\"https:\/\/algocademy.com\/blog\/the-art-of-breaking-down-complex-problems-a-step-by-step-approach-to-coding-challenges\/\">breaking complex problems into steps<\/a> is about that move.<\/p>\n<h2>Stage 4: cook for a crowd<\/h2>\n<p>A recipe for four people does not simply multiply by fifty. Pots, oven space and timing all change. In code, the question is how the work grows as the input grows.<\/p>\n<p>Searching for a value in a sorted list shows this well. Checking every item takes work proportional to the list length. Binary search, which repeatedly looks at the middle and discards half, takes work proportional to the logarithm of the length. Counting the steps on a list of one million even numbers (0, 2, 4, up to 1,999,998):<\/p>\n<pre><code class=\"language-python\">def linear_search(items, target):\n    steps = 0\n    for x in items:\n        steps += 1\n        if x == target:\n            return True, steps\n    return False, steps\n\ndef binary_search(items, target):\n    lo, hi, steps = 0, len(items) - 1, 0\n    while lo &lt;= hi:\n        steps += 1\n        mid = (lo + hi) \/\/ 2\n        if items[mid] == target:\n            return True, steps\n        if items[mid] &lt; target:\n            lo = mid + 1\n        else:\n            hi = mid - 1\n    return False, steps\n\ndata = list(range(0, 2_000_000, 2))\nprint(linear_search(data, 1_999_998))   # (True, 1000000)\nprint(binary_search(data, 1_999_998))   # (True, 20)<\/code><\/pre>\n<p>One million steps against twenty. Binary search only works because the list is sorted, which is the algorithmic version of &#8220;this technique needs the dough to rest first&#8221;. If you want to go deeper, read <a href=\"https:\/\/algocademy.com\/blog\/diving-into-search-algorithms-linear-vs-binary-search\/\">linear vs binary search<\/a> or <a href=\"https:\/\/algocademy.com\/blog\/understanding-algorithms-time-complexity-explained\/\">time complexity explained<\/a>.<\/p>\n<h2>Where the comparison breaks<\/h2>\n<ul>\n<li><strong>A computer has no taste.<\/strong> A cook adjusts to what they see and smell. Code does exactly what you wrote, including the mistakes, so you must decide in advance what &#8220;done&#8221; means and test for it.<\/li>\n<li><strong>Recipes tolerate vagueness; algorithms do not.<\/strong> &#8220;A pinch of salt&#8221; is fine. &#8220;Loop until it looks sorted&#8221; is not a step.<\/li>\n<li><strong>Correctness is checkable.<\/strong> A dish is a matter of taste. An algorithm can be proven or tested against every input you can think of, and it should be.<\/li>\n<li><strong>The same input always gives the same output.<\/strong> Your oven has hot spots; a deterministic function does not.<\/li>\n<\/ul>\n<p>Use the analogy to get started and drop it when it stops helping.<\/p>\n<h2>How to practice in this order<\/h2>\n<ol>\n<li>Pick a small problem and solve it by following a worked solution, typing it yourself instead of pasting.<\/li>\n<li>Close the solution and write it again from memory. Where you get stuck is what you did not understand.<\/li>\n<li>Break it on purpose with an empty input, a single item, duplicates, negative numbers. Fix what breaks.<\/li>\n<li>Change one requirement and adapt the code (smallest instead of largest, position instead of value).<\/li>\n<li>Only then try problems you have never seen.<\/li>\n<\/ol>\n<p>If you want guided problems where each step is small and your code is checked immediately, the Python course at <a href=\"https:\/\/app.algocademy.com\/\">AlgoCademy<\/a> works this way. A good first one is <a href=\"https:\/\/algocademy.com\/link\/?lang=py&amp;problem=max-in-array&amp;solution=1\">Maximum Number In Array<\/a>, the same problem as above.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A recipe is an algorithm. See how learning to cook maps onto solving coding problems, with tested Python examples, and see where the comparison breaks down.<\/p>\n","protected":false},"author":1,"featured_media":2264,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[],"class_list":["post-2265","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-problem-solving"],"_links":{"self":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/2265"}],"collection":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/comments?post=2265"}],"version-history":[{"count":1,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/2265\/revisions"}],"predecessor-version":[{"id":8734,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/posts\/2265\/revisions\/8734"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/media\/2264"}],"wp:attachment":[{"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/media?parent=2265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/categories?post=2265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/algocademy.com\/blog\/wp-json\/wp\/v2\/tags?post=2265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}