Puzzle Structure

Learn about how the different parts of puzzles are organized.

There are 25 programming puzzles, some perform specific tasks, while others may attempt to do something that doesn’t quite work. All of the code is written in C. No additional files or libraries are required. The programs run in the text mode environment, specifically, under Linux in a terminal window.

For each puzzle, your job is to guess what happens. You can predict the output, guess what the program is trying to accomplish, or identify a potential problem. The code is discussed in the next lesson that follows each puzzle, including an insight into understanding the code, what it does, and how or why it fails to do what you might think it does. The point is to learn more about C programming, witness a few tricks, and put your new knowledge to work in your own programs.

Here’s a sample puzzle.

Puzzle code

Read carefully the code given below:

Press + to interact
int puts(const char *s);
#define lineout(a) puts(a)
#define end return(0)
int main()
{
lineout("Hello there!");
end;
}

Your task(s)

  1. Can you guess the output from this code?

  2. It’s C source code, though we’ve taken some liberties with the way things are expressed. If you can guess the output, can you identify the liberties we’ve taken in the source code?

Try to complete the tasks on your own before you turn to the next lesson to see our explanation and further exploration of the puzzle.

Answers with explanation

Here are the answers:

  • The output is the string "Hello there!" followed by a newline. This is the output generated by the puts() function, normally declared within the stdio.h header—but this header is missing in the source code!

  • Instead of including the entire stdio.h header, we write the puts() function prototype. This is a legal move, as you can prototype any function you’ve created. But, here we just looked up the main definition for puts() and copied it into our source code. Properly prototyped, the function works just fine. (Remember that the function’s mechanics are stored in the library, not in the header file.)

  • Here, the two #defines create the unusual statements found in the main() function. The first defines a function lineout() equivalent to the puts() function. The a in both represents the function’s argument. So lineout() replaces puts() in the main() function, carrying out the same task.

  • The second #define assigns the return(0) statement to the word end. The result is the main() function’s statements appear alien—very non-C-like. Still, the preprocessor replaces both lineout() and end with the proper C statements.

Your goal

This unusual construction is one of the things we adore about the C language. While as a programmer your goal should be to write easily readable text, you can add your own quirks to the language just to keep things interesting. But on a grander scale, you can use these tricks to help simplify some complex operations. So, while there was an attempt to obfuscate the code, you can use the same tools to make a program more readable. And hopefully, you’ll have fun while doing so.

Further reading

For more detailed explanations and further reading on the concepts used in the puzzles, please refer to the Appendix section.