
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
    
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/graphs","feed_url":"https:\/\/mathspp.com\/blog\/tags\/graphs.json","description":"Stay up-to-date with the articles on mathematics and programming that get published to mathspp.com.","author":{"name":"Rodrigo Gir\u00e3o Serr\u00e3o"},"items":[{"title":"Floodfill algorithm in Python","date_published":"2025-11-17T16:49:00+01:00","id":"https:\/\/mathspp.com\/blog\/floodfill-algorithm-in-python","url":"https:\/\/mathspp.com\/blog\/floodfill-algorithm-in-python","content_html":"<p>Learn how to implement and use the floodfill algorithm in Python.<\/p>\n\n<link rel=\"stylesheet\" href=\"https:\/\/pyscript.net\/releases\/2025.11.1\/core.css\"><script defer type=\"module\" src=\"https:\/\/pyscript.net\/releases\/2025.11.1\/core.js\"><\/script><py-script>\nimport js\n\nroot = js.document.documentElement\ncomputed = js.window.getComputedStyle(root)\n\nBG_COLOUR = computed.getPropertyValue(\"--bg\").strip()\nFG_COLOUR = computed.getPropertyValue(\"--tx\").strip()\nUI_COLOUR = computed.getPropertyValue(\"--ui\").strip()\nAC_COLOUR = computed.getPropertyValue(\"--accent\").strip()\nAC2_COLOUR = computed.getPropertyValue(\"--accent-2\").strip()\nRE_COLOUR = computed.getPropertyValue(\"--re\").strip()\nBL_COLOUR = computed.getPropertyValue(\"--bl\").strip()\nGR_COLOUR = computed.getPropertyValue(\"--gr\").strip()\nYE_COLOUR = computed.getPropertyValue(\"--ye\").strip()\nOR_COLOUR = computed.getPropertyValue(\"--or\").strip()\n\nCONTRAST = {\n    BG_COLOUR: FG_COLOUR,\n    FG_COLOUR: BG_COLOUR,\n    UI_COLOUR: FG_COLOUR,\n    AC_COLOUR: FG_COLOUR,\n    AC2_COLOUR: FG_COLOUR,\n    RE_COLOUR: FG_COLOUR,\n    BL_COLOUR: FG_COLOUR,\n    GR_COLOUR: FG_COLOUR,\n    YE_COLOUR: FG_COLOUR,\n    OR_COLOUR: FG_COLOUR,\n}\n<\/py-script><p>In this article you will learn about the floodfill algorithm.\nYou will learn the intuitive explanation of the algorithm, how it can be used to colour regions in images, and how to implement it in Python.\nYou will also see three example applications of the floodfill algorithm, with interactive demos and code.<\/p>\n<p>By the time you are finished reading this article, you will be able to apply the floodfill algorithm in your own projects and modify it or tweak it according to your needs and preferences.<\/p>\n<h2 id=\"what-is-the-floodfill-algorithm\">What is the floodfill algorithm?<a href=\"#what-is-the-floodfill-algorithm\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Click the image below to randomly colour the region you click.<\/p>\n<p>Go ahead, try it!<\/p>\n<canvas id=\"bitmap\" width=\"320\" height=\"320\" style=\"display: block; margin: 0 auto; max-width: 100%; height: auto;\"><\/canvas><script>\nfunction set_canvas_loading(canvas) {\n    let ctx = canvas.getContext(\"2d\");\n\n    \/\/ Get computed values of CSS variables\n    const styles = getComputedStyle(document.documentElement);\n    const bg = styles.getPropertyValue(\"--bg\").trim();\n    const fg = styles.getPropertyValue(\"--accent\").trim();\n\n    ctx.fillStyle = bg;\n    ctx.fillRect(0, 0, canvas.width, canvas.height);\n    ctx.fillStyle = fg;\n    ctx.font = \"36px Atkinson Hyperlegible\";\n    ctx.textAlign = \"center\";\n    ctx.textBaseline = \"middle\";\n    ctx.fillText(\"Loading...\", canvas.width \/ 2, canvas.height \/ 2);\n}\n\nset_canvas_loading(document.getElementById(\"bitmap\"));\n<\/script><py-script>\nIMG_WIDTH = 160\nIMG_HEIGHT = 160\nPIXEL_SIZE = 2\n\nimport asyncio\nimport collections\nimport itertools\n\nfrom pyscript import display\nfrom pyodide.ffi import create_proxy\nimport js\nfrom js import fetch\n\ncanvas = js.document.getElementById(\"bitmap\")\nctx = canvas.getContext(\"2d\")\n\n_BITMAP_COLOURS = itertools.cycle([AC_COLOUR, AC2_COLOUR, RE_COLOUR, BL_COLOUR, YE_COLOUR, GR_COLOUR, OR_COLOUR])\n\n_ints = [0, 0, 0, 0, 0, 0, 0, 9903520019135137019840167936, 316912650047833978337321025536, 5069364463233662545642129457152, 40406362882311561545666757918720, 159723975628759174402796798607360, 628754697713202062365541686837248, 1216944576219100292990829487718400, 2433889152438200467762168756961280, 4543259751217974183408433589387264, 9086519502435948354150493226795008, 18173039004871896701827061989244928, 15586952552243794457451031487840256, 36366340612306816504545604379082752, 31189423920820070440268979792510976, 31224838909463946599208478310400000, 31214663042341020773348807509278720, 31295792680755627454903859026067456, 31295772873714998888819460640079872, 31295772873714998888819460640079872, 31214663042341020773208070020923392, 31214658090580863631686970424426496, 31224838909463946599067740822044672, 31191949318500212615924220889661440, 31174023946731360309543681570897920, 31158772525447364424556924360458240, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 41538374867674158118542209162674176, 41538374867674158118542209162674176, 41538374867674158118542209162674176, 1813388729527496878325760, 1813388729531894857728000, 5444517870735014810951084025942904930304, 87112285931760246042160989809567281971200, 347088014259357233337105009500967893204992, 1372018503425223884684326417278139134115840, 2613368577952807399398716985189229563609088, 5226737155905614798797433970265209426542592, 9756576024357147624421876744396907856986112, 19513152048714295248843753488680566015623168, 39026304097428590497687506977247882333241344, 78052608194857180995375013954382514968641536, 78052608194857180995375013954382514968649728, 156105216389714361990750027908651780239548416, 133804471191183738849214309636003418733572096, 312210432779428723981500055817190310781399040, 267608942382367477698428619271893587769440256, 624420865558857447963000111634267371865126912, 535217884764734955396857238543673925841197056, 535217884764734955396857238543673925841198080, 1248841731117714895926000223268421494032571392, 1070435769529469910793714477087375339473079296, 1070435769529469910793714477087375339473079296, 1070435769529469910793714477087339055589363200, 2497683462235429791852000446537115666948820480, 2497683462235429791852000446537045298204642816, 2140871539058939821587428954175243260155397632, 2140871539058939821587428954176226223550629376, 2140871539058939821587428954176243815736673792, 2140871539058939821587428954182717740201018880, 2140871539058939821587428954191192775827916288, 4995366924470859583704000893143091548121990912, 4995366924470859583704000893352579299538896640, 4995366924470859583704000897667150887862142720, 4995366924470900148523208196270458264975574784, 4995366924471184102257659318649205691078674176, 4995366924472147516713832774153879352074307328, 4995366924475889621285706507409303589789632256, 4995366924480596407964353923103877354846422784, 4995366924489042763913674615590287289608046336, 4995366924507286632895834264625967053561399040, 4995366924543708928397916780318445517146162944, 4995366924533795900704132026398741298080122624, 2140871539205541078202623227998533436869445120, 2140871539185988835344703017709848286629725696, 2140871539354576223970255702273697839319090688, 2140871539312713330548318654518670712664753664, 2140871539649563589245765596919586662022907392, 2140871539648265515031131890012454037940604416, 2497683462752063329276215795575400873427209728, 2497683462749467180846948381761135625262599168, 1070435770708121297681120348763544019020024832, 1070435770728890485115259659277666004336905216, 1248841732317135470247545405458852896384752640, 1248841732311943173389010577830322400055531520, 535217885958963232859867593105574831864158208, 535217885958963232859867593105574831864166400, 624420866753085725426010466196168277888086016, 267608943576595755161438973833794493792415744, 312210433973657001444510410379091216804372480, 133804472385412016312224664197904324756561920, 156105217583942639453760382470552686262534144, 66902236789820146887617509379959240238678016, 78052609389085458458385368516283420991782912, 39026305291656867960697861539148788356546560, 19513153242942572711854108050581472039272448, 20906949817850736658200090442621994634313728, 10453475506039507060605222502318075184414720, 5226738350133892261807788532166115481092096, 1306685483204681162709713054552146185289728, 691454963811624423185783403544767058935808, 174224436863802173805581096441418979737600, 21777936483221741569526362504672367869952, 31153781153022354500604921737379840, 31153781153626817410377051952644096, 31153781153626817410377051952644096, 31153781153626817410377051952644096, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208965771288531091587072, 31153781151208974706430191794651136, 31153781151209002592719084472762368, 31153781151209035487010762786865152, 31153781151209095024597836624822272, 31153781151209076577853762915270656, 31153781151209224079748758553755648, 31153781151209187195267810389393408, 31153781151209187195267810389393408, 31153781151209224088755957808496640, 36346078009744051708279254882975744, 36346078009743922653128332954042368, 15576890575604621488479174058311680, 18173039004871970415021728557170688, 9086519502435985099512434151915520, 9086519502435951809185463605919744, 4543259751217974175949346706554880, 2433889152438200452843994991296512, 1216944576219100229377484751110144, 628754697713201800030863392505856, 157188674428300515591385421709312, 39930993907189793600699199651840, 10061976639316146531601490116608, 2534063261007325117889137082368, 158456325026222832177874206720, 4951760083354544804758290432, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n\ndef parse_bitmap():\n    return [[1] * 160] + [\n        [1] + [int(c) for c in bin(i).removeprefix(\"0b\").zfill(158)] + [1]\n        for i in _ints\n    ] + [[1] * 160]\n\n'''\nasync def load_bitmap(url: str) -&gt; list[list[int]]:\n    # Fetch the text file from the URL\n    response = await fetch(url)\n    text = await response.text()\n\n    bitmap: list[list[int]] = []\n    for line in text.splitlines():\n        line = line.strip()\n        if...<\/py-script>","summary":"Learn how to implement and use the floodfill algorithm in Python.","date_modified":"2025-11-23T15:59:09+01:00","tags":["python","programming","algorithms","pyscript","visualisation","graphs"],"image":"\/user\/pages\/02.blog\/floodfill-algorithm-in-python\/thumbnail.webp"},{"title":"Minimax algorithm and alpha-beta pruning","date_published":"2021-11-21T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/minimax-algorithm-and-alpha-beta-pruning","url":"https:\/\/mathspp.com\/blog\/minimax-algorithm-and-alpha-beta-pruning","content_html":"<p>This article will teach you about the minimax algorithm and alpha-beta pruning, from a beginner's perspective.<\/p>\n\n<figure class=\"image-caption\"><img title=\"Photo by Faye Cornish on Unsplash\" alt=\"\" src=\"\/user\/pages\/02.blog\/minimax-algorithm-and-alpha-beta-pruning\/thumbnail.png\"><figcaption class=\"\">Photo by Faye Cornish on Unsplash<\/figcaption><\/figure><h2 id=\"introduction\">Introduction<a href=\"#introduction\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>This article aims at providing the reader with an introduction to the minimax search algorithm,\nand to alpha-beta pruning &ndash; an optimisation over that same algorithm.<\/p>\n<p>I am writing this article as a complete beginner with regards to this topic,\nwhich hopefully will benefit you and me:<\/p>\n<ul><li>it will benefit me because, in order to write a good article,\nI will have to push myself to really understand the algorithms; and<\/li>\n<li>it will benefit you because, as I am a beginner in this topic,\nI will be extra careful to explain all the little details.<\/li>\n<\/ul><p>The article will introduce the theoretical concepts needed to understand the minimax algorithm,\nas well as the alpha-beta pruning optimisation.<\/p>\n<p>I will be implementing the algorithms in Python.\nFeel free to join me in writing some Python code,\ndo it in any other language you prefer,\nor just skip the coding parts altogether!<\/p>\n<p>On top of this, we will be taking a look at these algorithms from the perspective\nof a game.\nThat is, we want to implement these algorithms so that we can use them\nas artificial intelligence algorithms to play games against humans.\nTherefore, the language I will be using will also revolve around that:\n&ldquo;players&rdquo;, &ldquo;moves&rdquo;, &ldquo;scores&rdquo;, &ldquo;winning\/losing&rdquo;, etc.<\/p>\n<p>So, without further ado, let's start!<\/p>\n<h2 id=\"prior-knowledge\">Prior knowledge<a href=\"#prior-knowledge\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Like I just said, I am a complete beginner at this topic.\nThe only things I have done are as follows:<\/p>\n<ul><li>I read <a href=\"https:\/\/en.wikipedia.org\/wiki\/Alpha%E2%80%93beta_pruning\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this<\/a> Wikipedia article; and<\/li>\n<li>watched two YouTube videos at 2&times; speed.<\/li>\n<\/ul><p>If you only want to watch one, I recommend you watch <a href=\"https:\/\/www.youtube.com\/watch?v=l-hh51ncgDI\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this one<\/a>.\nIf you have the time and patience to watch both,\nthen start with <a href=\"https:\/\/www.youtube.com\/watch?v=xBXHtz4Gbdo\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this one<\/a> and only then watch <a href=\"https:\/\/www.youtube.com\/watch?v=l-hh51ncgDI\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this<\/a>.<\/p>\n<h2 id=\"the-minimax-algorithm\">The minimax algorithm<a href=\"#the-minimax-algorithm\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The minimax algorithm is the algorithm around which this whole article revolves,\nso it is best if we take some time to really understand it.<\/p>\n<p>In a short, but unhelpful sentence, the minimax algorithm\ntries to maximise my score,\nwhile taking into account the fact that you will do your best\nto minimise my score.<\/p>\n<p>Suppose that you and me are playing Tic Tac Toe, I'm the crosses (<code>X<\/code>),\nit's my turn to play, and the game looks like this:<\/p>\n<figure class=\"image-caption\"><img title=\"A game of Tic Tac Toe\" alt=\"\" src=\"\/user\/pages\/02.blog\/minimax-algorithm-and-alpha-beta-pruning\/_tic_tac_toe.webp\"><figcaption class=\"\">A game of Tic Tac Toe<\/figcaption><\/figure><p>I have to pick a move and, for that, I analyse all of my possibilities:<\/p>\n<figure class=\"image-caption\"><img title=\"My three possible moves.\" alt=\"\" src=\"\/user\/pages\/02.blog\/minimax-algorithm-and-alpha-beta-pruning\/_tic_tac_toe_tree.webp\"><figcaption class=\"\">My three possible moves.<\/figcaption><\/figure><p>So, I play out these three moves inside my head, and I see that none of the moves gives me a win.\nTherefore, there is no obvious choice that I should make.<\/p>\n<p>What does this mean?\nIt means I need to keep playing out the moves inside my head,\nand I need to predict what you would do in each situation:<\/p>\n<figure class=\"image-caption\"><img title=\"My three possible moves together with the two possible replies for each.\" alt=\"\" src=\"\/user\/pages\/02.blog\/minimax-algorithm-and-alpha-beta-pruning\/_tic_tac_toe_tree_2.webp\"><figcaption class=\"\">My three possible moves together with the two possible replies for each.<\/figcaption><\/figure><p>Now, this reveals something interesting!\nIf we look at the...<\/p>","summary":"This article will teach you about the minimax algorithm and alpha-beta pruning, from a beginner&#039;s perspective.","date_modified":"2025-07-23T16:49:02+02:00","tags":["algorithms","artificial intelligence","graphs","mathematics","programming","python","recursion"],"image":"\/user\/pages\/02.blog\/minimax-algorithm-and-alpha-beta-pruning\/thumbnail.png"},{"title":"TIL #015 \u2013 DARPA network challenge","date_published":"2021-11-18T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/til\/015","url":"https:\/\/mathspp.com\/blog\/til\/015","content_html":"<p>Today I learned about the DARPA network challenge and the power of referral systems.<\/p>\n\n<figure class=\"image-caption\"><img title=\"Photo by Blake Cheek on Unsplash\" alt=\"A red balloon held by a hand.\" src=\"\/images\/9\/6\/4\/c\/8\/964c81c549f04333f6c03b50ed9df365b3fde6ff-thumbnail.png\"><figcaption class=\"\">Photo by Blake Cheek on Unsplash<\/figcaption><\/figure>\n<h2 id=\"darpa-network-challenge\">DARPA network challenge<a href=\"#darpa-network-challenge\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The DARPA network challenge was a challenge that took place in 2009 in the United States.<\/p>\n<p>(DARPA stands for Defense Advanced Research Projects Agency, a research organisation of the US Department of Defense.)<\/p>\n<p>The challenge was for participants to report the locations of 10 red balloons that were to be deployed, at the same time, in mainland US.\nIn other words, 10 balloons were scattered around the US and the teams had to find them.<\/p>\n<p>Its purpose was to study the effect that Internet and social networking could have in solving time-constrained, broad-scope challenges.<\/p>\n<p>The challenge had an associated pecuniary prize worth $40,000.<\/p>\n<h2 id=\"winning-strategy\">Winning strategy<a href=\"#winning-strategy\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The challenge was won by an MIT team who employed a networking referral strategy:\neach of the 10 balloons was defined to be worth \\$4,000 (total prize divided by total number of balloons).\nThen,<\/p>\n<ul>\n<li>the person that accurately reported the location of a balloon would be awarded $2,000;<\/li>\n<li>the person that had referred the reporter got $1,000;<\/li>\n<li>the person that referred the referrer got $500;<\/li>\n<li>and so on, and so forth...<\/li>\n<\/ul>\n<p>By consecutively dividing the prize in half, the team was able to make sure that the incentives flowed up the referral network, and this incentivised people to refer yet other people, as the new referrals would be working \u201cfor\u201d the referrers, and not \u201cagainst\u201d.<\/p>\n<p>One of the things I like about this strategy is how it theoretically works for an arbitrarily long chain of referrals, because even if you have to give compensation to millions of referrers in a chain, adding up all the money spent on compensations will never exceed the money allocated for each balloon.<\/p>\n<p>That's because the series<\/p>\n<p class=\"mathjax mathjax--block\">\\[\n\\sum_{n = 1}^\\infty \\frac1{2^n} = \\frac12 + \\frac14 + \\frac18 + \\cdots\\]<\/p>\n<p>adds up to 1.<\/p>\n<p>The prize money that was left, after awarding the compensations, was donated to charity.<\/p>\n<p>That's it for now! <a href=\"\/subscribe\">Stay tuned<\/a> and I'll see you around!<\/p>","summary":"Today I learned about the DARPA network challenge and the power of referral systems.","date_modified":"2025-07-23T16:49:02+02:00","tags":["graphs","mathematics"],"image":"\/user\/pages\/02.blog\/04.til\/015.darpa-network-challenge\/thumbnail.png"},{"title":"Problem #038 \u2013 bridges of K\u00f6nigsberg","date_published":"2021-06-13T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/problems\/bridges-of-konigsberg","url":"https:\/\/mathspp.com\/blog\/problems\/bridges-of-konigsberg","content_html":"<p>You are on vacation and must find the most efficient way to\ncross all bridges.\nHow will you do that?<\/p>\n\n<figure class=\"image-caption\"><img title=\"Satellite view of Kaliningrad, Russia.\" alt=\"\" src=\"\/user\/pages\/02.blog\/03.problems\/p038-bridges-of-konigsberg\/thumbnail.webp\"><figcaption class=\"\">Satellite view of Kaliningrad, Russia.<\/figcaption><\/figure><h2 id=\"problem-statement\">Problem statement<a href=\"#problem-statement\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>If you like solving riddles and puzzles, it is likely that you have\nalready encountered this puzzle.\nBut even if you have, it is always good to go back\nand think about the classics.\nOn top of that, I will formulate the problem in a slightly different\nway, so that you can be entertained for a bit even if you already\nknow the more classic version.<\/p>\n<p>Take a look at this satellite view from Kaliningrad, Russia,\nwhere I have highlighted seven bridges:<\/p>\n<figure class=\"image-caption\"><img title=\"Seven highlighted bridges in Kaliningrad, Russia.\" alt=\"\" src=\"\/user\/pages\/02.blog\/03.problems\/p038-bridges-of-konigsberg\/_bridges.webp\"><figcaption class=\"\">Seven highlighted bridges in Kaliningrad, Russia.<\/figcaption><\/figure><p>Your task is to figure out what route to take if what you want to do\nis cross all of the highlighted bridges at least once but,\nat the same time, keep the total number of crossed bridges as low\nas possible.<\/p>\n<p>Having said that, what is the best route you can come up with?<\/p>\n<p>(Just to be clear, I don't care about the length of the route &ndash;\nthe number of miles\/kilometres you would walk\/drive &ndash; I only\ncare about the number of bridges you cross.)<\/p>\n<div class=\"notices blue\">\n<p>Give it some thought!<\/p>\n<\/div>\n<p>If you need any clarification whatsoever, feel free to ask in the comment section below.<\/p>\n<p>In case you are wondering, the classic version of this puzzle is\ndubbed &ldquo;the seven bridges of K&ouml;nigsberg&rdquo; because that\nis what this place was called when a famous mathematician first\ndwelled on this problem.<\/p>\n<h2 id=\"solvers\">Solvers<a href=\"#solvers\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Congratulations to the ones that solved this problem correctly and, in particular, to the ones\nwho sent me their correct solutions:<\/p>\n<ul><li>Attila K., (Hungary)<\/li>\n<\/ul><h2 id=\"solution\">Solution<a href=\"#solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>There are seven distinct bridges that we want to traverse,\nso we know the shortest path has to go over seven bridges, minimum.\nWhat we will show is that, actually, we need to go over eight bridges\nin total in order to visit all seven bridges.<\/p>\n<p>In order to show that is the case, consider the following figure:<\/p>\n<figure class=\"image-caption\"><img title=\"Numbered pieces of land connected to the bridges.\" alt=\"\" src=\"\/user\/pages\/02.blog\/03.problems\/p038-bridges-of-konigsberg\/_bridges_lands.webp\"><figcaption class=\"\">Numbered pieces of land connected to the bridges.<\/figcaption><\/figure><p>In the figure above we can see that I numbered the four pieces\nof land to which the bridges are connected.<\/p>\n<p>How many bridges does each piece of land connect to?<\/p>\n<ol><li>connects to 3 bridges;<\/li>\n<li>connects to 3 bridges (as well);<\/li>\n<li>connects to 3 bridges (as well); and<\/li>\n<li>connects to 5 bridges.<\/li>\n<\/ol><p>Now we will use this information to show that it is impossible to create\na path that visits all bridges exactly once.<\/p>\n<p>Let us think about a hypothetical path we would do,\nin order to traverse all the bridges exactly once.\nMore specifically, let us think about what happens\nin the middle of our walk.\nIf we are in the middle of our path,\nwhen we enter some piece of land through a bridge,\nwe have to leave that piece of land through another bridge.\nIn other words, for each time we <em>arrive<\/em> at a piece of land,\nwe also...<\/p>","summary":"Can you solve this classical puzzle where you just have to cross some bridges?","date_modified":"2025-11-22T09:33:35+01:00","tags":["graphs","mathematics","topology"],"image":"\/user\/pages\/02.blog\/03.problems\/p038-bridges-of-konigsberg\/thumbnail.webp"},{"title":"Problem #033 - syncro","date_published":"2021-04-04T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/problems\/syncro","url":"https:\/\/mathspp.com\/blog\/problems\/syncro","content_html":"<p>Syncro is a beautiful game where you have to unite all the petals\nin a single flower.\nIn how many moves can you do it?<\/p>\n\n<p><img alt=\"\" src=\"\/images\/6\/2\/9\/6\/b\/6296b0937cb083f2b5064d1ad223a3701bd4285f-thumbnail.webp\"><\/p>\n<h2 id=\"problem-statement\">Problem statement<a href=\"#problem-statement\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Look at the image above.\nThere are four &ldquo;flowers&rdquo;, each one with four &ldquo;petals&rdquo;.\nNotice that each of the flowers has one coloured petal.\nThere are also arrows going from one flower to the other:\nthis means that the corresponding shape sends the coloured\npetals in that direction.<\/p>\n<p>For example, the square makes all coloured petals rotate once\nin the clockwise direction, or if you take the image above\nand do &ldquo;circle + square&rdquo; then the coloured petals end up like this:<\/p>\n<figure class=\"image-caption\"><img title=\"Petal distribution after doing the sequence &ldquo;circle + square&rdquo;.\" alt=\"\" src=\"\/user\/pages\/02.blog\/03.problems\/p033-syncro\/_syncro.webp\"><figcaption class=\"\">Petal distribution after doing the sequence &ldquo;circle + square&rdquo;.<\/figcaption><\/figure><p>Your objective is to find a sequence of circles and squares that\nput all coloured petals in a single flower, in the smallest\nnumber of steps possible.<\/p>\n<div class=\"notices blue\">\n<p>Give it some thought...<\/p>\n<\/div>\n<p>If you need any clarification whatsoever, feel free to ask in the comment section below.<\/p>\n<h2 id=\"syncro\">Syncro<a href=\"#syncro\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Syncro is a desktop\/mobile game developed by some friends of mine, and the objective\nof the game is the same as that of this problem, except the game itself has several\nlevels.<\/p>\n<p>This game can be played <a class=\"external-link no-image external-link no-image\" href=\"https:\/\/rawegg.itch.io\/syncro\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">online<\/a> and there is also an\n<a class=\"external-link no-image external-link no-image\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.RawEgg.Syncro\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Android app<\/a>.<\/p>\n<p>If you complete the game, you can even end up in the <a href=\"\/syncro\">hall of fame<\/a>!<\/p>\n<h2 id=\"solvers\">Solvers<a href=\"#solvers\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Congratulations to the ones that solved this problem correctly and, in particular, to the ones\nwho sent me their correct solutions:<\/p>\n<ul><li>Filippo M., Italy;<\/li>\n<li>Attila K., Hungary;<\/li>\n<li>Andr&eacute; S., Portugal.<\/li>\n<\/ul><p>(The list is in no particular order.)<\/p>\n<h2 id=\"solution\">Solution<a href=\"#solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>This problem is really hard to solve without a visual representation of what is going on,\nso let me remind you of what the problem looks like:<\/p>\n<figure class=\"image-caption\"><img title=\"Initial configuration.\" alt=\"\" src=\"\/images\/6\/2\/9\/6\/b\/6296b0937cb083f2b5064d1ad223a3701bd4285f-thumbnail.webp\"><figcaption class=\"\">Initial configuration.<\/figcaption><\/figure><p>We want to figure out what is the shortest sequence of circles and squares sends the four white triangles\nin the four petals into a single flower.<\/p>\n<p>We see that the square rotates the whole thing while the circle swaps the top corners\nand joins the bottom corners on the bottom left.<\/p>\n<p>Making a couple of smart remarks will make it easier to solve the problem:<\/p>\n<ul><li>it makes no sense to start out with a square;<\/li>\n<li>two circles in a row are superfluous;<\/li>\n<li>the solution uses circle at least three times;<\/li>\n<li>the solution ends with circle.<\/li>\n<\/ul><p>This shows that a hard minimum amount of moves we need is 5,\nbecause that is the sequence <code>&#9675;&#9109;&#9675;&#9109;&#9675;<\/code>, which is the absolute\nminimum we could need, as we need at least 3 circles and\nwe cannot have consecutive circles.\nThis clearly doesn't work, so the solution is at least 6 steps long.<\/p>\n<p>After that, and playing around a bit, you can figure out that\nthe shortest solution has eight steps and it is<\/p>\n<blockquote>\n<p><code>&#9675;&#9109;&#9109;&#9675;&#9109;&#9109;&#9109;&#9675;<\/code><\/p>\n<\/blockquote>\n<p>There is, obviously, a more rigorous solution that <em>proves<\/em> that this is the shortest solution.\nDoing so in paper involves keeping track of some branching possibilities, so I will do my best to...<\/p>","date_modified":"2025-07-23T16:49:02+02:00","tags":["automatons","combinatorics","graphs","mathematics"],"image":"\/user\/pages\/02.blog\/03.problems\/p033-syncro\/thumbnail.webp"},{"title":"Solving mazes with programming","date_published":"2017-11-29T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/solving-mazes-with-programming","url":"https:\/\/mathspp.com\/blog\/solving-mazes-with-programming","content_html":"<p>I have always loved solving mazes... so naturally I had to write a program to solve mazes for me!<\/p>\n\n<p><img alt=\"a black and white maze\" src=\"\/images\/3\/6\/e\/f\/c\/36efc6bd4eb9df9c15ae0f3af26f4b153a125eed-maze2.jpg\"><\/p>\n<p>Take a look at this maze; can you find a path from the upper left entrance in the maze to the lower right exit? Probably you can, and so does the program I wrote!<\/p>\n<p>I wrote a program in Python (making use of <code>pygame<\/code> and <code>Pillow<\/code>) to solve any maze given. I did this project several years ago, after learning about <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dijkstra's_algorithm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Dijkstra's algorithm<\/a>. I read about the algorithm and decided to implement it, to get a feel for it. I realized that I could apply it to a maze in a picture, if I took each pixel of the image to be a vertex in the graph where I'd apply the method.<\/p>\n<p>I wanted to make my program fairly general, in terms of the mazes that could be given, and so I dwelled with a problem: how to tell if two adjacent pixels should be connected in the graph or not. I knew I only wanted to connect pixels that referred to the path, and not to the walls, so my idea was simple: I supposed that a picture of a maze would have mainly two colours, one for the walls and another for the paths. I leveraged on that to preprocess the image and turn it to a black and white picture, where each pixel would be either completely white or completely black (I did this by finding the average luminosity of a pixel in the image and used that as a threshold; a pixel with luminosity below the average becomes black, otherwise it becomes white). After processing, ask the user for the two points we want to connect; if they have the same colour (say it was white) then it must have been because the paths have been changed into white and thus I need only to consider white pixels.<\/p>\n<p>After we know where to start, where to end, and which colour we care about (either black or white) I apply Dijkstra's algorithm on the graph of the vertices of that colour, where two vertices are connected if the two corresponding pixels are adjacent. Of course I didn't have to explicitly build the graph, as it was given by the pixels in the picture. After a path is found, a red line is drawn. The first version of the script would draw the absolute shortest path, and so it would mainly be adjacent to walls and I found it aesthetically unpleasing. To try and counter that I added a slight element of randomness when drawing the red path. Using my script to solve the maze above we get this drawing:<\/p>\n<p><img alt=\"the maze above but solved with a red line showing the path\" src=\"\/user\/pages\/02.blog\/solving-mazes-with-programming\/maze2_solved.webp\"><\/p>\n<p>which looks like a line I could draw with my pencil, if I managed to not overlap my line with the walls of the maze by accident. The code can be found in <a href=\"https:\/\/github.com\/RodrigoGiraoSerrao\/projects\/tree\/master\/MazeSolver\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this GitHub repo<\/a> and a downloadable executable can be found <a href=\"https:\/\/drive.google.com\/open\" id=\"1L7Ell-R4hUlN8Tutp10ycKyUq8kp5_c-\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">here<\/a>. In both...<\/p>","summary":"In this blog post I will be showing how I wrote a program to solve mazes for me.","date_modified":"2024-08-14T19:34:45+02:00","tags":["algorithms","graphs","image processing","programming","pygame","python","visualisation"],"image":"\/user\/pages\/02.blog\/solving-mazes-with-programming\/maze2.jpg"},{"title":"Water buckets riddle","date_published":"2017-11-21T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/water-buckets","url":"https:\/\/mathspp.com\/blog\/water-buckets","content_html":"<p>Can you measure exactly <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span>L of water with two plain buckets with volumes of <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span>L and <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span>L? Of course you can!<\/p>\n\n<figure class=\"image-caption\"><img title=\"Photo by Carolyn V on Unsplash\" alt=\"some gray tin (?) buckets\" src=\"\/images\/9\/3\/a\/c\/f\/93acfe4081371f2ddbcc471a44cd07ca25992aca-buckets.jpg\"><figcaption class=\"\">Photo by Carolyn V on Unsplash<\/figcaption><\/figure><p>The way you go about measuring those <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span>L of water is simple:<\/p>\n<ul><li>Pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>fill the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>fill the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>empty the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>fill the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>fill the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one, then<\/li>\n<li>fill the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket, then<\/li>\n<li>pour the <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> bucket into the <span class=\"mathjax mathjax--inline\">\\(14\\)<\/span> one<\/li>\n<\/ul><p>Piece of cake. Ok, maybe this sequence of moves is annoyingly long but this <em>is<\/em> a relatively well-known riddle and is a really interesting problem, honestly: given <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> buckets of capacities <span class=\"mathjax mathjax--inline\">\\(c_1, c_2, \\cdots, c_N\\)<\/span>, as well as a target value <span class=\"mathjax mathjax--inline\">\\(T\\)<\/span> and an infinite source of water, is there a sequence of moves that puts exactly <span class=\"mathjax mathjax--inline\">\\(T\\)<\/span> litres in one of the buckets?<\/p>\n<p>There are some cases for which one can immediately say that there is no such sequence. On one hand, if <span class=\"mathjax mathjax--inline\">\\(T &gt; c_i\\ \\forall i\\leq N\\)<\/span>, it is obvious we cannot do so; on the other hand, if such a sequence exists, then <span class=\"mathjax mathjax--inline\">\\(d = \\gcd{(c_1,\\cdots, c_N)} | T\\)<\/span>, i.e., if <span class=\"mathjax mathjax--inline\">\\(T\\)<\/span> is not a multiple of the greatest common divisor <span class=\"mathjax mathjax--inline\">\\(d\\)<\/span> of all the capacities, then the answer is no.<\/p>\n<p>I don't find it obvious that <span class=\"mathjax mathjax--inline\">\\(T\\)<\/span> being a multiple of <span class=\"mathjax mathjax--inline\">\\(d\\)<\/span> is sufficient to prove the existence of a solving sequence, even though we can find integer coefficients <span class=\"mathjax mathjax--inline\">\\(a_i\\)<\/span> such that <span class=\"mathjax mathjax--inline\">\\(a_1c_1 + \\cdots + a_Nc_N = T\\)<\/span> (which would hint on the sequence to be used) it feels like we could not be able to juggle the water in the buckets to hold the intermediate steps needed to get to the final solution.<\/p>\n<p>Even so, it was with astounding ease that I created a script to solve this problem, presenting the sequence of moves when there is a solving sequence and indicating that there is no such sequence when there is no solution. By \"astounding ease\" I mean that I was expecting it to be fairly difficult, but turned out not to be that complicated. I challenge you to try it for yourself. <em>Really<\/em>.<\/p>\n<p>Say we have <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> ordered buckets. We can represent how much each bucket is filled by a tuple <span class=\"mathjax mathjax--inline\">\\((w_1, \\cdots, w_N)\\)<\/span>. We can now think of all the tuples of length <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> that could represent a plausible state; that is, we can think of <span class=\"mathjax mathjax--inline\">\\(V = \\{(w_1,\\cdots, w_N) \\in \\mathbb{N}_0^N | w_i \\leq c_i \\}\\)<\/span> as the set of vertices of a directed graph, and then have an edge from <span class=\"mathjax mathjax--inline\">\\(a = (a_1, \\cdots, a_N)\\)<\/span> to <span class=\"mathjax mathjax--inline\">\\(b = (b_1,...<\/span><\/p>","summary":"This post goes over a well known riddle about measuring quantities.","date_modified":"2024-08-13T12:47:46+02:00","tags":["algorithms","graphs","mathematics","programming","python","number theory"],"image":"\/user\/pages\/02.blog\/water-buckets\/buckets.jpg"},{"title":"Problem #003 - a quarrel in the Shire","date_published":"2017-11-07T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/problems\/quarrel-in-the-shire","url":"https:\/\/mathspp.com\/blog\/problems\/quarrel-in-the-shire","content_html":"<p>Gandalf has some Hobbits to appease but his task seems to go on forever. Can you give him a hand..?<\/p>\n<!-- v -->\n\n<p><img alt=\"A picture of the Shire\" src=\"\/user\/pages\/02.blog\/03.problems\/p003-quarrel-in-the-shire\/shire.jpg\"><\/p>\n<p>Once again I bring you a problem alongside my proposed solution. If you find any mistakes or come up with a different solution, please let me know!<\/p>\n<!-- ^ -->\n<h2 id=\"problem-statement\">Problem statement<a href=\"#problem-statement\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The Shire is a lovely place where <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> Hobbits live in perfect harmony. Or at least they lived, until a Hobbit decided to become an outside decorator and convinced some of his friends to paint their front doors with a very <em>fashionable<\/em> purple (all doors were yellow before that preposterous change).<\/p>\n<p>Overnight, the perfect balance and harmony in which the Hobbits lived shattered, and Hobbits whose doors were different colours couldn't stand one another.<\/p>\n<p>Worried, the great and wise Gandalf hurried to the Shire to try and settle this matter. This was what he decided to do: in alphabetical order, he would visit each Hobbit. When visiting a Hobbit, he would change the colour of its door if and only if there were more Hobbits mad at him than there were Hobbits at peace with him. After visiting each Hobbit once, he would visit them all again in the same order, and then again, and then again, ..., repeating this process until a complete round of visits didn't change a thing.<\/p>\n<p>Is Gandalf's task always going to end, regardless of <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> and of the way the doors are coloured when he first arrives? Or are there values of <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> and\/or door colourings such that Gandalf will have to spend an eternity trying to solve the Hobbits' problems?<\/p>\n<div class=\"notices blue\">\n<p>Give it some thought... Grab a piece of paper and play out some scenarios by hand!<\/p>\n<\/div>\n<p>If you need any clarification whatsoever, feel free to ask in the comment section below.<\/p>\n<div class=\"notices green\">\n<p><strong>Hint<\/strong>: Gandalf's endeavour is always a finite one.<\/p>\n<\/div>\n<div class=\"notices green\">\n<p><strong>Hint<\/strong>: look for a \"semi-invariant\"; a quantity that can only change in a certain way, which allows you to verify that Gandalf will rest eventually.<\/p>\n<\/div>\n<h2 id=\"solution\">Solution<a href=\"#solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Gandalf's task always has an end. To see why, imagine the <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span> Hobbits represented as dots, and every two Hobbits are connected by a line. That line is green if they are friendly towards each other (their front doors have the same colour) and red if their front doors have different colours. Now count the number of red lines in that representation and call it <span class=\"mathjax mathjax--inline\">\\(R_0\\)<\/span>, where the <span class=\"mathjax mathjax--inline\">\\(0\\)<\/span> indicates the number of visits Gandalf has already paid to the Hobbits. If Gandalf already visited <span class=\"mathjax mathjax--inline\">\\(t\\)<\/span> Hobbits, let <span class=\"mathjax mathjax--inline\">\\(R_t\\)<\/span> denote the number of red lines in the representation I defined earlier.<\/p>\n<p>It should be fairly easy to see that we have <span class=\"mathjax mathjax--inline\">\\(R_{t+1} \\leq R_t\\)<\/span>. This is true because when Gandalf visits a Hobbit, he will only change its door if that means the number of green lines increases, i.e. the number of red lines decreases. This means only two things can happen:<\/p>\n<ul><li>For a certain <span class=\"mathjax mathjax--inline\">\\(k\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(R_k = 0\\)<\/span> and that means all Hobbits...<\/li><\/ul>","summary":"Gandalf from Lord of The Rings is the star of this brain teaser...","date_modified":"2025-07-23T16:49:02+02:00","tags":["invariants","mathematics","graphs"],"image":"\/user\/pages\/02.blog\/03.problems\/p003-quarrel-in-the-shire\/shire.jpg"}]}
