Click here to Skip to main content
15,885,216 members
Articles / Programming Languages / C#

How Bresenham Got Five Programmers Into Two Cars?

Rate me:
Please Sign up or sign in to vote.
3.73/5 (6 votes)
23 Jun 2016CPOL3 min read 10K   2   7
How Bresenham got five programmers into two cars?

Introduction

So I’m 43 and the other night I finally asked myself the all- important question. How to get five programmers into two cars?

Well… you invite three to the first car and two to the second car. That is not so difficult. The formula for calculating how many programmers you can put to one car is:

But what if the objective was optimal performance? What if we wanted the algorithm to work on old 8-bit systems that allowed us only limited tools: (positive) integer numbers, addition, and comparison. There is no floating point, no negative integer numbers, and no division. Now how do you get five programmers into two cars?

Using the Code

I invented a tiny algorithm just for that. I call this trick the weighted iterative division. And it is designed to work when there are more programmers than cars.

C#
int N = 5; // Programmers.
int M = 2; // Cars.

// Weighted sums. 
int sumN = M;
int sumM = N;

int programmer = 1;
int car = 1;
while (programmer <= N)
{
    Console.WriteLine("Put programmer {0} to car {1}.", programmer, car);
    if (sumN >= sumM) { sumM += N; car++; }
    sumN += M;
    programmer++;
}

What we are doing here is very basic math. If floating point was allowed, we would multiply programmer with M/N (i.e. 0.4). Let us write this as an equation:

By multiplying both sides of the equation with N, we get:

Now the job of our algorithm is to iteratively keep this equation in balance. As soon as the left side is smaller, we add a new car (add N to the left side). And every time we add a new programmer, we add M to the right side. Here is how algorithm evolves 5 programmers.

Programmer # Left side Right side Car #
1 5 2 1
2 5 2 + 2 1
3 5 2 + 2 + 2 1
4 5 + 5 2 + 2 + 2 + 2 2
5 5 + 5 2 + 2 + 2 + 2 + 2 2
How does it work:

We already discovered that left side of the equation is N * car and right side of the equation is M * programmer. Left side counts cars and right side counts programmers. Hence 5 + 5 on the left side means 2 * car weight (5). And 2 + 2 + 2 on the right side means 3 * programmer weight (2). 

You initially put one programmer 1 in car 1. Next you put programmer 2 into car 1. The right side is now 2 + 2 which is 2 * programmer weight. The equation is still not balanced. So you put programmer 3 into car 1. Right side is now 3 * programmer weight (2 + 2 + 2 = 6). It is now larger then left side. The equation is balanced. So in the next step you add a car on the left side (hence 5 + 5 which is 2 * car weight). You proceed by adding the fourth and the fifth programmer to car 2. Last step has equation in balance. 

Let us optimize this just a bit more to come to an interesting conclusion. If we allow using negative integer numbers, then instead of calculating left and right side of the equation, we can just calculate the difference between them.

C#
int N = 5; // Programmers.
int M = 2; // Cars.
int D = M - N;
int programmer = 1;
int car = 1;
while (programmer <= N)
{
    Console.WriteLine("Put programmer {0} to car {1}.", programmer, car);
    if (D > 0) { D -= N; car++; }
    D += M;
    programmer++;
}

Now the algorithm starts to look familiar. It is, indeed, a close relative of Bresenham line drawing algorithm where D is our error and we’re iteratively correcting it.

Points of Interest

This method was originally developed for mapping line length N pixels to line length M pixels for projective transformations. It was inspired by the Quadrilateral Distortion article. The logic can be used in any situation where a very fast mapping from N items to M items is required. It is equivalent to drawing a bresenham line where dx=N and dy=M.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Wischner Ltd
United Kingdom United Kingdom
Writing code since 1982 and still enjoying it.

Comments and Discussions

 
QuestionAlternative to Bresenham Pin
YvesDaoust24-Jun-16 2:50
YvesDaoust24-Jun-16 2:50 
QuestionAlternative to Bresenham Pin
YvesDaoust24-Jun-16 2:51
YvesDaoust24-Jun-16 2:51 
Even though the successive subtraction method to compute the fractions (k.a)/b spares divisions, it can still be costly because of branches, which will be regularly mispredicted.

An alternative (admittedly not fit for your computer) is to evaluate the ratio a/b in fixed-point representation once for all (as the integer (2^N.a)/b) and perform successive additions, to obtain k(a/b). The integer part (shift right N) gives the desired quotient, and this is branchless.

AnswerRe: Alternative to Bresenham Pin
Tomaž Štih24-Jun-16 6:13
Tomaž Štih24-Jun-16 6:13 
SuggestionShould add a bit more explanation Pin
Philippe Mori23-Jun-16 3:31
Philippe Mori23-Jun-16 3:31 
GeneralRe: Should add a bit more explanation Pin
Tomaž Štih23-Jun-16 3:55
Tomaž Štih23-Jun-16 3:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.