Repeating in Pascal (third part)

first part -- second part -- third part

Let's look at some examples of nested repeating, that is repeating inside of another repeating. How can this be useful? For example we can have an array of numbers, and we want to know if there are two same numbers. One possible solution is to compare each number with each number, and tell when we found two same. "Each number with each number" is double repeating; the first compared number, and the second compared number. Here is a short example:

var
  count : Integer;
  numbers : Array[1..100] of Integer;
  found : Boolean;
  i, j : Integer;

begin
  Write('How many numbers: ');
  ReadLn(count);
  for i := 1 to count do begin
    Write('Enter a number: ');
    ReadLn(numbers[i])
  end;
  found := false;
  for i := 1 to count do begin
    for j := 1 to count do begin
      if i <> j then begin
        if numbers[i] = numbers[j] then begin
          WriteLn('On positions ', i, ' and ', j, ' we found ', numbers[i]);
          found := true
        end
      end
    end
  end;
  if not found then begin
    WriteLn('There are no two same numbers')
  end
end

The test "if i <> j" is in program to prevent comparing a number with itself. Numbers at positions "i" and "j" are compared only if "i" and "j" are different.

This example makes an error of displaying each same pair twice. For example if we have the same numbers at positions 2 and 4, the program will display found pair at positions 2 and 4, and later found pair at positions 4 and 2. How can we prevent this? We need to remove one of the combinations of "i" and "j", and to keep the other one. We could for example demand that "j" must be the greater of two indices, by changing the test "if i <> j" to "if i < j".

Another possibility is not using in "j" all values from 1 to maximum, but only walues greater than "i", that is starting at "i + 1". The inner repeating would be "for j := i + 1 to count". And we can remove the following test, because now "j" will always be greater than "i". For example when we have five numbers, when "i" is 1, "j" will have values from 2 to 5. In the next step when "i" is 2, "j" will have values from 3 to 5. Etc. When "i" is 4, "j" will only be 5. And in the last step when "i" is 5, the repeating command for "j" will want numbers from 6 to 5, and this means it will be skipped.

var
  size : Integer;
  x : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for x := 1 to size do begin
    Write('*');
  end;
  WriteLn
end

More graphical example of double repeating is displaying simple geometrical shapes. In this example we will build shapes from small stars "*". If we want to display the stars in a row, we can ask for size of a row, and using the command "Write" we will write the corresponding number of stars. Finally we will end the line using command "WriteLn".

var
  width : Integer;
  height : Integer;
  x, y : Integer;

begin
  Write('Enter width: ');
  ReadLn(width);
  Write('Enter height: ');
  ReadLn(height);
  for y := 1 to height do begin
    for x := 1 to width do begin
      Write('*');
    end;
    WriteLn
  end
end

In this example the inner repeating will display stars in a row, and the other repeating will display the required number of rows. When we write things on screen, we proceed horizontally; we first need to complete one row, and only then start another row. This is why inner repeating corresponds to "x" coordinate, and other repeating to "y" coordinate.

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := 1 to size do begin
      Write('*');
    end;
    WriteLn;
  end
end

When both dimensions are the same, we receive the square. (Not exactly, because the width and height of letters on screen may be different, and therefore the real dimensions of the "square" will be different too.)

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := 1 to y do begin
      Write('*');
    end;
    WriteLn;
  end
end

With a very small change we create a triangle. The command "for x := 1 to y" means that each row will contain as many stars, as is the number of this row. That is 1 star in the first row, 2 stars in the second row, etc.

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := y to size do begin
      Write('*');
    end;
    WriteLn
  end
end

Other change in program will create a triangle with different orientation. The command "for x := y to size" will display in each row as many stars, as is the distance of this row from the bottom. That is 1 star in the last row, 2 stars in the previous row, etc.

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := 1 to y - 1 do begin
      Write(' ');
    end;
    for x := y to size do begin
      Write('*');
    end;
    WriteLn
  end
end

To receive the remaining possible orientations of the triangle, we must write some spaces before the stars. We can do it by putting two inner repeatings into the other repeating.

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := 1 to size do begin
      if x < y then begin
        Write(' ')
      end else begin
        Write('*');
      end
    end;
    WriteLn
  end
end

Another solution is to make the same repeatings like when we make a square, but inside we can use the condition for displaying space or star. This second solution is more versatile, because it allows also more complicated equations.

var
  size : Integer;
  x, y : Integer;

begin
  Write('Enter size: ');
  ReadLn(size);
  for y := 1 to size do begin
    for x := 1 to size do begin
      if x > 2*y then begin
        Write(' ')
      end else if y > 2*x then begin
        Write('.')
      end else begin
        Write('*');
      end
    end;
    WriteLn
  end
end

Comments: 0


Google