One of the key skills required for engineering is the ability to reach some goal, complying with several constraints. Many times these constraints prevent you from going from A to B on a straight line, and you are required to find sideway methods, or avoid using the most obvious approach.

The corresponding pattern is "how can you do X without using Y?". This is the same pattern for the successful first Schindler Milan office weekly riddle [1], as well as the pattern for the second one, that I’m going to describe in this post.

This puzzle, I devised as prescribed for the winner of the previous one, is about determining the least of two numbers without using the **if** statement. After all, **if** statement can be tricky and someone already pointed out that **if** statement should be considered harmful [2] in the same way the "harmful" **goto** statement is [3].

The puzzle had many submissions, that I’m going to present alongside my solution. In the interest of presentation, I will not attribute solutions. To all purposes here, you may consider them a team effort.

I have classified the submissions by their approach to the solution. There are five main approaches:

- Comparison expressions evaluate to 1 if they are true and 0 if they are false
- Using library functions
- Bending other conditional constructs
- Using math
- Using information theory

One of the original design goals of C was simplicity. It had to be a simple language so that the compiler would be easy to write. Stemming from BCPL [4] where there was just one type - **int** - C also got rid of extra types, notably strings and boolean expressions (and defaulted types to **int**).

So every boolean expression (e.g. *a>b*) is of type **int** and evaluates to 1 if the expression is *true*, or 0 if the expression is *false*.

This can be leveraged in a number of ways to determine the lower value between two numbers, in this way:

Esoteric programming languages [8] have the expressive power to make you laugh. Once you get over the confusing and exhilarating syntax, it’s easy to identify the input request for two numbers and the output of the lowest.

I believe that most of these esoteric languages are translated into C and then compiled, that’s why they could inherit some C behaviors, rather than by design.

Although it may seem like cheating, I considered using a library function a valid solution. First, hiding a low-level construct under a higher abstraction level contraption is the right way to go, since it enables us to tackle increasingly complex problems. Moreover, knowing your tools is always an important asset for programmers, regardless of the language and the library used.

This is the shortest version (the same code in C++ is one line longer):

Other library usage includes various applications of containers.

For example, you can fill a container with the two values and then sorting it -

We can find a different take on containers in this solution:

**std::find_if** doesn’t find any item that satisfies the predicate, then it returns the **end()** iterator. Since **end()** is one past the last item of the range, it *points* to the other value.

Two solutions are based on sets. This is the first one -

This uses C++20 ranges, **std::views::iota** produces a sequence of integers from the first to the second argument. Then, an output vector is filled with the intersection. Per construction, the intersection is equal to the set with the lower cardinality. And cardinality of the intersection is the solution.

The other solution uses sets, but determines the smaller one, by trying to access it out of range:

Note the use of this **std::vector** constructor that creates a vector of size equal to the value of the first argument and then fills the vector with the value of the second argument.

I liked this solution for the creative approach and the creative application of exceptions, and the peculiar use of vectors.

Note that relying on set cardinality works only for positive integers (which is consistent with my formulation of the problem).

It is true that the **if** statement is the first we turn to when we need to make a binary decision, but the conditional branching - core to the Turing Machine - resurfaces also in other commands - **switch**, **for** and **while** just to name a few.

You can bend the while statement -

Or conditional expression shortcuts:

*x < y* yields true. The shortcut to **&&** cannot be applied since the right-hand side term may be false. Evaluating **result = x **always yields true, but when x is 0, in that case, the result is false. The use of the comma operator discards this result and replaces it with its right-hand side term, i.e. true. Now the shortcut kicks in for || since the result is not determined.

There are two directions for employing mathematics: devise a formula that produces the lower of two numbers or approach it with arithmetic and sequence.

Finding a formula is not rightly intuitive, but it can be achieved by considering the two values as points A and B on a line. There will be a medium point M equally distant from A and B. If you subtract half of the distance AB from M, then you get the lower value. This is what my solution does -

Another way to put it -

As put by the author - *This relies on the fact that [abs(x-y) - (x - y)] = 0 if x > y, else it is equal to 2 * abs(x-y). The solution works ONLY if x is different from y (otherwise there is a division by 0)*.

Another arithmetic solution is to go down from x and y to zero and count the iterations:

This solution applies only to positive integers.

The last mathematical solution is based on randomness:

Although most programmers are familiar with the concept of Turing’s Machine [10], much fewer have ever been in touch with Alonzo Church’s work [11].

Alonzo Church was a bright mathematician. Besides being a teacher of Turing, Church devised a computational model based on functions named Lambda Calculus [12]. It has been demonstrated that Lambda calculus is equivalent to Turing’s Machine, meaning that any algorithm that can be implemented on a Turing’s Machine can also be implemented with Lambda calculus.

The solution to the problem implemented in Lambda calculus is quite convoluted and I fully explain it in my blog [13]. A quick rough idea presentation follows. Just keep in mind that in lambda calculus, everything (really everything) is a function.

First numbers to compare have to be converted into a special notation called Church’s numerals [14]. This notation that encodes the numbers is a well-defined pattern of functions.

The next step is to subtract the two numbers with a properly defined subtraction, which yields zero when you try to subtract a greater value from a lesser value.

A function for checking zero is then used to understand which number is the least one. And the *if* instruction is defined to call the *then* branch or *else* branch according to the *if* argument.

Of course, no one would write production code like this [15] in the same way no one would write code using Turing’s Machine notation. On the other hand, I find it very fascinating how something so functional, in the mathematical sense, can compute algorithms.

Being purely functional opens the way to mathematical tools and, therefore, to rock-solid certainties.

I tried for a while to write this in C++, but I haven’t found a good solution that avoids slicing, so I resorted to a better-suited language – Scala:

This has been another really entertaining riddle proving that lateral thinking is a precious resource to get us out of sticky situations.

A task that could be deemed impossible at first sight turns out to be accomplished in many different ways. Surely most of them are impractical or even laughable, but this is like brainstorming where the goal is not to produce the perfect solution, but to explore the solution space and to get around all the roadblocks set by the problem.

**Special Thanks**

I’d like to mention here all the colleagues that contributed with their solutions to the contest – Anna, Domenico, Mario, Matteo, Nicola and Phuong. Thank you, without your code this post wouldn’t have been happened.

**About the Author**

Massimiliano Pagani started coding back in the 80s, when computers were laughably slow, never had enough RAM and used tape recorders as storage memory. Since then, he never stopped writing bugs and other features. He worked in the video game industry, had some exposure to server and service development, got fascinated by functional programming, and spent several years in writing firmware and embedded software. When he is struck by something he reckons interesting, and has enough spare time, he writes on his blog at https://www.maxpagani.org/.

**References**

[1] https://group.schindler.com/en/media/stories/coding-riddle-of-the-week.html

[2] If statement considered harmful https://www.youtube.com/watch?v=z43bmaMwagI

[3] Goto statement considered harmful (PDF) https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf

[4] BCPL programming language https://en.wikipedia.org/wiki/BCPL

[5] Definition of Zero element https://en.wikipedia.org/wiki/Absorbing_element

[6] Definition of Identity element https://en.wikipedia.org/wiki/Identity_element

[7] LOLCODE esoteric programming language http://www.lolcode.org/

[8] Esoteric programming languages https://en.wikipedia.org/wiki/Esoteric_programming_language

[9] Random Number Generator https://dilbert.com

[10] Turing Machine https://en.wikipedia.org/wiki/Turing_machine

[11] Alonzo Church https://en.wikipedia.org/wiki/Alonzo_Church

[12] Lambda Calculus https://en.wikipedia.org/wiki/Lambda_calculus

[13] Full explanation of lambda calculus solution https://www.maxpagani.org/2022/09/29/lambda-headache-for-mere-mortals/

[14] Church Numerals https://en.wikipedia.org/wiki/Church_encoding

[15] How to write code if all you have is a Scala compiler and nothing else https://www.maxpagani.org/2018/02/12/lambda-world-2017-lambda-core-hardcore/

[16] Von Neumann https://en.wikipedia.org/wiki/John_von_Neumann