Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

A Solution to the Spiral Print Problem

5.00/5 (3 votes)
6 May 2020CPOL1 min read 6K   55  
An alternative solution to the Spiral Print problem
In this tip, you will find a solution to the Spiral Print problem using multiple iterations over four Action delegates.

Introduction

This tip is an alternative to the article, A Stepwise C# Implementation of a Solution to the Spiral Print Problem. It’s not meant to be a critique of that article. It’s simply another approach.

Analysis of the Problem

It seems to me that spiral printing of a two dimensional array is just a question of iterating around the border of the array, then reducing the active size of the array by removing from consideration the 2 rows and 2 columns that have just been iterated over and repeating the exercise until all the characters have been printed.

So an array :
A B C D
E F G H
I J K L
M N O P
Q R S T
Is spiral printed as: ABCDHLPTSRQMIEFGKONJ

The Implementation of a Solution

There are four steps needed to print the border of the array. They are:

  1. Print the first row in ascending column order.
  2. Print the end column in ascending row order.
  3. Print the end row in descending column order.
  4. Print the first column in descending row order.

Each of the four steps can be implemented using an Action delegate defined in the constructor of a SpiralPrinter class in this way.

C#
public SpiralPrinter(char[,] characters)
        {
            var nCols = characters.GetLength(1);
            var nRows = characters.GetLength(0);
            colEnd = nCols - 1;
            rowEnd = nRows - 1;
             PrintRowAsc = (() =>
            {
                for (int i = colStart; i <= colEnd; i++)
                {
                    Console.Write(characters[rowStart, i]);
                    isActive = true;
                }
                rowStart++;
            });
            PrintRowDes = (() =>
            {
                for (int i = colEnd; i >= colStart; i--)
                {
                    Console.Write(characters[rowEnd, i]);
                    isActive = true;
                }
                rowEnd--;
            });
            PrintColAsc = (() =>
            {
                for (int i = rowStart; i <= rowEnd; i++)
                {
                    Console.Write(characters[i, colEnd]);
                    isActive = true;
                }
                colEnd--;
            });
            PrintColDes = (() =>
            {
                for (int i = rowEnd; i >= rowStart; i--)
                {
                    Console.Write(characters[i, colStart]);
                    isActive = true;

                }
                colStart++;
            });
        }

Each delegate removes from consideration the row or column that it has just printed. It also sets the isActive flag if it does any work. This enables the PrintSpiral method to know when it has finished.

Printing Out the Spiral

This is done by simply iterating over the four methods until the isActive flag is not set by any of them.

C#
public void PrintSpiral()
{
    do
    {
        isActive = false;
        PrintRowAsc();
        PrintColAsc();
        PrintRowDes();
        PrintColDes();
    }
    while (isActive);
    Console.ReadLine();
}

Conclusion

Breaking a repetitive task into a series of self-contained actions and iterating over them until there is no more work to be done is a useful technique for simplifying seemingly complex problems.

History

  • 6th May, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)