Puzzle of 7 points and 6 straight lines

My friend presented me with a puzzle: Construct a geometric shape with 7 points such that there are 6 straight lines, and each line must pass through 3 points.

My friend came up with a solution, but he wasn’t sure, so he consulted me. Actually there was a “model” answer, but he wanted to find another solution. So we had 2 solutions. I’ll present that model answer here so you can understand the puzzle better.

Equilateral triangle solution

Points A, B and C form an equilateral triangle. Points D, E and F are the midpoints of lines AB, AC and BC respectively. Point G is the centre of the triangle.

Note: 3 points are collinear if they lie on a straight line.

The 7 points are A to G. The 6 lines are formed by ADB, AEC, BFC, AGF, BGE and CGD.

[I'm not going to go too much into math theories and proofs. Besides, I'm not even sure if I can recall them after losing track for so long...]

The first three lines should be easy to understand. D is the midpoint of AB, so ADB is a straight line. So it is for AEC and BFC.

E is the midpoint of AC, and BE is the perpendicular bisector (remember ABC is an equilateral triangle). And G lies on the line BE, since G is the centre of the triangle. So BGE is a straight line.

Using this reasoning, AGF and CGD are also straight lines.

I know, the explanation I gave isn’t quite backed up with math proofs, more with intuitive reasoning. But I’m sure they are (I just don’t know exactly which theorems to cite…).

So I have 2 favours:

  • Send me a more proper explanation of the solution given above
  • Or send me another solution (remember I have another one?)

I know there are at least 2 solutions. Just wondering if there are more. I will post my other solution, together with any submissions from you next Monday. Or earlier, depending on the number of submissions. You’re welcome to do both. *smile*

Since this is a geometric construction, a picture together with some explanations is appreciated. You can host the image on a site like Flickr, then add a comment to this post with a link to that image and a brief explanation.

Or you can send me your solution via email to vincent at polymathprogrammer dot com. Let me know if you want to remain anonymous (why?), and I’ll just post your solution only.

Your construction doesn’t have to be exact in proportions. Meaning if there’s a right angle, it doesn’t have to be 90 degrees exactly, so long as it looks like it’s 90 degrees. Just add some explanation to supplement the drawing. Try Paint.NET if you don’t have any image editing software.

Have fun!

Multiplications, additions and bit shifts

In a previous article, I asked what this does

int foo(int para)
{
	int temp = para << 3;
	return temp + temp + temp;
}

The function basically returns a value of the parameter multiplied by 24 (thanks Mark!).

So why was it written that way? Speed.

From what I understand, in the olden days, multiplication was slower than addition and bit shift operations. I don't know how slow, but it was slow. It was so slow that programmers (particularly game programmers) started replacing multiplication operations with a combination of additions and bit shifts.

Our example above with 1 bit shift and 2 additions was faster than just 1 multiplication operation. Hmm... that example may not be the best to use... Let me give another one.

The idea is to split the multiplication into additions first. So
i * 80
becomes
i * (64 + 16)
which becomes
(i * 64) + (i * 16)
which becomes
(i << 6) + (i << 4)
where we swap multiplications with powers of 2 to bit shifts. See, you do need some math in game programming.

Bit shifts are faster than additions, which are faster than multiplications. The speed difference obtained from rewriting the code was enough for some game programmers to adopt for use.

With modern computer chips, multiplications are just as fast as additions and bit shifts. So I did some comparison. Before I show you the code, there are 2 warnings:

  • The code segments aren't supposed to be tested on their own. The original speed improvements made sense when combined with their surrounding code.
  • Measuring something changes it, so you're not measuring the true value (some principle from physics. If you can find me a reference, I'd appreciate it).

I will present 4 different ways of multiplying by 24 using 4 functions. The first is the one posed in the previous post:

int foo(int para)
{
    int temp = para << 3;
    return temp + temp + temp;
}

The second function uses multiplication.

int goo(int para)
{
    int temp = para;
    return temp * 24;
}

I didn't really have to declare the variable temp. I did it so all 4 functions declare a variable. Even variable declaration takes time, minute as it is, so I had to take that into account and standardise it across the 4 functions. This is the part where "measuring something changes it"...

The third function uses 2 bit shifts and 1 addition.

int hoo(int para)
{
    int temp = para;
    return (temp << 4) + (temp << 3);
}

Convince yourself that the return value is a multiplication of the parameter by 24.

The fourth function is a modification of the first function.

int loo(int para)
{
    int temp = para << 3;
    return (temp << 1) + temp;
}

If bit shifts are faster than additions, temp << 1 is faster than temp + temp, right? The use of temporary variables to hold intermediate values for another calculation is another technique used in game programming. This sounds a little vague, so I'm publishing another article to explain this further.

And here's the timing code

const int cnMax = 500000000;
const int cnLoops = 20;
const int cnValue = 5;
DateTime dtStart = DateTime.Now;
DateTime dtEnd = DateTime.Now;
TimeSpan ts;
int i, j, temp = 0;

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = foo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = goo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = hoo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = loo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

I've initialised temp to 0 just before the test loops, and printed its value after the loops to check that the calculations give correct results. The loops are coded with a standard structure, and the only difference is the function used. All 4 functions are coded in as similar a structure as possible, to isolate only the method of calculation.

I've used nested for loops to increase the number of iterations. One loop can only go as high as 2^31 iterations (unless I use long). Nested loops increase this limit by doing a lower iteration limit multiple times.

And the conclusion? Multiplications are now just as fast. I didn't get consistent results to rank the methods in order of speed though. Generally speaking, the 2-shift-1-add method (3rd function) is faster than multiply-by-24 method (2nd function).

That's it. As an exercise, you might want to come up with better code to time them. Follow some simple rules:

  • The results must be repeatable
  • Tests must be standardised

A suggestion? Perhaps you can add more code to the loop structure (or the functions). So long as all 4 loops (or function code) are similar, you don't need a minimalistic approach. This allows you to increase the percentage of identical parts between the tests, and thus highlight the difference in only the calculation method (let me know if you're confused by this).

Have fun!

Translating database column names for globalisation

I was working at a software development house where one of those enterprisey .NET web applications was created for a large company. It was fairly standard. There were workflow processes, inventory tracking business logic, user management and the like.

The web application also had to display information in both English and Japanese (the customer was, you know, a Japanese company).

While the database column names were in English, there must be an option to display the Japanese equivalent. Suppose we had a table scripted like:

create table staff
(
STF_ID nchar(10) not null,
STF_NAME nvarchar(100) not null,
EFF_DT datetime not null
)

When I was creating datasets, I used Pascal case as recommended, and typed out words in full. So I had something like

ds.StaffID = "FIRSTID";
ds.StaffName = "Some name";
ds.EffectiveDate = DateTime.UtcNow;

The lead developer gently asked me why I coded that way. I explained the recommended practices for variable naming. I was actually quite puffed up with pride because of that knowledge.

The lead developer said he understood (though I didn’t think he did). Then he gave me an explanation why my method was a bad idea. He said translations for English and Japanese were based on resource files, and the contents of those files were based on the names used in the database tables.

So in the resource file, there would be an entry for STF_ID to be translated into “Staff ID” in English and “sutafu ID” in Japanese.

Staff ID translation (English and Japanese)

If I used “ds.StaffID”, it would be confusing for other programmers because I did some “translating” on my own. Someone else might translate differently and soon, the whole project would go up in flames. A standard way of referring to the database column name was established, and that was whatever the column name was originally. Even if it doesn’t look quite right in code.

So there would be

ds.STF_ID = "ID09183";
ds.STF_NAME = "another robot";
ds.EFF_DT = DateTime.UtcNow;

After some thinking, I had to concede. Using the database column name in code did make sense. There were full-time people hired to enter a code, word or phrase with the English and Japanese equivalent into the resource files. There were many developers working on that project. It’s just more efficient to use the column names as a standard.

That said, there’s much to be desired for the variable naming skills of the database administrators…

Please ConvertToEnglish()

So, I thought it would be interesting to do something different. How about deciphering code? The challenge is to explain a piece of code by giving a minimalist description in English. We’ll practise understanding code with no comments and only the surrounding context as clues.

Here’s the code

int foo(int para)
{
	int temp = para << 3;
	return temp + temp + temp;
}

Explain what the function is doing in the simplest possible way. Don't just tell me what it's doing line by line. Tell me what it finally does.

Post your answer in a comment. Bonus points if you can give a reason why it was coded that way (yes, it has a rational explanation). I'll post my answer in a few days time.

Are you a malleable code editor?

Let me explain malleability by telling you a short story. There was this guy, let’s call him Vincent, who was learning programming and the intricacies of using a Unix machine. The default editor software taught was the vi editor, and Vincent was having some trouble with it.

Copying and pasting was frustrating. Vincent had to remember vi had an edit mode and a command mode. He frequently typed in code and was surprised that a bunch of gobbledegook was on screen because he was in a different mode (the “u” undo command was extremely handy). Even moving up and down lines of code was a challenge (until he found he could still use the direction keys instead of h,j,k,l).

After a while, Vincent could use the vi editor fluently, editing his code with ease and thus able to focus on the logic and code. It’s not as easy as Notepad on Windows. It’s just a little different.

Then Vincent’s classmate and fellow student, let’s call him Paul, said he had a better way of writing code in Unix. “I’m using pico,” he said, as though that was the most sensible thing anyone could do, accompanied with an irritating smug on his face. It had a *gasp* white background with black text, and works similarly to Notepad.

Vincent was like, whatever. He had gotten used to the black background and light-coloured text on the Unix machines, and frankly, didn’t care that the vi editor had that colour palette. In fact, it helped Vincent in distinguishing the Unix and Windows editing environments, simply through a colour distinction.

Paul’s appalling passion for pico was palpably pedestrian. Vincent felt using vi on Unix, and Notepad on Windows was just fine. Of course, Vincent had enough sense to use Dev-C++ instead of Notepad…

Couldn’t let go, or couldn’t adapt?

I found the editing habit of one of my colleagues… intriguing. He’s an ASP.NET developer, or he compiles web applications targeting the .NET framework anyway.

When he needs to edit code, whether it’s the .aspx or the .vb code-behind file, he would open the code file in … Notepad. Or Notepad+. Or some other text editor meant for general use. I can’t remember which.

After he’s done, he would save the file, then switch to Visual Studio and compile the code. Basically, code was edited outside of Visual Studio, and the IDE was used only for compiling and debugging. I still can’t fathom the reasons behind this…

I had another colleague who had another intriguing habit. There were some C++ code files on our Unix machine, where the executable was to run in Unix too. Did he use the vi editor? Of course not.

He would transfer the code files to his computer via FTP. Then he would open them in Visual Studio, the only IDE capable of editing C++ code files on his computer (other than Notepad. We’ve been there. Moving on…). The editing was done in the IDE, never mind the limited Intellisense since the code file was the only file in a “project” as reference.

Since he can’t compile the code anyway (the code references Sybase libraries, which was on the Unix machine), he transferred the code files back into his directory on the Unix machine. Then he switched to the Unix environment and compiles the code.

Is there something wrong with the “indigenous” code editor for that code and environment?

I don’t see a noticeable enhancement for the change in editing tools. So I’m stumped. Perhaps you can provide an answer to the riddle.