#!/usr/bin/perl -I ../../../cgi-bin use CGI::Carp qw(fatalsToBrowser); use AIOC::HTML; use AIOC::SiteBase; use POSIX qw(strftime); $specDir = AIOC::SiteBase::specDir(); my $site = new AIOC::SiteBase("aioc", "$specDir/aioc.train", '', $site_news); $site->putHeader(); $site->putPageHeader("Tutorials"); print << "__END__";

Counting to Infinity

Let's solve Counting to Infinity.

The problem statement asks us to output the numbers from 1 to n for some integer n. As with the preceding problem, we will require some kind of loop to achieve our goal, but one could argue that this is easier than the preceding problem. I'll look at two equivalent solutions to this problem, each of which uses a different kind of loop.

Solution using a while loop

The while loop is the most basic kind of loop: it readily translates to plain English, and it closely reflects how the computer actually interprets our code. As I discussed previously, a while loop requires a condition to check for, and a set of statements to execute while the condition is true.

It seems clear enough that our program should keep track of the number it's up to. I'll use a variable called upto for this, though as always you should name your own variable whatever is most meaningful to you. (One-letter names like i are popular for variables used to count from one number to another.) What value should we give to upto to begin with? There is no one right answer, but starting off at 1 seems sensible. That is, after all, where we're counting from.

What needs to happen inside the loop? To answer this, we must ask ourselves what actions we need to repeat multiple times. After some consideration, we might decide we need to:

Printing an integer should be second nature for us. Incrementing the value of upto is done by writing upto++ or an equivalent.

What is the condition we need to check? Well, if left unchecked, upto will simply continue growing until it is too big for the computer to store. To make sure we only print the first N integers, our condition should be true when upto is one of the numbers {1, 2, 3, ..., N-1, N}, and false when upto grows any bigger.

A natural condition satisfying the above is (upto <= N). Notice that we don't have to worry about upto being too small, because we set it to 1 and only ever let it grow.

Putting this all together, we get:

upto = 1;
while (upto <= N) {
	fprintf(outputFile,"%d\n",upto);
	upto++;
}

The first line of code initialises upto to 1. Then, while upto <= N the computer prints out the value of upto and increments it. This should print out all the integers from 1 to N. (An aside: when the program leaves the loop, the value of upto is in fact N+1. This is because it is incremented after the very last printf, only after which the condition is checked and found to be false.)

Solution using a for loop

Before we go on, I should stress something: the above code is correct. It makes perfect sense, and should score you 100% for Counting to Infinity. Any coding problem that requires a loop can be solved using a while loop, and there are many cases in which this is the best approach.

Despite this, many programming languages offer you a variety of other loops you can use in your code. I will be discussing the for loop as it appears in languages like C and C++. (If you are using a different language you should consult a reference to see what kinds of loop it supports. Most languages will at least provide you with a convenient way to count through a list of numbers.)

This particular kind of loop is useful when a program is going through a sequence of data. In this problem, we are running through the numbers from 1 to N. In each iteration of the while loop (each time it is run) our program does two things: it does something with the current number - specifically, it prints it out - and then it increments the counter variable in preparation for the next iteration.

Now, printing out the number is something very specific to the problem. There aren't that many contexts in which we'd want to print out the numbers 1 to N. However, the rest of the code to do with the loop (the initialisation, the condition, and the update) is quite general, and could easily be used for other purposes. A program that prints out the first N squares or a program that modifies a list of numbers will need to use the same kind of code to iterate through some range.

We can use for loops to separate these elements of our code. At the start of the loop we put all the code that deals with the counting. Inside the loop we put all the code that actually uses the counter. Here's a direct translation of the previous code:

for (upto = 1; upto <= N; upto++) {
	fprintf(outputFile,"%d\n",upto);
}

In general, the format is "for (initialisation; condition; update)". The computer executes the initialisation code, then, while the condition is true, executes the statements inside the loop followed by the update.

Whether this is any more readable than the while loop version is a matter of opinion. You may find that after a while spent reading and writing for loops, you are able to quickly interpret the start of the loop as "use upto to count between 1 and N". The added benefit is that there is no confusing the 'counting' code and the 'processing' code, as they are clearly separated.

__END__ $site->putPageFooter(); # Always return true. 1;