5 Absurd Ways to Add Two Numbers in Python

Absurd Ways to Add Two Numbers in Python Featured Image

If you know me, you know I love to play around with silly ways to solve problems with programming languages. Today is no different! This time, let’s see how many ways we can add two numbers in Python.

Table of Contents

Inspiration

If you take some time to explore the site, you’ll find that I love programming languages, especially the impractical ones. What I love even more is pushing these languages to their limits, not just in terms of performance but also in less practical and more creative ways. For instance, I recently saw the following meme on Twitter—or at least what’s left of it:

And in case Twitter dies in the near future, here’s a text copy of the tweet:

The legacy code they told you not to touch

from time import sleep, time

def add(num1, num2):
  """
  adds two positive integers
  """
  start = time()
  sleep(num1)
  sleep(num2)
  return int(time() - start)
@iammemeloper

As is hopefully obvious, this is s joke, but it’s a joke the sheds light on the variety of ways we can solve problems. As a result, I thought I’d take a stab at this meme myself by attempting to come up with a few other silly ways to add two numbers together.

Absurd Ways to Add Two Numbers Together

As it turns out, finding ways to add two numbers together is actually kind of challenging. So much of what we do in software development relies on implicit arithmetic that we don’t even realize it’s happening. That said, I had quite a bit of fun trying to put together this list, so enjoy!

The Baseline: The Addition Operator

To start off the list, it’s probably worth actually adding two numbers the way most folks do by using the addition operator:

def add(num1, num2):
  return num1 + num2

In this example, we add two numbers together by taking the two numbers and combining them with the addition operator. Nothing spicy so far!

Absurd Case #1: The Addition Function

For all of the basic operators in Python, there are functional overloads. We can wrap these overloads to create our own addition function:

from operator import add as op_add

def add(num1, num2):
  return op_add(num1, num2)

Again, this isn’t too wacky, but it’s definitely out of the norm for most cases.

Absurd Case #2: Childhood Algorithm

When you’re a kid, you learn to add each place value one at a time. What if we did that for our addition function?

def add(num1, num2):
  total_sum = num1 // 10
  num2_smaller = num2 // 10
  if num2_smaller != 0:
    total_sum = add(total_sum, num2_smaller)
  ones_place_sum = num1 % 10 + num2 % 10
  if ones_place_sum > 9:
    ones_place_sum -= 10
    total_sum += 1
  return total_sum * 10 + ones_place_sum

One of the challenges with an algorithm like this, beyond its absurdity, is that it doesn’t quite work for decimal values. That said, we’re not here for correctness; we’re here for fun!

Regardless, the underlying idea is that we’re adding together the “ones” place of each number and letting the recursion take care of the rest. In this case, all of the addition goes from num2 into num1, so recursion ends when there is nothing else to add from num2.

Absurd Case #3: Bitwise Arithmetic

A remarkably simpler but far less readable solution involves the recursive use of bitwise operators.

def add(num1, num2):
  if num2 == 0:
    return num1
  return add(num1 ^ num2, (num1 & num2) << 1)

Like with the previous solution, the general approach is to add num2 to num1. The way the addition is executed however is through the underlying binary representation. For example, if we were adding 5 to 2, the recursive call would read: add(5 ^ 2, (5 & 2) << 1). The first parameter is computing the exclusive OR between the two numbers, which evaluates to 7 because the exclusive OR between 0b101 and 0b010 is 0b111. Interestingly, 7 happens to be the sum between 5 and 2, but the only way for this to work would be for the second parameter to be 0. Fortunately, the second parameter is computing AND between the two numbers before shifting the bits one position to the left, which evaluates to 0 because AND between 0b101 and 0b010 is 0b000 with nothing to shift.

For any pair of numbers that would result in a binary carry, such as the sum of 5 and 3, an extra recursive call is necessary. You can try visualizing how this works with the actually binary values since it’s not immediately obvious in base 10.

Absurd Case #4: Data Structure Size

Up to this point, all the solutions made use of different mathematical approaches to getting the correct answer, but I’m interested in the truly absurd. Surely, there are ways to compute addition that are nonsensical like the one from the tweet. Unfortunately, many of the ways I brainstormed all involved some form of counting, which is addition at its core. Then, I considered importing a third-party library because that’s a common meme. Finally, I settled on using a data structure for performing addition for me. Under the hood, it probably relies on addition, but I like the idea of storing items representing actual values. Here’s the result:

def add(num1, num2):
  element = [...]
  items = element * num1
  items.extend(element * num2)
  return len(items)

Here, we lazily create a list with one item in it, an ellipsis. The ellipsis is just a placeholder that we use to scale the size of the list for math purposes. Then, we generate a list from the placeholder list and one of the inputs. A similar process occurs in the next line when we extend the original list with another scaled list from the other input. Finally, the sum is the result of a call to the length of the list.

Again, this solution only works for integers, but it’s interesting just how many ways addition can be computed without actually using the operator we all know and love.

Pitching to ChatGPT

I’ve been somewhat of a machine learning hater, but I figured this is probably the perfect activity for a tool like ChatGPT. As a result, I made an account and asked it for its own absurd solutions to this problem.

As expected, it kicked things off with an iterative solution using bitwise operators:

def add_numbers(a, b):
    while b != 0:
        carry = a & b
        a = a ^ b
        b = carry << 1
    return a

# Example usage
num1 = 10
num2 = 5
result = add_numbers(num1, num2)
print(result)  # Output: 15

When I asked for another solution, it gave the same recursive solution:

def add_numbers(a, b):
    if b == 0:
        return a
    else:
        return add_numbers(a ^ b, (a & b) << 1)

# Example usage
num1 = 10
num2 = 5
result = add_numbers(num1, num2)
print(result)  # Output: 15

As expected, things sort of went off the rails quickly as soon as I restricted the use of bitwise operators. Immediately, ChatGPT generated illegal code by suggesting that a “successor” function exists for integers:

def add_numbers(a, b):
    if b == 0:
        return a
    else:
        return add_numbers(a.successor(), b - 1)

# Example usage
num1 = 10
num2 = 5
result = add_numbers(num1, num2)
print(result)  # Output: 15

When I called it out, it returned to using bitwise operators. Even after rephrasing the prompt to explicitly disallow the addition operator and bitwise operators, it just abstracted them into methods.

Eventually, I decided to ask it to come up with an absurd way to add two numbers, but the code was so broken that I couldn’t really tell what it was trying to do aside from making use of some lookup table. It would have been way funnier if it just generated a list of if statements for every combination of two integers.

At any rate, it seems I can go back to being a machine learning hater, or perhaps I’m just a bad “prompt engineer.” That said, it was fun to use!

Do You Love Programming Languages?

At some point in your journey of software development, you’ll probably gain an appreciation not just for the craft but also for the tools related to the craft. For many of us, the tools we use are called programming languages, and they each have their own quirks. I grew more deeply interested in them in 2018 when I started the Sample Programs repoOpens in a new tab.. I’m more hands off these days, but there are still folks helping grow the collection—such as folks like you.

If you’d rather keep reading, I won’t stop you! Here are some related articles:

And while you’re at it, here are some Python resources (#ad):

Finally, you can go above and beyond by checking out my list of ways to grow the site, which features a Discord, a Patreon, and a YouTube channel. Otherwise, thanks for sticking around and take care!

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Posts