
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/recursion","feed_url":"https:\/\/mathspp.com\/blog\/tags\/recursion.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":"Recursive structural pattern matching","date_published":"2026-01-08T16:22:00+01:00","id":"https:\/\/mathspp.com\/blog\/recursive-structural-pattern-matching","url":"https:\/\/mathspp.com\/blog\/recursive-structural-pattern-matching","content_html":"<p>Learn how to use structural pattern matching (the match statement) to work recursively through tree-like structures.<\/p>\n\n<p>In this short article you will learn to use <a href=\"\/blog\/pydonts\/structural-pattern-matching-tutorial\">structural pattern matching<\/a> in recursive, tree-like data structures.<\/p>\n<p>The examples from this article are taken from a couple of <a href=\"\/insider\">recent issues of my weekly newsletter<\/a>.<\/p>\n<h2 id=\"a-recursive-data-structure\">A recursive data structure<a href=\"#a-recursive-data-structure\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Structural pattern matching excels at... matching the structure of your objects!\nFor the two examples in this article, we'll be using a number of dataclasses that you can use to build abstract Boolean expressions:<\/p>\n<pre><code class=\"language-py\">from dataclasses import dataclass\n\nclass Expr:\n    pass\n\n@dataclass\nclass And(Expr):\n    exprs: list[Expr]\n\n@dataclass\nclass Or(Expr):\n    exprs: list[Expr]\n\n@dataclass\nclass Not(Expr):\n    expr: Expr\n\n@dataclass\nclass Var(Expr):\n    name: str<\/code><\/pre>\n<p>For example, the code <code>Not(And([Var(\"A\"), Var(\"B\")]))<\/code> represents the Boolean expression <code>not (A and B)<\/code>.<\/p>\n<h2 id=\"evaluating-a-boolean-expression\">Evaluating a Boolean expression<a href=\"#evaluating-a-boolean-expression\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Suppose you have a Boolean expression built out of the components shared above.\nHow do you evaluate that formula if you are given the assignments that map the variables to their values?<\/p>\n<p>For example, if you have the assignments <code>{\"A\": True, \"B\": False}<\/code> (for example, a dictionary that maps variable names to values), how can you determine that the expression <code>Not(And([Var(\"A\"), Var(\"B\")]))<\/code> is <code>True<\/code>?<\/p>\n<p>This is where structural pattern matching can be applied recursively and it's where it really shines!<\/p>\n<p>To solve this problem, you will write a function called <code>evaluate(expression: Expr, assignments: dict[str, bool]) -&gt; bool<\/code>.\nYour function accepts an expression and the assignments in the form of a dictionary and it returns the final Boolean value the expression evaluates to.<\/p>\n<p>Since you're accepting an expression, you're going to use the <code>match<\/code> statement on the full expression and then create a <code>case<\/code> branch for each of the possible expressions you might have:<\/p>\n<ol><li>a variable;<\/li>\n<li>an <code>And<\/code> expression;<\/li>\n<li>an <code>Or<\/code> expression; or<\/li>\n<li>a <code>Not<\/code> expression.<\/li>\n<\/ol><p>The structure of the code looks like this:<\/p>\n<pre><code class=\"language-py\">def evaluate(expression: Expr, assignments: dict[str, bool]) -&gt; bool:\n    match expression:\n        case Var(): pass\n        case And(): pass\n        case Or(): pass\n        case Not(): pass<\/code><\/pre>\n<p>The trick here is realising that you're using <code>Expr<\/code> as the type of the argument but really, you always expect the argument to be an instance of one of the subclasses of <code>Expr<\/code>, and not a direct <code>Expr<\/code> instance.<\/p>\n<p>However, to make sure you don't trip on a weird bug later on, and because this matching is supposed to be exhaustive &ndash; you're supposed to have one <code>case<\/code> for each subclass of <code>Expr<\/code> &ndash; you can defend yourself by including a catch-all pattern that raises an error.<\/p>\n<p>When I'm being lazy, I just raise a <code>RuntimeError<\/code>:<\/p>\n<pre><code class=\"language-py\">def evaluate(expression: Expr, assignments: dict[str, bool]) -&gt; bool:\n    match expression:\n        case Var(): pass\n        case And(): pass\n        case Or(): pass\n        case Not(): pass\n        case _:\n            raise RuntimeError(\n                f\"Couldn't evaluate expression of type {type(expression)}.\"\n            )<\/code><\/pre>\n<p>Now, it's just a matter of implementing the evaluation logic.\nIn the case of a variable, all you have to do is fetch the variable value from the corresponding dictionary.\nHowever, to make it more convenient to...<\/p>","summary":"Learn how to use structural pattern matching (the match statement) to work recursively through tree-like structures.","date_modified":"2026-01-08T19:23:42+01:00","tags":["python","programming","recursion"],"image":"\/user\/pages\/02.blog\/recursive-structural-pattern-matching\/thumbnail.webp"},{"title":"Beating LinkedIn \u201cQueens\u201d with Python","date_published":"2025-02-25T18:40:00+01:00","id":"https:\/\/mathspp.com\/blog\/beating-linkedin-queens-with-python","url":"https:\/\/mathspp.com\/blog\/beating-linkedin-queens-with-python","content_html":"<p>This is a short account of how I wrote a program that solves all LQueens puzzles from LinkedIn automatically with Python.<\/p>\n\n<p>About a year ago LinkedIn started publishing a daily logic puzzle called &ldquo;Queens&rdquo;.\nThis puzzle is a crossover between the <a href=\"\/blog\/problems\/8-queens\">queen-placing puzzle from chess<\/a> and Sudoku, and takes place in a square grid with a number of heterogeneous coloured regions, as the image below demonstrates:<\/p>\n<figure class=\"image-caption\"><img title=\"Queens puzzle #179.\" alt='A screenshot showing the text \"Puzzle 179 Appeared on 26 October 2024\" and a coloured grid that is 8 by 8 with 8 coloured regions of heterogeneous shapes.' src=\"\/user\/pages\/02.blog\/beating-linkedin-queens-with-python\/_puzzle.webp\"><figcaption class=\"\">Queens puzzle #179.<\/figcaption><\/figure><h2 id=\"puzzle-rules\">Puzzle rules<a href=\"#puzzle-rules\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The rules for the puzzle are quite simple.\nYou have to place one queen on each coloured region while also making sure that:<\/p>\n<ul><li>there is one and only one queen per row and column; and<\/li>\n<li>queens cannot touch each other, not even diagonally.<\/li>\n<\/ul><p>See if you can solve the puzzle above, for example by visiting <a href=\"https:\/\/www.archivedqueens.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this unofficial archive<\/a>.\n(Make sure to select the same puzzle as I'm showing above, number 179.)<\/p>\n<h2 id=\"solving-the-puzzle\">Solving the puzzle<a href=\"#solving-the-puzzle\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I write algorithms for things like this all the time &ndash; which is a bit of a weird thing to be experienced on, but oh well... &ndash;, so solving the puzzle in Python was actually quite straightforward.<\/p>\n<p>I decided to represent the board as a list of sets, where each set contains the coordinates of the cells of a coloured region.\nFor example, puzzle 179 shown above would be represented as the following list of sets:<\/p>\n<pre><code class=\"language-py\">[\n    {(0, 1), (4, 0), (0, 0), (7, 0), (2, 0), (3, 0), ...},  # yellow\n    {(7, 4), (7, 1), (2, 1), (7, 7), (3, 1), (6, 1), ...},  # orange\n    {(2, 4), (0, 4), (0, 3), (1, 4), (0, 6), (0, 2), ...},  # blue\n    {(2, 3), (3, 2), (1, 2), (2, 2)},                       # green\n    {(6, 2), (4, 3), (4, 2), (3, 3), (5, 2)},               # gray\n    {(2, 5), (3, 4), (3, 5), (1, 5)},                       # red\n    {(4, 4), (5, 5), (6, 5), (5, 4), (4, 5)},               # purple\n    {(0, 7), (2, 7), (3, 7), (4, 6), (5, 7), (1, 7), ...},  # brown\n]<\/code><\/pre>\n<p>The good stuff lies in the function <code>solve<\/code>.\nThe function <code>solve<\/code> is a recursive function that accepts the list with coloured groups that don't have a queen yet and returns the list of positions where queens must go.<\/p>\n<p>How does the function know it's done?\nIf it receives an empty list of coloured groups, then that means all groups received a queen, and we can start producing the list of queen positions:<\/p>\n<pre><code class=\"language-py\">def solve(group_sets):\n    if not group_sets:\n        return []\n\n    # ...<\/code><\/pre>\n<p>That's the best possible scenario, because that's when the function is already done.\nBut usually, the function has work to do.<\/p>\n<p>If the list of coloured groups is not empty, then the function looks at the very first coloured group, which should be <code>group_sets[0]<\/code>, and traverses that set of positions, one position at a time:<\/p>\n<pre><code class=\"language-py\">    for tx, ty in group_sets[0]:<\/code><\/pre>\n<p>The <code>tx<\/code> and <code>ty<\/code> and the x and y coordinates for the <em>tentative<\/em> position of the queen of the current coloured group.\nBut let us assume, for a second,...<\/p>","summary":"This is a short account of how I wrote a program that solves all Queens puzzles from LinkedIn automatically with Python.","date_modified":"2025-07-23T16:49:02+02:00","tags":["algorithms","image processing","python","programming","recursion","slice of life"],"image":"\/user\/pages\/02.blog\/beating-linkedin-queens-with-python\/thumbnail.webp"},{"title":"Animating a tree fractal","date_published":"2025-01-12T19:10:00+01:00","id":"https:\/\/mathspp.com\/blog\/animating-a-tree-fractal","url":"https:\/\/mathspp.com\/blog\/animating-a-tree-fractal","content_html":"<p>This article walks through the code used to animate a tree fractal.<\/p>\n\n<p>I really enjoy fractals and for the longest time I've been meaning to draw the classical tree fractal that starts with the main trunk which then successively splits into two branches, that themselves can be seen as the full tree.<\/p>\n<p>Today I quickly put together the code to do this and then I animated the rotation of the tree to make sure it's easy to see the self-similarity of the tree.<\/p>\n<p>This is the animated GIF that I produced:<\/p>\n<p><img alt=\"Animated GIF of a tree fractal rotating and zooming in, so that the end position is the same as the starting position, displaying the self-similarity properties of the fractal.\" src=\"\/user\/pages\/02.blog\/animating-a-tree-fractal\/_tree.gif?decoding=auto&amp;fetchpriority=auto\"><\/p>\n<h2 id=\"drawing-the-tree\">Drawing the tree<a href=\"#drawing-the-tree\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To draw the tree I wrote a recursive function (obviously!) that draws a trunk and then recursively draws the remainder of the tree.\nTo &ldquo;recursively draw the remainder of the tree&rdquo; I needed to compute the two trunks that stem from the trunk I just drew, so to do that I:<\/p>\n<ul><li>computed the direction of the trunk I just drew as a numpy vector;<\/li>\n<li>rotated this vector by 60 degrees (clockwise and counter-clockwise);<\/li>\n<li>scaled down this vector; and<\/li>\n<li>used it to compute the two new trunks.<\/li>\n<\/ul><p>The recursive function looks like this:<\/p>\n<pre><code class=\"language-py\">def tree(screen, start, to, depth=0):\n    if depth &gt;= 15:\n        return\n    sx, sy = start\n    tx, ty = to\n    pygame.draw.line(\n        screen,\n        BLACK,\n        (WIDTH \/\/ 2 + sx, HEIGHT \/\/ 2 - sy),\n        (WIDTH \/\/ 2 + tx, HEIGHT \/\/ 2 - ty),\n        1,\n    )\n    direction = np.array([[tx - sx], [ty - sy]])\n    for angle in [pi \/ 3, -pi \/ 3]:\n        rot = np.array(\n            [\n                [cos(angle), -sin(angle)],\n                [sin(angle), cos(angle)],\n            ]\n        )\n        new_direction = ((rot @ ((direction) \/ 1.7))).reshape((2,))\n        tree(screen, to, to + new_direction, depth + 1)<\/code><\/pre>\n<p>One important thing that I ended up doing, and that explains the weird calculations inside the call to <code>pygame.draw.line<\/code>, is that I decided to do all calculations as if the coordinate system were the standard one from maths class: the origin is at the centre of the pygame window and the values of the coordinate y increase by going up, not by going down.\nThen, I need to convert from this sytem to the pygame system right before drawing, which is why I add <code>(WIDTH \/\/ 2, HEIGHT \/\/ 2)<\/code> to the points we're drawing and then for the y coordinate I need to use the symmetric value (<code>-y<\/code> instead of <code>y<\/code>) to compensate for the fact that the y axis is flipped.<\/p>\n<p>The full script to draw the tree looks like this:<\/p>\n<pre><code class=\"language-py\">from math import sin, cos, pi\nimport sys\n\nimport numpy as np\nimport pygame\nimport pygame.locals\n\nWIDTH, HEIGHT = 600, 400\n\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nscreen = pygame.display.set_mode((WIDTH, HEIGHT))\n\ndef tree(screen, start, to, depth=0):\n    ...\n\ndef main() -&gt; None:\n    screen.fill(WHITE)\n    tree(screen, np.array((0, -200)), np.array((0, 0)))\n    pygame.display.flip()\n    pygame.image.save(screen, \"tree.png\")\n\n    while True:\n        for event in pygame.event.get():\n            if event.type == pygame.locals.QUIT:\n                pygame.quit()\n                sys.exit(0)\n\nif __name__ == \"__main__\":\n    main()<\/code><\/pre>\n<h2 id=\"animating-the-tree\">Animating the tree<a href=\"#animating-the-tree\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To make it easier to animate the tree I first started by splitting the function <code>tree<\/code> in two:<\/p>\n<ol><li>a...<\/li><\/ol>","summary":"This article walks through the code used to animate a tree fractal.","date_modified":"2025-07-23T16:49:02+02:00","tags":["fractals","mathematics","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/animating-a-tree-fractal\/thumbnail.webp"},{"title":"Reverse-engineering the \u201cChronospatial Computer\u201d","date_published":"2024-12-21T09:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/reverse-engineering-the-chronospatial-computer","url":"https:\/\/mathspp.com\/blog\/reverse-engineering-the-chronospatial-computer","content_html":"<p>Reverse-engineering the program from &ldquo;Chronospatial Computer&rdquo;, day 17 of Advent of Code 2024.<\/p>\n\n<p>The &ldquo;Chronospatial Computer&rdquo; is from <a href=\"https:\/\/adventofcode.com\/2024\/day\/17\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Advent of Code 2024, day 17<\/a>, a problem that entertained me for a couple of hours.<\/p>\n<h2 id=\"parsing-the-input\">Parsing the input<a href=\"#parsing-the-input\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>My input file looked like this:<\/p>\n<pre><code class=\"language-txt\">Register A: 64012472\nRegister B: 0\nRegister C: 0\n\nProgram: 2,4,1,7,7,5,0,3,1,7,4,1,5,5,3,0<\/code><\/pre>\n<p>To read the input and parse it I used a context manager and a couple of calls to <code>readline<\/code>:<\/p>\n<pre><code class=\"language-py\">with open(\"input.txt\", \"r\") as f:\n    register_a = int(f.readline().split()[-1])\n    register_b = int(f.readline().split()[-1])\n    register_c = int(f.readline().split()[-1])\n    _ = f.readline()\n    program = [int(num) for num in f.readline().split()[-1].split(\",\")]\n\nprint(program, register_a, register_b, register_c)<\/code><\/pre>\n<h2 id=\"solving-part-1-with-functional-programming\">Solving part 1 with functional programming<a href=\"#solving-part-1-with-functional-programming\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Part 1 required me to simulate a series of simple instructions that operate on three registers.\nWhen I read the problem statement, I decided I wanted to use some ideas from functional programming.\nSo, what I did was to separate each operator (there are 8) into three parts:<\/p>\n<ol><li>the part that performs some computation with the registers and\/or with the operand;<\/li>\n<li>the part that updates the state of the program, maybe by updating a register or by outputting a value; and<\/li>\n<li>the part that updates the pointer of the program, which controls the instruction that will run next.<\/li>\n<\/ol><p>By using <code>lambda<\/code> functions, <a href=\"\/blog\/pydonts\/dunder-methods\">dunder methods<\/a>, and <a href=\"\/blog\/functools-partial\">currying with <code>functools.partial<\/code><\/a>, each list below represents one of the three parts of each opcode.<\/p>\n<p>First, the computation part of each operation:<\/p>\n<pre><code class=\"language-py\">registers = [0, 1, 2, 3, register_A, register_B, register_C]\nA, B, C = 4, 5, 6  # Indices of the named registers in the list `registers`.\n\ncomputations = [\n    lambda o: registers[A] \/\/ pow(2, registers[o]),  # ADV\n    lambda o: registers[B] ^ o,                      # BXL\n    lambda o: registers[o] % 8,                      # BST\n    lambda o: ...,                                   # JNZ\n    lambda o: registers[B] ^ registers[C],           # BXC\n    lambda o: registers[o] % 8,                      # OUT\n    lambda o: registers[A] \/\/ pow(2, registers[o]),  # BDV\n    lambda o: registers[A] \/\/ pow(2, registers[o]),  # CDV\n]<\/code><\/pre>\n<p>In the lambda functions above, when we use <code>o<\/code> in isolation, we're using the operand as a literal operand, whereas the list <code>registers<\/code> maps an operand into its combo operand.\nBy using this list, we can map the numbers 0 through 3 to themselves and the indices 4, 5, and 6, to the registers A, B, and C, respectively, without having to use a conditional statement.<\/p>\n<p>The operation <code>JNZ<\/code> has a lambda function that does nothing because there is no proper computation for this operator.<\/p>\n<p>Then, I wrote a list with all the functions that update the state of the program:<\/p>\n<pre><code class=\"language-py\">from functools import partial\n\noutput = []\nstate_updates = [\n    partial(registers.__setitem__, A),\n    partial(registers.__setitem__, B),\n    partial(registers.__setitem__, B),\n    lambda v: ...,\n    partial(registers.__setitem__, B),\n    output.append,\n    partial(registers.__setitem__, B),\n    partial(registers.__setitem__, C),\n]<\/code><\/pre>\n<p>This uses the <a href=\"\/blog\/pydonts\/dunder-methods\">dunder method <code>__setitem__<\/code><\/a> and <a href=\"\/blog\/functools-partial\">the function <code>functools.partial<\/code><\/a> to create a function that accepts a single value and that writes that value to the correct register in the list <code>registers<\/code>.<\/p>\n<p>Finally, all operators move the program pointer by two positions except the operator <code>JNZ...<\/code><\/p>","summary":"Reverse-engineering the program from \u201cChronospatial Computer\u201d, day 17 of Advent of Code 2024.","date_modified":"2025-07-23T16:49:02+02:00","tags":["algorithms","mathematics","modular arithmetic","programming","python","recursion"],"image":"\/user\/pages\/02.blog\/reverse-engineering-the-chronospatial-computer\/thumbnail.webp"},{"title":"Solving \u201cBridge Repair\u201d in 4ms with Python","date_published":"2024-12-07T19:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/solving-bridge-repair-in-4ms-with-python","url":"https:\/\/mathspp.com\/blog\/solving-bridge-repair-in-4ms-with-python","content_html":"<p>Solving &ldquo;Bridge Repair&rdquo;, from day 7 of Advent of Code 2024, in 4ms with Python with a simple deductive algorithm.<\/p>\n\n<p>Today I solved the problem from <a href=\"https:\/\/adventofcode.com\/2024\/day\/7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Advent of Code 2024, day 7<\/a> in 4ms using Python.\nMy first solution used brute-force and ran in 15 seconds.\nIt was very easy to implement and I got the job done quite quickly.\nBut then I thought about using a smarter algorithm, and I got a solution that's over 4,000 times faster and that runs in under 4ms.\nI will describe both solutions in this article.<\/p>\n<p>(It should be obvious by now, but this article contains spoilers!)<\/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>In short, given a target integer and a list of integers, can we use addition, multiplication, and concatenation, to manipulate the list of integers to equal the target integer?\nThere is the added restriction that the operations are always evaluated from left to right and the integers cannot be reordered.<\/p>\n<p>Here are some examples that are possible:<\/p>\n<pre><code>5: 2 3\n6: 2 3\n23: 2 3\n94: 2 4 9 5<\/code><\/pre>\n<p>To make <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span> with <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span> and <span class=\"mathjax mathjax--inline\">\\(3\\)<\/span> we can do <span class=\"mathjax mathjax--inline\">\\(5 = 2 + 3\\)<\/span>.\nTo make <span class=\"mathjax mathjax--inline\">\\(6\\)<\/span> with <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span> and <span class=\"mathjax mathjax--inline\">\\(3\\)<\/span> we can multiply the two numbers and to make <span class=\"mathjax mathjax--inline\">\\(23\\)<\/span> with <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span> and <span class=\"mathjax mathjax--inline\">\\(3\\)<\/span> we can concatenate the two digits.\nFinally, to make <span class=\"mathjax mathjax--inline\">\\(94\\)<\/span> with the integers <span class=\"mathjax mathjax--inline\">\\(2\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(4\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(9\\)<\/span>, and <span class=\"mathjax mathjax--inline\">\\(5\\)<\/span>, we start by multiplying, then we concatenate, and then we add.\nIf we use <span class=\"mathjax mathjax--inline\">\\(||\\)<\/span> to represent concatenation, then <span class=\"mathjax mathjax--inline\">\\(94 = ((2 \\times 4) || 9) + 5\\)<\/span>.<\/p>\n<h2 id=\"brute-force-solution-15-seconds\">Brute-force solution, 15 seconds<a href=\"#brute-force-solution-15-seconds\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To determine if a certain list of numbers can be manipulated to match the target value, we can write a function that generates all distinct sequences of operators and then tries to use each sequence of operators in turn.<\/p>\n<p>Using <code>itertools.product<\/code>, we can generate all sequences of distinct operators quite easily:<\/p>\n<pre><code class=\"language-py\">from itertools import product\nfrom operator import add, mul\n\nvalid_operators = [\n    add,\n    mul,\n    lambda x, y: int(f\"{x}{y}\")\n]\n\ndef is_valid(target, operands):\n    operator_sequences = product(valid_operators, repeat=len(operands) - 1)\n    start, *head = operands\n    for operators in operator_sequences:\n        total = start\n        for operator, operand in zip(operators, head):\n            total = operator(total, operand)\n        if total == target:\n            return True\n    return False\n\nprint(is_valid(94, [2, 4, 9, 5]))<\/code><\/pre>\n<p>Advent of Code provides an <a href=\"\/blog\/solving-bridge-repair-in-4ms-with-python\/.\/input.txt\">input file with 850 tests<\/a> and this code takes slightly over 15 seconds to classify all 850 tests on my machine.\nNow, I will show you how you can speed this up by a factor of 2,000.<\/p>\n<h2 id=\"deducing-valid-operations-4-milliseconds\">Deducing valid operations, 4 milliseconds<a href=\"#deducing-valid-operations-4-milliseconds\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The faster algorithm is conceptually very simple.\nDisappointingly simple.\nInstead of working from the front to the back, trying random operations and seeing if they work out in the end, we work from the back to the front.<\/p>\n<p>For example, consider the target <code>94<\/code> and the list of integers <code>[2, 4, 9, 5]<\/code>.\nIf this is a possible case, then the final operation must be an addition.\nWhy?<\/p>\n<p>The...<\/p>","summary":"Solving \u201cBridge Repair\u201d, from day 7 of Advent of Code 2024, in 4ms with Python with a simple deductive algorithm.","date_modified":"2025-07-23T16:49:02+02:00","tags":["algorithms","mathematics","programming","python","recursion"],"image":"\/user\/pages\/02.blog\/solving-bridge-repair-in-4ms-with-python\/thumbnail.webp"},{"title":"N queens problem","date_published":"2024-02-09T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/n-queens-problem","url":"https:\/\/mathspp.com\/blog\/n-queens-problem","content_html":"<p>This article shows how to solve the N queens problem in 20 lines of code.<\/p>\n\n<h2 id=\"the-problem-for-n-10\">The problem for N = 10<a href=\"#the-problem-for-n-10\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>(You can <a href=\"#the-solution\">skip to the solution<\/a> or just <a href=\"#the-code\">see the code<\/a>.)<\/p>\n<p>&ldquo;Do you understand what you have to do?&rdquo;, Queen #6 asks.<\/p>\n<p>&ldquo;Uh, I&ndash; I think so.&rdquo;<\/p>\n<p>The challenge sounded simple enough but I was a bit intimidated by the Ten Queens all looking at me.<\/p>\n<p>They stood tall in front of me.\nAn impeccable pose, worthy of a Queen.\nTimes ten.<\/p>\n<p>They looked rigid and cold, wearing their white and black dresses.\nBut if you looked carefully enough, they also looked...\nThey looked... hopeful!\nThey believed I would be able to help them.<\/p>\n<p>I wasn&rsquo;t feeling confident and Queen #8 picked up on that, so she decided to recap what they needed:\n&ldquo;Like my sister #6 said, we need to distribute ourselves on this 10 &times; 10 board.\nThe goal is to <em>count<\/em> in how many different ways this can be done.<\/p>\n<p>We like to have room to pace a bit, so no two of us can be on the same row, column, or diagonal.\nThis restriction is essential.&rdquo;<\/p>\n<p>I nodded along while she recapped.\nThen, I asked &ldquo;How on Earth am I supposed to compute this?\nI can&rsquo;t do this with pen and paper!&rdquo;.<\/p>\n<p>All Queens started laughing uncontrollably.\nQueen #1 managed to control herself for long enough to reply.<\/p>\n<p>&rdquo;You silly! You use Python, of course!&rdquo;\nShe waved.<\/p>\n<p>The two pawns at the entrance of the room we were in opened the massive doors.\nAs the huge doors creaked and opened slowly, four pawns came into the hall, carrying a computer.\nThe computer was already turned on.\nAs the computer moved closer, this is what I saw on the screen:<\/p>\n<pre><code>Python 3.12.0 (the Ten Queens build)\nType \"help\" for more information.\n&gt;&gt;&gt;<\/code><\/pre>\n<p>&ldquo;You have one week.\nYou can start now.&rdquo;<\/p>\n<p>I walked up to the computer and started working on the problem.<\/p>\n<h2 id=\"the-solution\">The solution<a href=\"#the-solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I was thinking aloud while I was typing.<\/p>\n<p>&ldquo;We know that no two queens can be on the same row or column.\nAnd that's easy to enforce in my code.\nI'll traverse the columns and put one of you in each column while also not repeating rows.\nIt's the diagonals that I have to be careful about.&rdquo;<\/p>\n<p>I paused for a bit.\nThen I wrote this function:<\/p>\n<pre><code class=\"language-py\">def diagonally_safe(row, col, placements):\n    for qrow, qcol in enumerate(placements):\n        if row - col == qrow - qcol or row + col == qrow + qcol:\n            return False\n    return True<\/code><\/pre>\n<p>I proceeded to explain:<\/p>\n<p>&ldquo;I'll store a tuple called <code>placements<\/code> with the positions of some of you.\nThe index is the row you're in and the value itself represents the column.\nFor example, if <code>placements<\/code> is <code>(5, 0, 4)<\/code> that means that the row <code>0<\/code> has a queen in column <code>5<\/code>, the row <code>1<\/code> has a queen in column <code>0<\/code>, and the row <code>3<\/code> has a queen in column <code>4<\/code>.&rdquo;<\/p>\n<p>The queens...<\/p>","summary":"This article shows how to solve the N queens problem in 20 lines of code.","date_modified":"2025-09-27T16:50:04+02:00","tags":["algorithms","combinatorics","logic","programming","python","recursion"],"image":"\/user\/pages\/02.blog\/n-queens-problem\/thumbnail.webp"},{"title":"(More) Animations from first principles","date_published":"2023-09-08T12:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/more-animations-from-first-principles-in-5-minutes","url":"https:\/\/mathspp.com\/blog\/more-animations-from-first-principles-in-5-minutes","content_html":"<p>Create a zooming animation from first principles in Python. In 5 minutes. Kind of.<\/p>\n\n<video width=\"400\" height=\"400\" poster=\"\/blog\/more-animations-from-first-principles-in-5-minutes\/_zoom_triangle.mp4.thumb.png\" controls><source src=\"\/blog\/more-animations-from-first-principles-in-5-minutes\/_zoom_triangle.mp4\" type=\"video\/mp4\">\n  You can't watch the video animation of a recursive triangular structure, zooming in and rotating, animated with a Python and pygame script.\n<\/source><\/video><p>This is a follow-up to my recent article called <a href=\"\/blog\/animations-from-first-principles-in-5-minutes\">&ldquo;Animations from first principles (in 5 minutes)&rdquo;<\/a>.\nIn that article, we created a simple animation with Python and pygame.<\/p>\n<p>In <em>this<\/em> article, we will create a different type of animation, where we will draw a recursive triangular structure that can be zoomed in indefinitely.\nWe'll be using Python and <code>pygame<\/code>, so make sure you install it in your preferred way, and make sure it was installed properly:<\/p>\n<pre><code class=\"language-pycon\">&gt;&gt;&gt; import pygame\npygame 2.5.1 (SDL 2.28.2, Python 3.11.4)\nHello from the pygame community. https:\/\/www.pygame.org\/contribute.html<\/code><\/pre>\n<p>The code in this article was written with Python 3.11 and <code>pygame<\/code> 2.5.1.\nHowever, it should run well on older versions of Python\/<code>pygame<\/code> because we're only using fundamental features that have been around for a while and that are unlikely to go anywhere.<\/p>\n<h2 id=\"in-5-minutes\">In 5 minutes?<a href=\"#in-5-minutes\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I have no idea if you can go through this in 5 minutes.\nYou'll likely need more time if these ideas are new to you and you're typing the code yourself.\nHowever, I did present most of this material in 5 minutes in <a href=\"\/talks\">a lightning talk at PyCon Portugal<\/a>.<\/p>\n<h2 id=\"i-ll-cheat-a-bit\">I'll cheat a bit<a href=\"#i-ll-cheat-a-bit\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>For this demo, I'll cheat a bit and I will add a little bit of boilerplate for free.\nThis is a class <code>Point<\/code> that I'm using to represent 2D points.\nThe idea is to make it easier to add and subtract points, and to multiply and divide points by numbers.<\/p>\n<p>The class <code>Point<\/code> looks like this:<\/p>\n<pre><code class=\"language-py\">class Point:\n    def __init__(self, x, y):\n        self.values = (x, y)\n\n    def __add__(self, other):\n        x, y = self.values\n        x_, y_ = other.values\n        return Point(x + x_, y + y_)\n\n    def __sub__(self, other):\n        x, y = self.values\n        x_, y_ = other.values\n        return Point(x - x_, y - y_)\n\n    def __mul__(self, other):\n        return Point(self.values[0] * other, self.values[1] * other)\n\n    __rmul__ = __mul__\n\n    def __truediv__(self, other):\n        return Point(self.values[0] \/ other, self.values[1] \/ other)\n\n    @property\n    def length(self):\n        return self.values[0] ** 2 + self.values[1] ** 2<\/code><\/pre>\n<p>It uses <a href=\"\/blog\/pydonts\/overloading-arithmetic-operators-with-dunder-methods\">arithmetic dunder methods<\/a> and a <a href=\"\/blog\/pydonts\/properties\">property<\/a>, but it is just so I can do operations like <code>Point(1, 2) + Point(3, 4)<\/code> or <code>3 * Point(1, 0)<\/code>.<\/p>\n<p>With this out of the way, let us start!<\/p>\n<h2 id=\"creating-the-canvas-to-draw-on\">Creating the canvas to draw on<a href=\"#creating-the-canvas-to-draw-on\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Just like last time, we'll start by making sure we can get a black screen in front of us:<\/p>\n<pre><code class=\"language-py\">import pygame\n\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nscreen = pygame.display.set_mode((400, 400))\nscreen.fill(BLACK)\n\nwhile True:\n    pygame.display.flip()<\/code><\/pre>\n<p>The code above fills a 400 by 400 screen with black and then it refreshes it forever.\nIf you run this program, you'll see a black screen:<\/p>\n<figure class=\"image-caption\"><img title=\"A black screen.\" alt=\"\" src=\"\/user\/pages\/02.blog\/more-animations-from-first-principles-in-5-minutes\/_black_screen.webp\"><figcaption class=\"\">A black screen.<\/figcaption><\/figure><p>To close this window, you'll need to interrupt <em>the Python shell where you ran your program<\/em>.<\/p>\n<h2 id=\"drawing-a-triangle\">Drawing a triangle<\/h2>...","summary":"Create a zooming animation from first principles in Python. In 5 minutes. Kind of.","date_modified":"2025-07-23T16:49:02+02:00","tags":["fractals","geometry","mathematics","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/more-animations-from-first-principles-in-5-minutes\/thumbnail.webp"},{"title":"TIL #064 \u2013 open recursion","date_published":"2023-06-19T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/open-recursion","url":"https:\/\/mathspp.com\/blog\/til\/open-recursion","content_html":"<p>Today I learned what open recursion is and how to leverage it.<\/p>\n\n<h2 id=\"open-recursion\">Open recursion<a href=\"#open-recursion\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Open recursion is a technique in which two methods of an object call each other recursively.\nThe power of this technique resides in the fact that the two methods can be implemented independently.<\/p>\n<p>A silly example of open recursion (in Python) is as follows:<\/p>\n<pre><code class=\"language-py\">class Fib:\n    def _even(self, n):\n        if n == 0:\n            return 1\n        else:\n            return self._odd(n - 1) + self._even(n - 2)\n\n    def _odd(self, n):\n        if n == 1:\n            return 1\n        else:\n            return self._even(n - 1) + self._odd(n - 2)\n\n    def compute(self, n):\n        if n % 2:\n            return self._odd(n)\n        else:\n            return self._even(n)\n\nprint(Fib().compute(16))<\/code><\/pre>\n<p>Notice that <code>_even<\/code> calls <code>_odd<\/code> and <code>_odd<\/code> calls <code>_even<\/code>, and that is the open recursion pattern.\nNow, this example is pretty silly.\nAre there good uses for open recursion?<\/p>\n<h2 id=\"using-open-recursion-in-interpretation-of-programs\">Using open recursion in interpretation of programs<a href=\"#using-open-recursion-in-interpretation-of-programs\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Going over <a href=\"https:\/\/github.com\/IUCompilerCourse\/Essentials-of-Compilation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">&ldquo;Essentials of Compilation, An Incremental Approach in Python&rdquo;<\/a>, we create a simple interpreter in Chapter 1 that can handle additions and subtractions of integers, along with a couple of other things.<\/p>\n<p>Such an interpreter could be written recursively, somewhat like this:<\/p>\n<pre><code class=\"language-py\">from ast import Add, BinOp, Constant\n\ndef interpret_1(expr, env):\n    match expr:\n        case Constant(value):\n            return value\n        case BinOp(lexpr, Add(), rexpr):\n            return interpret_1(lexpr, env) + interpret_1(rexpr, env)\n        ...<\/code><\/pre>\n<p>Then, in Chapter 2, the author wants us to extend this interpreter to also handle variables.\nA naive approach would be to handle variables explicitly in <code>interpret_2<\/code> and then defer to <code>interpret_1<\/code> for the other cases, like so:<\/p>\n<pre><code class=\"language-py\">def interpret_2(expr, env):\n    match expr:\n        case Name(id):\n            return env[id]\n        case _:\n            return interpret_1(expr, env)<\/code><\/pre>\n<p>However, this approach will <em>not<\/em> work!\nWhat if there is a variable that appears further down the tree?\nAs soon as the function <code>interpret_2<\/code> calls <code>interpret_1<\/code>, we arrive at a place where variables cannot be handled!<\/p>\n<p>For example, the tree <code>tree1<\/code> below can be handled by <code>interpret_2<\/code> but the tree <code>tree2<\/code> cannot, because it will be dispatched to <code>interpret_1<\/code> and then <code>interpret_1<\/code> will not know how to handle the <code>Name(\"foo\")<\/code>.<\/p>\n<pre><code class=\"language-py\">from ast import Add, BinOp, Constant, Name\n\ntree1 = Name(\"foo\")\n\ntree2 = BinOp(\n    Name(\"foo\"),\n    Add(),\n    Constant(5),\n)<\/code><\/pre>\n<p>Instead of laying out our code with the two independent functions, we can have an interpreter class that is inherited whenever we want to extend our interpreter, and we use <strong>open recursion<\/strong> to make sure that the &ldquo;old&rdquo; interpret function gets to leverage <em>its own override<\/em>!<\/p>\n<p>Here is the code:<\/p>\n<pre><code class=\"language-py\">from ast import Add, BinOp, Constant, Name\n\nclass Interpreter1:\n    def interpret(self, expr, env):\n        match expr:\n            case Constant(value):\n                return value\n            case BinOp(lexpr, Add(), rexpr):\n                return self.interpret(lexpr, env) + self.interpret(rexpr, env)\n\nclass Interpreter2(Interpreter1):\n    def interpret(self, expr, env):\n        match expr:\n            case Name(id):\n                return env[id]\n            case _:\n                return super().interpret(expr, env)<\/code><\/pre>\n<p>The key here is that <code>Interpreter2.interpret<\/code> will call <code>Interpreter1.interpret<\/code> via the <code>super().interpreter<\/code> call.\nIn turn, inside that call, the <code>self.interpret<\/code> will refer to <code>Interpreter2.interpret<\/code>, which will allow us to go back and forth between the two implementations of <code>interpret<\/code>.<\/p>\n<p>Here is an example, after...<\/p>","summary":"Today I learned what open recursion is and how to leverage it.","date_modified":"2025-07-23T16:49:02+02:00","tags":["programming","python","recursion"],"image":"\/user\/pages\/02.blog\/04.til\/064.open-recursion\/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":"The formula that plots itself","date_published":"2019-04-24T15:32:00+02:00","id":"https:\/\/mathspp.com\/blog\/the-formula-that-plots-itself","url":"https:\/\/mathspp.com\/blog\/the-formula-that-plots-itself","content_html":"<p>This post gives you the code to mess around with \"Tupper's self-referential formula\", a formula that plots itself.<\/p>\n\n<p>By the end of this blog post, I hope that you know how to make mathematical drawings and why the number<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN \\approx 4.85845063618971342358209596 \\times 10^{543}\\]<\/p>\n<p>is so special.<\/p>\n<p>Given a function <span class=\"mathjax mathjax--inline\">\\(f(x, y)\\)<\/span>, how can you use it to make a drawing? Well, we just imagine the whole plane as a white, clean grid, and then we fill with black the squares at the positions <span class=\"mathjax mathjax--inline\">\\((x,y)\\)<\/span> such that <span class=\"mathjax mathjax--inline\">\\(f(x,y) &gt; \\frac{1}{2}\\)<\/span>. In a way, it is as if the function <span class=\"mathjax mathjax--inline\">\\(f\\)<\/span> is telling us whether to use white or black, i.e., to leave the square empty (<span class=\"mathjax mathjax--inline\">\\(0\\)<\/span>) or filled in (<span class=\"mathjax mathjax--inline\">\\(1\\)<\/span>).<\/p>\n<p>(More rigorously, we divide the plane into unit squares and assign each square the coordinates of its lower-left corner.)<\/p>\n<p>If we take, for example, <span class=\"mathjax mathjax--inline\">\\(f(x, y) = x + y\\)<\/span>, then square <span class=\"mathjax mathjax--inline\">\\((0,0)\\)<\/span> would be white because <span class=\"mathjax mathjax--inline\">\\(f(0, 0) = 0 &lt; \\frac{1}{2}\\)<\/span> but the squares <span class=\"mathjax mathjax--inline\">\\((0, 1)\\)<\/span> and <span class=\"mathjax mathjax--inline\">\\((1, 0)\\)<\/span> would be black because <span class=\"mathjax mathjax--inline\">\\(f(0, 1) = f(1, 0) = 1 &gt; \\frac{1}{2}\\)<\/span>.<\/p>\n<p>As another example, take <span class=\"mathjax mathjax--inline\">\\(f\\)<\/span> to be this function:<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nf(x, y) = \\left\\lfloor \\text{mod}\\left(\\left\\lfloor\\frac{y}{17} \\right\\rfloor 2^{-17\\lfloor x \\rfloor -  \\text{mod}(\\lfloor y \\rfloor, 17)}, 2\\right) \\right\\rfloor\\]<\/p>\n<p>where <span class=\"mathjax mathjax--inline\">\\(\\lfloor n \\rfloor\\)<\/span> denotes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Floor_and_ceiling_functions\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">floor function<\/a> and <span class=\"mathjax mathjax--inline\">\\(\\text{mod}(a, b)\\)<\/span> denotes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Modulo_operation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">modulo operator<\/a>. This function looks way more interesting, doesn't it? Yes, it does! And if you look in the right place, this is what is plotted by this function:<\/p>\n<figure class=\"image-caption\"><img title=\"The formula, drawn.\" alt=\"A plot showing the Tupper formula written in black in a pixelated font.\" src=\"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/_tupper_formula.webp\"><figcaption class=\"\">The formula, drawn.<\/figcaption><\/figure><p>What is going on here..? The function I just showed you, called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tupper's_self-referential_formula\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Tupper's self-referential formula<\/a>, is a formula that plots itself! But you might be suspicious because I said <em>if you look in the <strong>right<\/strong> place<\/em>. What is this <em>place<\/em> then?<\/p>\n<p>Quite simply, define<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN=4858450636189713423582095962494202044581400587983244549483093085061934704708809928450644769865524364849997247024915119110411605739177407856919754326571855442057210445735883681829823754139634338225199452191651284348332905131193199953502413758765239264874613394906870130562295813219481113685339535565290850023875092856892694555974281546386510730049106723058933586052544096664351265349363643957125565695936815184334857605626529915320311182856118951164066401426579727262440270286409619368825536815027849325692956320299303330714849102058741137034502,\\]<\/p>\n<p>(a 544-digit-long number). Then, the image I showed you is the rectangular area with the lower-left corner <span class=\"mathjax mathjax--inline\">\\((0, N)\\)<\/span> and the upper-right corner <span class=\"mathjax mathjax--inline\">\\((105, N + 16)\\)<\/span> (so it is a <span class=\"mathjax mathjax--inline\">\\(106 \\times 17\\)<\/span> rectangle). Quite impressive, right? Self-references are always fun!<\/p>\n<p>But that is not all... If you look hard enough, you can find literally anything inside that <span class=\"mathjax mathjax--inline\">\\(106\\times17\\)<\/span> rectangle! For example, taking<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN=677269797063266389145771001639366162904443300634759368354244105189144417475687924080590138582401925400953401198762670070868017028632609067495842127259345485889052110555312844858658969250766978033911456684637024394115209279287448522343527514061700072005928325124098808483476326307953390156875355289624192978628506335125351370018499785193486797521350328711540234844414805471938182060305235921541912512179523099720166772353828125144439537587189530425493554812515912471900753848603802337280,\\]<\/p>\n<p>you can find the name of this site \"mathspp\" and a winking face \";)\":<\/p>\n<figure class=\"image-caption\"><img title=\"mathspp ;)\" alt='The text \"mathspp ;)\" drawn in black in a pixelated font.' src=\"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/_tupper_mathspp.webp\"><figcaption class=\"\">mathspp ;)<\/figcaption><\/figure><p>Now the really important question is... How does one find such values for <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span>? Well, you can watch <a href=\"https:\/\/www.youtube.com\/watch?v=_s5RFgd59ao\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this Numberphile YouTube video<\/a>, or I can tell you all about it...<\/p>\n<p>You start with a <span class=\"mathjax mathjax--inline\">\\(106\\times17\\)<\/span> grid and you colour it (with black\/white) the way you want. Then you will construct a bit sequence: you start on the top-right corner, and write down a <span class=\"mathjax mathjax--inline\">\\(1\\)<\/span> if that square is black, <span class=\"mathjax mathjax--inline\">\\(0\\)<\/span> if that square is white. Then you go down one square, and repeat. You do this column by column, top to bottom, right to left. When you finish, you convert your bit sequence...<\/p>","summary":"This post gives you the code to mess around with \u201cTupper&#039;s self-referential formula\u201d, a formula that plots itself.","date_modified":"2025-07-23T16:49:02+02:00","tags":["binary","mathematics","modular arithmetic","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/thumbnail.webp"}]}
