code

Lisp in Python

This is definitely the coolest programming related text I’ve read in a long while: Church Encoding in Python. I even almost understood all of it! :D
I saw this on the Planet Python feed aggregation(?) (it is the second entry right now) which I got introduced to today.
But seriously, how cool is the CONS construction and number encoding stuff?!

VN:F [1.0.8_357]
Rating: 7.0/10 (3 votes cast)

code
cool
programming

Comments (0)

Permalink

Fun with C++: Useless Consts?

Many C++ programmers see the keyword “const” as something redundant that only gets in the way. They curse Stroustrup and his ancestors each time they encounter a const-related compile error because of that view and fail to use it correctly quite often (note that I’m not saying that I’m not one of these people, but I curse neither Stroustrup nor anyone else.)

If you ask them about the purpose of the const keyword, they would give you the classic answer that any C++ textbook gives: variables declared as consts cannot be changed by the programmer, and const class methods cannot modify their instance data (and can be called on const class instances), etc.

The programmer may give you the textbook answer (or some mutilated version of it, depending on which textbook she read and how much of it she actually remembers,) but she is wondering with herself who will stop the other programmer to change the header file and remove the const from the declaration? Who is there to prevent her from doing so?!

She may even make a conjecture that if she removes all the consts from all her source files and headers (including standard and 3rd party headers she uses,) then her programs will continue to compile and work just fine (after all, the const keyword has no runtime effect. It’s an exclusively compile-time construct, is it not? So if her programs used to work, and they compile after removing all consts, they should continue to run without problem.)

If she is a little bit more sophisticated and skilled in C++, she knows that the C++ compilers differentiates between functions that take const arguments and those that take exactly the same arguments, but not const. This fact lets you have function overloads that only differ in constness of their arguments. The same is also true for template specializations (which is a form of overload anyway.)

So this more sophisticated C++ programmer will conjecture that if she removes all the consts and eliminates the redundant overloads (which were nothing but nuisances to begin with) then her programs will compile.

Now, is she right? Is this the case with const?
(I should say that I know of one case that is not so (the program will not compile without the the const) but it’s not a common case. I’ll write about that in a later post (if no one guesses it first.) I’m genuinely interested in other such cases.)
(Another note. The use of const frees the compiler to do some optimizations that may not be safe with a non-const object. My question is about correctness and not about performance.)

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code
programming

Comments (2)

Permalink

Fun with C++: When Parentheses Don’t Call!

Just a quick one. Most of us have come to think of parentheses as sometimes necessary but always harmless little creatures. Our view is that unless parentheses change the order of evaluation (and therefore the meaning) of an expression, they are completely harmless.
Well, while that is true almost by definition, there are cases that we might not realize the meaning of an expression is being changed. One such case is in the presence of the versatile and extremely useful (and possibly massively pain inducing) comma operator (’,‘.)
You see, the comma has two uses in C++ language: as an operator and as a separator for many different lists of things in the language grammar (function arguments, object declaration, etc.) In the first context, a pair of parentheses work exactly as anyone would expect; in the second, probably not. The problem is that the use of commas in the first context is not common at all, while the commas of second kind riddle any and every C++ source file. It’s mixing the meaning of the uses that’ll lead to potentially cryptic compile errors (what a shocker! Cryptic compile error messages in C++?!), or worse, logical bugs that will make you wish you were coding in machine language.

Just for the sake of comprehensiveness, while I know that you all know how the comma operator operates, I’m gonna describe its workings anyway. The comma operator has the lowest precedence among all the operators in C++ and it is a left-associative operator (meaning “a, b, c” will be evaluated as “(a, b), c“.)
An expression of the form “a, b” (where a and b are expressions themselves (and not statements)) will always evaluate a first, and then b and will return the evaluated value of b.
Please believe me when I say that overloading this operator can achieve magic and convenience one can only dream of in C++! Just see the Boost.Assignment library for a sample.

One place that the implicit mixing up of the meaning of comma could cause trouble is in function calls. Suppose that a function X accepts two arguments. Now, if instead of X (a, b) someone writes X ((a, b)) then they will be given a compile error saying that function X does not take one argument(s);-) . This is because the extra pair of parens have changed the meaning of the comma from a simple argument list separator to a C++ operator.
This will not confuse any C++ programmer out of her first few months with the language, and will be obvious and easy to find and fix. But what if the extra pair of parentheses is the result of a macro expansion? Then you’ll have to chase down the macro definition. Still not very hard, because the compiler will catch you. But what happens if the X function has an overload with a single argument, incidentally with a type compatible with b? What happens if the function takes more than two arguments and has many overloads and it’s called like this: X (a, (b, c), d, (e, f, g))?
I should probably list this as another macro pitfall. Take care where you put parentheses! Don’t just slap them whenever you’re in doubt!

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code

Comments (0)

Permalink

Fun with C++: Metaprogramming, Part 1

Metaprogramming can mean many things, but all of them can be made to (loosely) fit under the description of “writing programs that write or rather describe (a class of) other programs.” A classic and somewhat useless sample of this is writing a program that prints it’s own source code. My first real contact with this field came from working with YACC. The rule file one writes to be fed to YACC, is kind of a metaprogram.
As a better example, if you could write a program that would accept a set of strings and generate a C++ program that would implement a “perfect hash function” that would hash those N input strings onto N collision-less values, then you’d have written a metaprogram. (Note that you are not implementing a hash function; you are writing a program that implements many hash functions based on the input.)

Now, these metaprograms can be in any language and output any language. If you write one in C++ that produces C++, then you have to run your compiler twice to get to the final usable program. Not really convenient, but it is used in the real world. For example, that perfect hash function generator example is exactly how gperf works.
On a cooler side, there’s already a couple of other mini-languages that any C++ compiler package can understand, e.g. the preprocessor language. I’m the first one to admit that writing a program only in preprocessor is like having trying to open a locked door with your head, but it’s not entirely without merits and fantastic experiences.

OK, so let’s get down to it. Before we can program in any language, we should know how some basic ideas like logic, conditions, repetition, etc. are expressed in that language. First off, doing loops a la “for” and gang is really really hard to do in preprocessor (I’d say impossible, but I’ve seen Boost.Preprocessor!) Fortunately, C++ preprocessor language does support a form of recursion (guess how?) and we can use that facility both as loops and as subroutines.
If you think about it, you’ll find out that the preprocessor’s programming model is not unlike digital logic circuits, with all the variables, inputs and outputs being single bits (whether a specific macro has been #defined or not) and the only operations being ANDs, ORs and NOTs. Although the preprocessor can assign arbitrary integers to macros and can compare them, but cannot do arithmetic on them.
As a first example, let’s see how an XOR logical function with two one-bit inputs can be implemented.

1
2
3
4
5
#if (defined(IN_a) && !defined(IN_b)) || (!defined(IN_a) && defined(IN_b))
    #define OUT_a
#else
    #undef OUT_a
#endif

That’s it. Not very complex or revolutionary, but this idea can be taken far. What if we put the above code in a header file, and #include that header whenever and wherever we need a 1-bit XOR? Of course, the parameters to that XOR are always the same (think of them as global variables) but this concept can be use to implement functions and therefore recursion. I’m not going to go into more elaborate examples of recursion. Just let me demonstrate a little more of the preprocessor with another example that actually does something and generates output. I’ve implemented a 1-but full-adder (three inputs: A, B and Carry, and two outputs: A and Carry. The input carry is for reusability.) This example consists of two files; a “OneBitAdder.h” like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
	OneBitAdder.h
 
	Inputs: "IN_X" and "IN_Y" and "IN_C"
	Outputs: "OUT_X" and "OUT_C"
 
	Returns the sum of the inputs. Note that each input and
	output here is one bit: either a macro is defined (it's 1)
	or not (it's 0.)
*/
 
  #if !defined(IN_X) && !defined(IN_Y) && !defined(IN_C)	// 0
	#undef OUT_X
	#undef OUT_C
#elif  defined(IN_X) &&  defined(IN_Y) &&  defined(IN_C)	// 3
	#define OUT_X
	#define OUT_C
#elif  defined(IN_X) && !defined(IN_Y) && !defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#elif !defined(IN_X) &&  defined(IN_Y) && !defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#elif !defined(IN_X) && !defined(IN_Y) &&  defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#else						// 2
	#undef OUT_X
	#define OUT_C
#endif

and the “PreprocessorAdderTest.cpp“:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Set input
#define IN_X
#undef IN_Y
#define IN_C
 
// Compute
#include "OneBitAdder.h"
 
// Display(!) output
#  if !defined(OUT_X) && !defined(OUT_C)
	#pragma message ("--- The answer is 0")
#elif  defined(OUT_X) && !defined(OUT_C)
	#pragma message ("--- The answer is 1")
#elif !defined(OUT_X) &&  defined(OUT_C)
	#pragma message ("--- The answer is 2")
#elif  defined(OUT_X) &&  defined(OUT_C)
	#pragma message ("--- The answer is 3")
#endif	
 
// main is mainly cosmetic.
int main () {return 0;}

I’ve used #pragma message for output here. I’m not sure which compilers support it (I suspect all that matter) but if you want you can use other methods, like using #error.
Create these two files and compile the “.cpp” file (note: just compile it.) There should be a string “— The answer is 2” in your compiler output! See what we did? We just run a program by compiling a C++ source file! Cool, eh?

Of course, getting any real use out of the preprocessor (beside the obvious) is really is not worth the effort, but if you want to see whether you have the hang of it, try writing a 2-bit adder using the above 1-bit adder. It’s not as easy (nor as hard) as it may sound. The samples here were not really good examples for metaprogramming, but I think you can extrapolate from here on if you want to.

I originally (i.e when I started writing this post!) wanted to write about template metaprogramming, but I went in a completely different direction. Maybe next time then.

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code

Comments (4)

Permalink

Fun with C++: Macro Pitfalls, Batch 1!

(UPDATE: Added the 6th item.)

I’m a fan of C/C++ preprocessor macros. I would be very happy if C++ received macros on par in power with those of Common Lisp macros, but that’s only a dream! We have to work with what we have.
Anyways, with use of macros come a lot of potential pitfalls. I’m going to go over a couple of them. I’m sure any C++ programmer is aware of these, but the reiteration would hurt now, would it? I’m also hoping that with your feedback, we can complete these into something referable and usable.

  1. Operator Mishaps From Hell!
    This is a classic example.

    #define SQR(x)    x * x

    Imagine what happens when you use something like SQR(a + b). But as I said, this is a classic example, and any C programmer with half a brain should know enough to avoid this (doesn’t mean it always happens though. We all have our shameful secrets!)
    The moral is: always enclose every usage of macro parameters in parentheses as well as the whole thing. (#define SQR(x) ((x) * (x)))

  2. The Space From Hell!
    #define SQR (x)   ((x) * (x))

    Notice the space between SQR and the (x)? The programmer didn’t! It usually results in a cryptic compile error about something not being a function or about incorrect number of arguments. Easy for more experienced programmers to understand and rectify (usually with a bang to their heads.)
    Also, it’s not hard to imagine cases without any compile errors and severe oddities in runtime behavior. Remember: Compile-time errors and warnings are your friends as long as you pay attention to them! They might be a little hard to understand, but a project with 100 pain-in-the-neck compile errors is better than 100 hidden runtime bugs just waiting to cut your neck off.

  3. The Semicolon From Hell!
    Let me demonstrate the perils of the semicolon.

    // A macro to increment a counter, and wrap around to zero is a limit is reached.
    #define ADVANCE(x, wrap)    ((x) = ((x)+1)%(wrap));
     
    // Usage 1
    while (should_go_on)
        ADVANCE(i, 100);
     
    // Usage 2
    for ( ; should_go_on; ADVANCE(i, 100))
    {}
     
    // Usage 3
    while (should_go_on)
        p = ADVANCE(i, 100) + 100;

    As long as you stick to the first usage (i.e. as a statement,) you get away with your mistake (the spurious semicolon at the end of the macro definition.) However, usage 2 won’t compile. But this is a good thing, since you will know that you have an error in your macro (of course, if you’re a newbie in C++, it may take you quite a few minutes to figure this one out.)
    Usage 3 is where things get interesting. The code will compile (at most with a mysterious and seemingly unrelated warning,) but it won’t do what you think it does. That can be a bitch to track down.
    So, the moral of this story is: don’t put semicolons in macros!

  4. The Multiple Evaluations From Hell!
    #define SQR(x)    ((x) * (x))

    What happens when you evaluate the value of SQR(++a)? Does that seem alright to you? (By the way, any one who tells you a += b is equivalent with a = a + b is either a moron, or thinks you are a moron!)
    The lesson of this item is: don’t use macros as fast, generic functions! Use inline templates (which are even potentially faster (do you know when? :D )) Like this:

    template <typename T>
    inline const T & sqr (const T & x) {return x * x;}
  5. The Multiple Statements From Hell!
    The following macro deletes a pointer and sets it to 0, a very sensible thing to do nearly all the time.

    // This is not OK. Don't use this macro like this. Keep reading down this article!
    // Also note that I've not placed a semicolon at the end.
    #define SAFE_DELETE(ptr)  delete (x); (x) = 0
     
    // Usage 1
    char * s = new char [42 + 1];
    ...
    SAFE_DELETE(s);
     
    // Usage 2
    if (some_condition) SAFE_DELETE(s);

    But it doesn’t work, does it? I mean, usage 1 is OK, but you’ll wish you were never born when you have to stay up late into the night and debug the results of the second usage, won’t you? So, what do we do? I imagine everybody’s first response would be:

    // This is not OK, still.
    #define SAFE_DELETE(ptr)  {delete (x); (x) = 0;}
     
    // Usage 3
    if (some_condition)
        SAFE_DELETE(s);
    else
        doSomeWork (s);

    See the problem? No? The problem is in the semicolon before else. C++ doesn’t let you put a semicolon after an closing curly brace (’}') and before “else”. So what do we do? This is one of the solutions:

    // This is almost OK, and usable if you are not very picky.
    #define SAFE_DELETE(ptr)  do { delete (x); (x) = 0; } while (false)

    That’s right! We put the multiple statements inside a do/while block that is guaranteed to be executed only once! Brilliant, isn’t it? Well, I didn’t come up with it. I wish I could say that I though of it independently, but that’s not the case. I saw it in kernel code even before I had run into this problem! But the code didn’t say why it was used this way, and analyzing and discovering the purpose of this small piece of code was one of my biggest “Aha!” moments in C programming.
    So, we are good to go, right? Well, not quite. If you don’t care much about warnings the compiler gives off, you are good to go. But the above code results in a warning (only when you have turned the compiler warning level to the highest degree,) that the used condition is constant. Although the occasions for this warning are intentional most of the time (like here,) it may be the case that the compiler is warning us about a typo. Because of this, I don’t want to disable this warning (unlike those blasted 4996 warnings Visual C++ gives off like candy on Halloween, which I shut off with a wide and hysterical grin, while caressing my ax handle!)
    So what do we do? The best solution that occurs to me is like this:

    // We define a function that always returns false
    namespace __useless {
    inline bool i_am_false () {return false;}
    }
     
    // Now we use the above function instead of hard-coding the constant expression
    #define SAFE_DELETE(ptr)  do { delete (x); (x) = 0; } while (__useless::i_am_false())

    We trick the compiler here. The compiler is wise enough (or not smart enough) to give a warning no more, but any optimizer would optimize the overhead of the function call away completely.

  6. The “if” From Hell!
    Suppose we “optimize” the above SAFE_DELETE macro, to check whether the argument is NULL, and do nothing in that case.

    #define SAFE_DELETE(ptr)    if(ptr) delete (ptr), ((ptr) = 0)
    // Note that I've incorporated the comments from Hadi (comment 2) here, to make a point.
     
    // Usage 1
    if (some_condition)
        SAFE_DELETE (s);
    else
        return 0;

    Ouch! That hurts. I don’t think there’s anyone who doesn’t know this already, but in case there is (almost no shame in not knowing,) the “else” in the first usage will be the else clause for the “if” inside the macro! You are going to hate Dennis Ritchie after the first two hours of bewilderment over this (but of course, that would be out of frustration, and without logical cause!)
    You may be tempted to solve the problem like this:

    #define SAFE_DELETE(ptr)    if(ptr) {delete (ptr); (ptr) = 0;} else {}

    But don’t! Do this:

    #define SAFE_DELETE(ptr)    do { if(ptr) {delete (ptr); (ptr) = 0;} } while (__uselss::i_am_false())

    The moral? If you write “if” clauses in macros, be extra careful.

The above were only some of the pitfalls, but I can’t continue right now. Looking forward to your suggestions. Don’t be shy!

VN:F [1.0.8_357]
Rating: 10.0/10 (1 vote cast)

C++
code
updated

Comments (6)

Permalink

KOPCS Distribution 1371

This is the long overdue package (and “ymeta” file,) containing KOPCS source code (verion 1.0.0 (codenamed Rincewind) build 1371.) The package also contains pre-built binaries mostly for Windows, but “Zero” is provided for 32-bit x86 Linux as well.
The package contains KOPCS (plus less-than-minimal documentation,) JFKOPCS scripts, yCrypto (plus documentation,) Zero, the web page templates, some tests and VS2005 project files and Makefiles.
There’s no guarantee that anything in it works or even compiles. Do not trust anything you hear or receive from me! The only external dependency is MySQL (preferably 4.x or 5.x, but 3.2x may work) to build and run and Apache 2.0.x or 2.2.x to run it.
There’s no setup guide whatsoever. Good luck!
BTW, I’m going to setup a subversion repository for KOPCS soon. The only problem I have is migrating from the existing local CVS (on Mike) to a remote SVN on yaserzt.com.
UPDATE 2007-11-04: The authors of KOPCS are (in no particular order) Ehsan Adeli Mosabbeb, B. Maryam Elahi and myself. The source code has been released with their expressed permission. An implementation of the SHA-256 in JavaScript language by Angel Marin has been used. Please refer to the file “webfiles/media/sha256.js” in the distro for more information.
I guess a quick note about licensing is in order. All the work done for KOPCS by the above-mentioned authors are released under the terms of the Lesser General Public License version 3 (a.k.a. LGPLv3) with the exception of the IAUM-CCC website templates and the JavaScript code used in it, which are under the terms of the General Public License version 3. The website templates include and is limited to any file with the extension of “.htmltemp”, “.js”, “.css”, “.png” and “.ico”. Note that KOPCS is released AS IS in the minuscule hope that it would be useful, but without any guarantee (even implied) that it will be suitable for any purpose. That means, if KOPCS destroyed your hard drives or burned down your house, it’s your fault not ours!

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
KOPCS
code
programming

Comments (4)

Permalink

C++: Fun With Comments

There’s much fun to be had with C++ comments, and a lot of seriously usable tricks there as well. Of course, most of programmers already know all I could tell about the subject, but nonetheless, I think I’ll take a shot at bringing all the techniques I think might be useful together, and I might be able to use a few possible tricks that a possible visitor would possibly leave on this post!
The first thing any programmer has to realize about comments is that (as their name suggests)

Comments are not the code that the compiler doesn’t see, but the sentences that a human would read.

Write comments (and code in general) for another human (or you yourself) to read. This generally means you should generally avoid too clever constructs that have no other advantage. I say it again: Write code for other humans to read, not the compiler to compile.
You can use special comments and tools like doxygen to generate useful, beautiful, always-up-to-date and comprehensive documentation of your source codes automatically, with little extra work (e.g. with putting a line with three slashes (”///“) at the beginning and describing the purpose of a function before its prototype.) These kinds of tools make you appreciate the value of comments!
My first advice is never use “//” or “/*” to comment out a piece of code. Those characters are reserved for “comments”, i.e for writing descriptions of your code! Always put another character (or sequence of characters) after them, and use different characters to distinguish the different situations in which you’ve commented out the code. For example, use “//0” and “/*0” for code that you suspect is incorrect, use “//1” and “/*1” for test code, and so on and so forth. Keep in mind that these are only suggestions. Any system you opt to use, must be documented somewhere. Write 10 lines to describe the meaning and connotation of the 10 different types of comments you use. Don’t take this lightly! As time goes by and you write more code, you’ll accumulate these rules and split or merge them, but your commenting rules become more comprehensive, more concise and more useful.
Anyway, suppose you want to comment a multi-line piece of code. Always put the comment openning and closing on a line by themselves. No code on those lines! Also, use “//*/” for the closing marker (instead of just “*/“.) This way, you can uncomment and recomment that part with only a single character; a ‘/‘ that you add to or remove from the beginning of the openning marker. Look at snippets 1 and 2.
There are times that you want to switch between commenting two parts of a single line. In these situations, you can put “/**” before the first part, put “/*/” between the two parts and “/**/” after the second part. Like snippets 3 and 4, you can then switch between the first part being commented out and the second one by adding a single ‘/‘ after the comment before the first part. (Also note the parsing/formatting bug of jEdit on line 18!)
You can also do it in the slightly prettier way that snippets 5 and 6 demonstrate (I really think so!) but only if you want to switch between two multi-line segments of code.
Commenting large blocks with “/*” and “*/” has a major problem. The commented blocks don’t nest. For this reason, I suggest the cleaner method of using “#if 0“, “#else” and “#endif” blocks (snippets 7 and 8, but they lack the coloring.) This way, not only you can nest commented out blocks inside of each other and enable/disable them individually just changing the ‘0‘ to ‘1‘ (provided the outer blocks are not disabled) but also you can comment the commented-outness(!) of these peices, and you can use preprocessor macros instead of just ‘0‘ to be able to switch these segments on and off from elsewhere. The only problem is that many editors and IDEs don’t process preprocessor directives and they won’t colorify the disabled parts as inactive.
In your “comment” comments, you can use well-recognized keywords like “NOTE“, “WARNING“, “TODO” and “FIXME” to make their meanings more apparent and to searching for them easier. Just remember to use them neatly and consistently.
If you have more ideas for using comments, I’d be happy to hear about them and to include them here. By the way, anybody has a clean and pretty way of switching (commenting/uncommenting) among three or more segments of code?

   1://{Snippet 1}
   2:/*0
   3:    for (unsigned i = 0; i < v.size(); ++i)
   4:        swap (v[i], v[v.size() - 1 - i]);
   5://*/
   6:
   7://{Snippet 2}
   8://*0
   9:    for (unsigned i = 0; i < v.size(); ++i)
  10:        swap (v[i], v[v.size() - 1 - i]);
  11://*/
  12:
  13://{Snippet 3}
  14:    for (unsigned i = 0; i < /**/ v.size() /*/ v.size() / 2 /**/; ++i)
  15:        swap (v[i], v[v.size() - 1 - i]);
  16:        
  17://{Snippet 4}
  18:    for (unsigned i = 0; i < /** v.size() /*/ v.size() / 2 /**/; ++i)
  19:        swap (v[i], v[v.size() - 1 - i]);
  20:        
  21://{Snippet 5}
  22:/*0
  23:    for (unsigned i = 0; i < v.size(); ++i)
  24:        swap (v[i], v[v.size() - 1 - i]);
  25:/*/
  26:    for (unsigned i = 0; i < v.size() / 2; ++i)
  27:        swap (v[i], v[v.size() - 1 - i]);
  28://*/
  29:        
  30://{Snippet 6}
  31://*0
  32:    for (unsigned i = 0; i < v.size(); ++i)
  33:        swap (v[i], v[v.size() - 1 - i]);
  34:/*/
  35:    for (unsigned i = 0; i < v.size() / 2; ++i)
  36:        swap (v[i], v[v.size() - 1 - i]);
  37://*/
  38:        
  39://{Snippet 7}
  40:#if 0
  41:    for (unsigned i = 0; i < v.size(); ++i)
  42:        swap (v[i], v[v.size() - 1 - i]);
  43:#else
  44:    for (unsigned i = 0; i < v.size() / 2; ++i)
  45:        swap (v[i], v[v.size() - 1 - i]);
  46:#endif
  47:        
  48://{Snippet 8}
  49:#if 1
  50:    for (unsigned i = 0; i < v.size(); ++i)
  51:        swap (v[i], v[v.size() - 1 - i]);
  52:#else
  53:    for (unsigned i = 0; i < v.size() / 2; ++i)
  54:        swap (v[i], v[v.size() - 1 - i]);
  55:#endif

UPDATE:I was wrong about the parsing/formatting bug in jEdit I mentioned above. That’s a Doxygen comment and jEdit handles it correctly. Oops!

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
code
programming

Comments (0)

Permalink

A Breach in the Hull

The Convex Hull code I posted earlier on this blog has a bug. When the points are all have the same X component, the implementation will misbehave. I may post a fix later; I’m off to work now, but I had meant to write and mention this for so long that when I remembered the matter in the shower I didn’t postpone the writing in fear of forgetting it once more.

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

code
programming

Comments (0)

Permalink

Convex Hull

I don’t know how do mathematicians define a Convex Hull, but informally, the (planar) convex hull of a set of point on the plain is defined as the smallest convex polygon that includes all the points.

If you think about it, the verteces of such polygon will have to be in the given set, and the convex hull will be unique (if we add the restriction that no three consecutive vertecs of the resulting hull can be on the same line. Which is not much of a “restriction“, because if they are, we just simply remove the middle point of the three and voila!)

So, the problem becomes finding the smallest area, convex polygon one can construct with the vertices from the set that encompasses all the given points.
Finding a convex hull is an interesting problem by itself, and quite useful in many other planar geometry and pattern recognition problems.

Now, many algorithms exist for finding the convex hull efficiently but not too simple (except the divide and conquer one which I’m not going to go into here.) When it comes to implementing, most people may try the naive O(n2), which is not easy to get right in one go (if you’re that kind of person who tries that and gets it right in the first try, leave my weblog immidiately. I can’t stand people better than I here!)
The other easy-to-comprehend-but-hard-to-implement method is “Graham’s Scan“, but that needs a special and none-trivial sort. Graham’s Scan runs in O(n log n).

The method I’m going to discuss here is a O(n log n), and easy to implement algorithm. I first saw it in a Python book, the title of which I can’t remember.

It starts with a straightforward sorting of the points, based on the X coordinate then the Y coordinate. Then, we’ll start from the leftmost point (least X) and work our way to the rightmost point, maintaining two lists of points. One is the botton run of the points between the min- and max-X points, and the other is the top run.
Here’s C++ code that implements the algorithm:

#define TURN_DIR(p1,p2,p3)  (p1.x * p2.y - p1.y * p2.x + \
                             p2.x * p3.y - p2.y * p3.x + \
                             p3.x * p1.y - p3.y * p1.x)
#define LAST(cntnr)         (cntnr).back()
#define BEFORE_LAST(cntnr)  (cntnr)[(cntnr).size() - 2]

vector<Point> ConvexHull (vector<Point> & pts)
{
    sort (pts.begin(), pts.end());

    vector<Point> lower, upper;
    for (unsigned i = 0; i < pts.size(); ++i)
    {
        while (lower.size() >= 2 &&
         TURN_DIR(BEFORE_LAST(lower), LAST(lower), pts[i]) <= 0
        )
            lower.pop_back ();
        while (upper.size() >= 2 &&
         TURN_DIR(BEFORE_LAST(upper), LAST(upper), pts[i]) >= 0
        )
            upper.pop_back ();

        lower.push_back (pts[i]); upper.push_back (pts[i]);
    }

    lower.insert (lower.end(), upper.rbegin() + 1, upper.rend() - 1);
    return lower;
}

You should be able to make sense of this code without much difficulty, but be warned, I changed my implemented code to put it here, and I have not tested it (my data structures for points and for return values were different, and I removed the comments! >:-) ) So use at your own risk.

Now, the challenge is this. Can you make it shorter? (It’s possible to use recursion to do so, I think.)

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

code
programming

Comments (0)

Permalink