{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/modular-arithmetic","feed_url":"https:\/\/mathspp.com\/blog\/tags\/modular-arithmetic.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":"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":"

Reverse-engineering the program from “Chronospatial Computer”, day 17 of Advent of Code 2024.<\/p>\n\n

The “Chronospatial Computer” is from Advent of Code 2024, day 17<\/a>, a problem that entertained me for a couple of hours.<\/p>\n

Parsing the input<\/a><\/h2>\n

My input file looked like this:<\/p>\n

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

To read the input and parse it I used a context manager and a couple of calls to readline<\/code>:<\/p>\n

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

Solving part 1 with functional programming<\/a><\/h2>\n

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

  1. the part that performs some computation with the registers and\/or with the operand;<\/li>\n
  2. the part that updates the state of the program, maybe by updating a register or by outputting a value; and<\/li>\n
  3. the part that updates the pointer of the program, which controls the instruction that will run next.<\/li>\n<\/ol>

    By using lambda<\/code> functions, dunder methods<\/a>, and currying with functools.partial<\/code><\/a>, each list below represents one of the three parts of each opcode.<\/p>\n

    First, the computation part of each operation:<\/p>\n

    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

    In the lambda functions above, when we use o<\/code> in isolation, we're using the operand as a literal operand, whereas the list 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

    The operation JNZ<\/code> has a lambda function that does nothing because there is no proper computation for this operator.<\/p>\n

    Then, I wrote a list with all the functions that update the state of the program:<\/p>\n

    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

    This uses the dunder method __setitem__<\/code><\/a> and the function 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 registers<\/code>.<\/p>\n

    Finally, all operators move the program pointer by two positions except the operator 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":"Base conversion in Python","date_published":"2024-01-07T10:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/base-conversion-in-python","url":"https:\/\/mathspp.com\/blog\/base-conversion-in-python","content_html":"

    This article shows how to do base conversions in Python with the built-in int, how to write integer literals in other bases, and how to do base conversions in general.<\/p>\n\n