Nicholas Westby

No Ifs, Ands, or Elses: Swap Numbers Brain Teaser

Nicholas Westby
No Ifs, Ands, or Elses: Swap Numbers Brain Teaser

Somebody recently explained to me a brain teaser they were given during an interview:

Given a function that accepts a number (either 5 or 7), return the opposite number. Give as many examples as you can of how to implement this without using an if statement.
— Brain Teaser From Interviewer

Should interviewers be asking brain teasers like this? Perhaps not. People don’t always do their most lateral thinking during interviews they may see as high pressure.

For the purposes of this article, who cares! Brain teasers are fun, so let’s see how we can solve this one.

First, let’s start off with the obvious implementation that isn’t allowed (since it uses an if statement):

function swap(n) {
  if (n == 5) {
    return 7;
  }
  return 5;
}

Now we just need to do that a dozen or so times without the use of an if statement. These are the solutions some others came up with (consider these to be pseudo-code):

Group Solutions

Group Solution 1: XOR

function swap(n) {
  // XOR to toggle the second bit.
  return xor(n, 2);
}

Group Solution 2: Array Lookup

function swap(n) {
  return [7, 0, 5][n - 5];
}

Group Solution 3: Substring

function swap(n) {
  return parse("705".charAt(n - 5));
}

Group Solution 4: Negative Distance

function swap(n) {
  return 12 - n;
}

Group Solution 5: Division

function swap(n) {
  return 35 / n;
}

Group Solution 6: Dictionary / Hashmap

function swap(n) {
  return {5: 7: 7: 5}[n];
}

Group Solution 7: Modulus

function swap(n) {
  return 7 - (n % 5);
  // Or:
  return (7 % n) + 5;
}

My Solutions

Whew, that was a lot of ideas. But we can go even further. Here are some ideas I had:


My Solution 8: Ternary

function swap(n) {
  return n == 5 ? 7 : 5;
}

My Solution 9: Switch

function swap(n) {
  switch (n) {
    case 5:
      return 7;
    default:
      return 5;
  }
}

My Solution 10: Try Catch

function swap(n) {
  try {
    const x = 1 / (n - 5);
  } catch {
    return 7;
  }
  return 5;
}

My Solution 11: Pivot Around Zero

function swap(n) {
  // This equation reduces to the same
  // formula as the 4th solution.
  return -(n - 6) + 6;
}

My Solution 12: Digits of Pi

function swap(n) {
  // Remember, this is pseudo-code,
  // so we'll assume this function exists.
  return DigitOfPi(156 + n);
}

My Solution 13: Missing Side of Triangle

function swap(n) {
  // a^2 + b^2 = c^2
  return sqrt(74 - n * n);
}

My Solution 14: Threads

function swap(n) {
  thread1 = new Thread(() => {
    Thread.Sleep(5);
    r = 7;
  });

  thread2 = new Thread(() => {
    Thread.Sleep(7);
    r = 5;
  });

  thread1.Start();
  thread2.Start();

  Thread.Sleep(n + 1);

  return r;
}

My Solution 15: Sine Wave

function swap(n) {
  // I don't feel like figuring out the constants.
  return a * sin(n * b + c) + d;
}

My Solution 16: Code Generation

function swap(n) {
  const Get5 = () => 7;
  const Get7 = () => 5;
  return eval("Get" + n + "()");
}

My Solution 17: While Loop

function swap(n) {
  while (n == 5) {
    return 7;
  }
  return 5;
}

My Solution 18: For Loop

function swap(n) {
  for (let i = 6; i < n;) {
    return 5;
  }
  return 7;
}

My Solution 19: Filter Values

function swap(n) {
  return [5, 7].First(x => x != n);
}

My Solution 20: Count Pixels

function swap(n) {
  // The "5" would take up more pixels than "7".
  const canvas = new Canvas(4, 4);
  return CountPixels(DrawText(
    n.ToString(), canvas));
}

Solution 21: Count Intersections

function swap(n) {
  // The diagonal line cross "5" 3 times
  // and "7" 1 time.
  const degrees = 45;
  return 4 + CountIntersections(degrees,
    DrawText(n.ToString()));
}

Solution 22: Factorial String Length

function swap(n) {
  return (factorial(n).ToString().Length
    - 3.5) * -2 + 6;
}

Solution 23: Bit Masking

function swap(n) {
  return 7 - (n & 2);
}


Summary of Techniques

That seems like a lot of solutions, but there are just a few techniques used:

  • Bit Manipulation. This involves noting that there is a similarity or difference in particular bits of each number. In particular, the second least significant bit (2, aka 0x00000010).

    1. Used by these solutions: XOR, Bit Masking

  • Collection Lookups. This involves using the number as a key/index to find the corresponding number in a collection.

    • Used by: Array Lookup, Substring, Dictionary / Hashmap

  • Math Equations. This involves finding a numeric equation that converts each number into its counterpart.

    • Used by: Negative Distance, Division, Modulus, Pivot Around Zero, Missing Side of Triangle, Sine Wave

  • Control Flow Statements. These are really if statements in disguise. They allow you to use a statement to conditionally change the flow of code.

    • Used by: Ternary, Switch, Try Catch, While Loop, For Loop

  • Timing. This uses some element of time to determine the outcome. This is essentially a very specialized control flow statement (a very inefficient one).

    • Used by: Threads

  • Code Generation. This is another very specialized control flow statement. We’re using string manipulation to determine the code we want to execute.

    • Used by: Code Generation

  • Filtering. This is akin to a collection lookup, but it’s not exactly using an index or key. Instead, the values are the focus, and equality is used to determine the output.

    • Used by: Filter Values

  • Visual. These rely on some aspect of the input that can be represented visually (e.g., as pixels). These are some of the least straightforward solutions, as they rely on a specific representation of a number (even particular fonts and formatting could impact these).

    • Used by: Count Pixels, Count Intersections

  • Composite Solutions. These are really combining several other techniques into one. For example, the digits of pi is a combination of math equations and collection lookups (since pi is essentially a collection of digits).

    • Used by: Digits of Pi, Factorial String Length

Not bad! We came up with 9 unique types of solutions. If you really want a challenge, try to think of even more!

(And I really hope interviewers are not using this sort of question during an interview.)